superman0007 发表于 2012-11-6 09:38:34

CMPS10 模块读取数值全为0XFF

#define SDAPTBDD_PTBDD1
#define SCLPTBDD_PTBDD0
#define SDA_IN       PTBD_PTBD1
#define SCL_IN       PTBD_PTBD0
void nop(void)    //d= 5 ,Delay10us   
{
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 and buffer
//buffer = 0x01;
//buffer = 0x32;

level = buffer<<8;
level += buffer;
//level = ((buffer<<8)+buffer);// Calculate bearing
//level = 906;

DispData_level = level /1000 + '0';
DispData_level = level /100%10 + '0';
DispData_level = level /10%10 + '0';
DispData_level = level %10 + '0';
DispData_level = '\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 = 255;//no acknowledge,reset buffers
      }
    return;
   }
if(i2c_tx(reg)) // reg
   {   
   i2c_stop();
    for(x = 0; x < (byte_count); x++)
      {
       // buffer = 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 = 255;//no acknowledge,reset buffers
      }
    return;
   }
for(x = 0; x< (byte_count-1); x++)
   {
   buffer = i2c_rx(ACK);
   }
buffer = 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();
}

bobo 发表于 2012-11-6 13:50:04

/****************************************************************
*                  Arduino CMPS10 example code                  *
*                  CMPS10 running I2C mode                  *
*                  by James Henderson, 2012                   *
*****************************************************************/
#include <Wire.h>
#include <SoftwareSerial.h>

#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 ofCMPS10 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);
}看下这个代码arduino的


我的I2C调试经验是,首先用示波器查看你发出来的波形是否正确,然后将总线接到例如24LC01 EEPROM上来判断是否可以可靠操作。 最好做一个I2C库封装起来,方便使用。

在I2C通信库OK的前提下,然后第三步,再接你最新使用的I2C设备,根据提供的操作手册和实例代码发送相应的数据。

页: [1]
查看完整版本: CMPS10 模块读取数值全为0XFF