CMPS10 模块读取数值全为0XFF

2012-11-067288
AI 快速预览详细 收起
本文讨论了CMPS10模块在I2C通信中读取数值全为0XFF的问题。通过检查I2C地址和寄存器配置,可以确保正确读取模块的数据。文章提供了详细的故障排查步骤和解决方案,帮助用户快速解决问题,节省调试时间。
  1. #define SDA  PTBDD_PTBDD1
  2. #define SCL  PTBDD_PTBDD0
  3. #define SDA_IN       PTBD_PTBD1
  4. #define SCL_IN       PTBD_PTBD0
  5. void nop(void)    //d= 5 ,Delay  10us   
  6. {
  7. byte d = 0;
  8. d = 5;
  9. while(d--)__RESET_WATCHDOG();
  10. }
  11. void display_compass(void)
  12. {
  13.   level = 0;
  14.   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]
  15. //buffer[0] = 0x01;
  16.   //buffer[1] = 0x32;
  17.   level = buffer[0]<<8;
  18.   level += buffer[1];
  19. //level = ((buffer[0]<<8)+buffer[1]);  // Calculate bearing
  20.   //level = 906;
  21.   
  22.   DispData_level[0] = level /1000 + '0';
  23.   DispData_level[1] = level /100%10 + '0';
  24.   DispData_level[2] = level /10%10 + '0';
  25.   DispData_level[4] = level %10 + '0';
  26.   DispData_level[5] = '\0';
  27.   __RESET_WATCHDOG();
  28.   LCD_P6x8Str(40,0,DispData_level);
  29. }
  30. void read_i2c_buffer(byte addr, byte reg, byte byte_count)
  31. {
  32.   byte x = 0;
  33.   //byte state = 0;
  34. i2c_start();     // send i2c data bytes
  35.   
  36.   if(i2c_tx(addr&0xfe))// abort if slave does not acknowledge
  37.    {  
  38.      i2c_stop();
  39.     for(x = 0; x < (byte_count); x++)
  40.       {
  41.        // buffer[x] = 255;  //no acknowledge,reset buffers
  42.       }
  43.     return;
  44.    }
  45.   if(i2c_tx(reg)) // reg
  46.    {   
  47.      i2c_stop();
  48.     for(x = 0; x < (byte_count); x++)
  49.       {
  50.        // buffer[x] = 255;  //no acknowledge,reset buffers
  51.       }
  52.     return;
  53.    }
  54. i2c_start();     // repeated start
  55.    
  56. if(i2c_tx(addr|0x01)) // addr again including read bit
  57.    {  
  58.     i2c_stop();
  59.     for(x = 0; x < (byte_count); x++)
  60.       {
  61.        // buffer[x] = 255;  //no acknowledge,reset buffers
  62.       }
  63.     return;
  64.    }
  65. for(x = 0; x< (byte_count-1); x++)
  66.    {
  67.      buffer[x] = i2c_rx(ACK);
  68.    }
  69. buffer[byte_count-1] = i2c_rx(NACK);
  70. i2c_stop();
  71. }
  72. byte i2c_rx(byte ack)
  73. {
  74.   byte x = 0;
  75.   byte d = 0;
  76. SDA = 0;
  77. //nop();  /////
  78. for(x = 0; x < 8; x++)
  79.    {
  80.     d <<= 1;  
  81.     do
  82.       {
  83.        SCL = 0;
  84.       }
  85.     while(SCL_IN == 0);    // wait for any SCL clock stretching   
  86.     nop();
  87.     if(SDA_IN)
  88.       {
  89.         d |= 1;
  90.       }
  91.     SCL = 1;
  92.     }
  93.   //nop();  /////
  94. if(ack)
  95.    {
  96.      SDA = 1;
  97.    }
  98. else
  99.    {
  100.      SDA = 0;
  101.    }
  102. SCL = 0;
  103. nop();       // send (N)ACK bit
  104. SCL = 1;
  105. SDA = 0;
  106. return d;
  107. }
  108. byte i2c_tx(byte d)
  109. {
  110.   byte x = 0;
  111. for(x=0; x<8; x++)
  112.    {
  113.     nop();
  114.     if(d&0x80 == 0x80)
  115.       {
  116.         SDA = 0;
  117.       }
  118.     else
  119.       {
  120.         SDA = 1;
  121.       }
  122.     nop();
  123.     SCL = 0;
  124.     nop();
  125.      d <<= 1;
  126.     SCL = 1;
  127.    }
  128. //nop();
  129. SDA = 0;
  130. x = SDA_IN;
  131. //nop(); ////
  132. SCL = 0;
  133. nop();
  134. SCL = 1;
  135. return x;  
  136. }
  137. void i2c_start(void)
  138. {
  139. SDA = 0;      // i2c start bit sequence
  140. nop();
  141. SCL = 0;
  142. nop();
  143. SDA = 1;
  144. nop();
  145. SCL = 1;
  146. nop();
  147. }
  148. void i2c_stop(void)
  149. {
  150. SDA = 1;      // i2c stop bit sequence
  151. nop();
  152. SCL = 0;
  153. nop();
  154. SDA = 0;
  155. nop();
  156. }
复制代码

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(1)
BoBo
BoBo
[code]/****************************************************************
* 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设备,根据提供的操作手册和实例代码发送相应的数据。
- 没有更多了 -