- #define SDA PTBDD_PTBDD1
- #define SCL PTBDD_PTBDD0
- #define SDA_IN PTBD_PTBD1
- #define SCL_IN PTBD_PTBD0
- void nop(void) //d= 5 ,Delay 10us
- {
- byte d = 0;
- d = 5;
- while(d--)__RESET_WATCHDOG();
- }
- void display_compass(void)
- {
- level = 0;
- read_i2c_buffer(0xC0,2,2);// read 2 bytes from compas starting at register 2, these are high byte and low byte for bearing. Put in buffer[0] and buffer[1]
- //buffer[0] = 0x01;
- //buffer[1] = 0x32;
-
- level = buffer[0]<<8;
- level += buffer[1];
- //level = ((buffer[0]<<8)+buffer[1]); // Calculate bearing
- //level = 906;
-
- DispData_level[0] = level /1000 + '0';
- DispData_level[1] = level /100%10 + '0';
- DispData_level[2] = level /10%10 + '0';
- DispData_level[4] = level %10 + '0';
- DispData_level[5] = '\0';
- __RESET_WATCHDOG();
- LCD_P6x8Str(40,0,DispData_level);
- }
-
- void read_i2c_buffer(byte addr, byte reg, byte byte_count)
- {
- byte x = 0;
- //byte state = 0;
- i2c_start(); // send i2c data bytes
-
- if(i2c_tx(addr&0xfe))// abort if slave does not acknowledge
- {
- i2c_stop();
- for(x = 0; x < (byte_count); x++)
- {
- // buffer[x] = 255; //no acknowledge,reset buffers
- }
- return;
- }
- if(i2c_tx(reg)) // reg
- {
- i2c_stop();
- for(x = 0; x < (byte_count); x++)
- {
- // buffer[x] = 255; //no acknowledge,reset buffers
- }
- return;
- }
- i2c_start(); // repeated start
-
- if(i2c_tx(addr|0x01)) // addr again including read bit
- {
- i2c_stop();
- for(x = 0; x < (byte_count); x++)
- {
- // buffer[x] = 255; //no acknowledge,reset buffers
- }
- return;
- }
- for(x = 0; x< (byte_count-1); x++)
- {
- buffer[x] = i2c_rx(ACK);
- }
- buffer[byte_count-1] = i2c_rx(NACK);
- i2c_stop();
- }
- byte i2c_rx(byte ack)
- {
- byte x = 0;
- byte d = 0;
- SDA = 0;
- //nop(); /////
- for(x = 0; x < 8; x++)
- {
- d <<= 1;
- do
- {
- SCL = 0;
- }
- while(SCL_IN == 0); // wait for any SCL clock stretching
- nop();
- if(SDA_IN)
- {
- d |= 1;
- }
- SCL = 1;
- }
- //nop(); /////
- if(ack)
- {
- SDA = 1;
- }
- else
- {
- SDA = 0;
- }
- SCL = 0;
- nop(); // send (N)ACK bit
- SCL = 1;
- SDA = 0;
- return d;
- }
-
- byte i2c_tx(byte d)
- {
- byte x = 0;
- for(x=0; x<8; x++)
- {
- nop();
- if(d&0x80 == 0x80)
- {
- SDA = 0;
- }
- else
- {
- SDA = 1;
- }
- nop();
- SCL = 0;
- nop();
- d <<= 1;
- SCL = 1;
- }
- //nop();
- SDA = 0;
- x = SDA_IN;
- //nop(); ////
- SCL = 0;
- nop();
-
- SCL = 1;
- return x;
- }
-
- void i2c_start(void)
- {
- SDA = 0; // i2c start bit sequence
- nop();
- SCL = 0;
- nop();
- SDA = 1;
- nop();
- SCL = 1;
- nop();
- }
-
- void i2c_stop(void)
- {
- SDA = 1; // i2c stop bit sequence
- nop();
- SCL = 0;
- nop();
- SDA = 0;
- nop();
- }
复制代码
|
* Arduino CMPS10 example code *
* CMPS10 running I2C mode *
* by James Henderson, 2012 *
*****************************************************************/
#include
#include
#define ADDRESS 0x60 // Defines address of CMPS10
#define LCD_RX 0x02 // RX and TX pins used for LCD0303 serial port
#define LCD_TX 0x03
#define LCD03_HIDE_CUR 0x04
#define LCD03_CLEAR 0x0C
#define LCD03_SET_CUR 0x02
SoftwareSerial lcd03 = SoftwareSerial(LCD_RX, LCD_TX); // Defines software serial port for LCD03
void setup(){
Wire.begin(); // Conects I2C
lcd03.begin(9600);
lcd03.write(LCD03_HIDE_CUR);
lcd03.write(LCD03_CLEAR);
}
void loop(){
byte highByte, lowByte, fine; // highByte and lowByte store high and low bytes of the bearing and fine stores decimal place of bearing
char pitch, roll; // Stores pitch and roll values of CMPS10, chars are used because they support signed value
int bearing; // Stores full bearing
Wire.beginTransmission(ADDRESS); //starts communication with CMPS10
Wire.write(2); //Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 4); // Request 4 bytes from CMPS10
while(Wire.available() < 4); // Wait for bytes to become available
highByte = Wire.read();
lowByte = Wire.read();
pitch = Wire.read();
roll = Wire.read();
bearing = ((highByte<<8)+lowByte)/10; // Calculate full bearing
fine = ((highByte<<8)+lowByte)%10; // Calculate decimal place of bearing
display_data(bearing, fine, pitch, roll); // Display data to the LCD03
delay(100);
}
void display_data(int b, int f, int p, int r){ // pitch and roll (p, r) are recieved as ints instead oif bytes so that they will display corectly as signed values.
lcd03.write(LCD03_SET_CUR); // Set the LCD03 cursor position
lcd03.write(1);
lcd03.print("CMPS10 Example V:");
lcd03.print(soft_ver()); // Display software version of the CMPS10
delay(5); // Delay to allow LCD03 to proscess data
lcd03.write(LCD03_SET_CUR);
lcd03.write(21);
lcd03.print("Bearing = "); // Display the full bearing and fine bearing seperated by a decimal poin on the LCD03
lcd03.print(b);
lcd03.print(".");
lcd03.print(f);
lcd03.print(" ");
delay(5);
lcd03.write(LCD03_SET_CUR); // Display the Pitch value to the LCD03
lcd03.write(41);
lcd03.print("Pitch = ");
lcd03.print(p);
lcd03.print(" ");
delay(5);
lcd03.write(LCD03_SET_CUR); // Display the roll value to the LCD03
lcd03.write(61);
lcd03.print("Roll = ");
lcd03.print(r);
lcd03.print(" ");
}
int soft_ver(){
int data; // Software version of CMPS10 is read into data and then returned
Wire.beginTransmission(ADDRESS);
// Values of 0 being sent with write need to be masked as a byte so they are not misinterpreted as NULL this is a bug in arduino 1.0
Wire.write((byte)0); // Sends the register we wish to start reading from
Wire.endTransmission();
Wire.requestFrom(ADDRESS, 1); // Request byte from CMPS10
while(Wire.available() < 1);
data = Wire.read();
return(data);
}[/code]看下这个代码 arduino的
我的I2C调试经验是,首先用示波器查看你发出来的波形是否正确,然后将总线接到例如24LC01 EEPROM上来判断是否可以可靠操作。 最好做一个I2C库封装起来,方便使用。
在I2C通信库OK的前提下,然后第三步,再接你最新使用的I2C设备,根据提供的操作手册和实例代码发送相应的数据。