CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

16F886 I2C question
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hamid9543



Joined: 31 Jan 2013
Posts: 63

View user's profile Send private message

l3g4200d
PostPosted: Sun Feb 10, 2013 7:16 am     Reply with quote

hi to all!
i read your code and write new code
Code:

#Include <16f873a.h>
#use delay (clock = 20000000)
#Use I2C (master, sda = PIN_C3, scl = PIN_C4)
#define LCD_RS_PIN      PIN_b1                                    ////
#define LCD_RW_PIN      PIN_b2                                    ////
#define LCD_ENABLE_PIN  PIN_b3                                    ////
#define LCD_DATA4       PIN_b4                                    ////
#define LCD_DATA5       PIN_b5                                    ////
#define LCD_DATA6       PIN_b6                                    ////
#define LCD_DATA7       PIN_b7
#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
#define CTRL_REG5 0x24
#include <LCD.c>
int L3G4200D_Address = 0xD2;   //I2C address of the L3G4200D
int x,y,z;
void writeRegister(int deviceAddress, int address,int val)
 {
    i2c_start();
    i2c_write(deviceAddress); // start transmission to device
    i2c_write(address);       // send register address
    i2c_write(val);           // send value to write
    i2c_stop();               // end transmission
 }

void setupL3G4200D(int scale)
{
  writeRegister(L3G4200D_Address, CTRL_REG3, 0b00001000);
  if(scale == 250)
  {
  writeRegister(L3G4200D_Address, CTRL_REG4, 0b00000000);
  }
  else if(scale == 500)
  {
  writeRegister(L3G4200D_Address, CTRL_REG4, 0b00010000);
  }
  else
  {
  writeRegister(L3G4200D_Address, CTRL_REG4, 0b00110000);
  }
}

void main()
{
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"starting up L3G4200D");
delay_ms (1000);
setupL3G4200D(2000);            //Configure L3G4200  - 250, 500 or 2000 deg/sec
writeRegister(L3G4200D_Address,0x20,0x0F);
delay_ms(1500);                 //wait for the sensor to be ready

while(true)
{
    i2c_start();
    i2c_write(L3G4200D_Address);
    i2c_write(0xD3);
    i2c_start();
    int xLSB=i2c_read(0x28);  // register to read
    int xHSB=i2c_read(0x29);  // register to read
    x = make16(xHSB,xLSB);
    int yLSB=i2c_read(0x2A); 
    int yHSB=i2c_read(0x2B);
    y = make16(yHSB,yLSB);
    int zLSB=i2c_read(0x2C); 
    int zHSB=i2c_read(0x2D);
    z = make16(zHSB,zLSB);
    i2c_stop();              //This will update x, y, and z with new values
  lcd_gotoxy(1,2); 
  printf(lcd_putc,"x=%03u",x);
  lcd_gotoxy(6,1);
  printf(lcd_putc,"y=%03u",y);
  lcd_gotoxy(12,1);
  printf(lcd_putc,"z=%03u",z);
  delay_ms(100);
}
}

}

but lcd show x=-1 y=-1 z=-1
can you help me?
Ttelmah



Joined: 11 Mar 2010
Posts: 19549

View user's profile Send private message

PostPosted: Sun Feb 10, 2013 8:27 am     Reply with quote

You have misunderstood how to reverse the I2C bus:
Code:

    int xLSB,xMSB,yLSB,yMSB,zLSB,zMSB;
    //C requires variables to be declared at the start of a code section
    //CCS doesn't complain, but commonly goes wrong if you use the
    //midblock definitions (not standard C)....
    i2c_start();
    i2c_write(L3G4200D_Address);
    //This is where you have to _write_ the register number you want
    i2c_write(0x28); //select the register you want to read
    i2c_write(L3G4200D_Address + 1); //now turn the bus round
    i2c_start(); //restart - the bus is now set to _read_
    xLSB=i2c_read();  //Now read the register
    //I2c_read cannot send anything except ack/nack at the end of
    //the transfer - the bus is in _read_ mode now......
    xMSB=i2c_read(); //Most chips will auto-increment to the next
    //register - check that yours does
    x = make16(xMSB,xLSB);
    yLSB=i2c_read();
    yMSB=i2c_read();
    y = make16(yMSB,yLSB);
    zLSB=i2c_read();
    zMSB=i2c_read(0);  //ACK the last byte - i2c _requires_ this
    z = make16(zHSB,zLSB);
    i2c_stop();              //This will update x, y, and z with new values


Once the bus is set to 'read', you can't send addresses. I2C_read, accepts just 0/1, for NACK/ACK, and the last byte should use this.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

Re: l3g4200d
PostPosted: Sun Feb 10, 2013 8:40 am     Reply with quote

hamid9543 wrote:
i read your code and write new code
The only relation between your question and the original Topic Starter is that you both are using the same gyro sensor.
For a new question like this please start a new thread, there you can optionally add a link to this thread for reference but since your code is so different it doesn't matter.

A few tips to start with:
- Try the I2C scanner program mentioned a few postings earlier in this thread. It will prove your I2C hardware is setup correctly and is configured for the address you expect it is using.
- I'm confused you get results of '-1' when using '%u' as format specifier. The 'u' is for 'unsigned', so only positive values can be displayed. Is the code as posted the exact same version as you are testing with?
- In CCS an int has an 8 bits size for the PIC16 and PIC18. Your values of 500 and 2000 don't fit this.
- Add #case to your program. By default the CCS compiler doesn't care about mixing small and upper case letters but the original the C language is case sensitive. Your program is easier to read when words 'look' the same as what everybody got used to.

Post the results in the new topic you are going to start.
otacon



Joined: 12 Nov 2010
Posts: 3

View user's profile Send private message

PostPosted: Fri Mar 22, 2013 1:15 pm     Reply with quote

Hi PGM
I did everything is right and i got a value about every axis X,Y,or Z but it seem not change when i move the sensor,it's just update the value when i cut off and reconnect the power supply for this sensor. what happened with my sensor? Can i reset it with a auto cycle!
Sorry about my english!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group