|
|
View previous topic :: View next topic |
Author |
Message |
John Ilicitean
Joined: 07 Jul 2005 Posts: 27 Location: Rotova
|
Problem with I2C and A/D |
Posted: Tue Oct 11, 2005 4:57 am |
|
|
Hello everyone!!!!
I'm working with PIC16f877 and Analog-to-Digital converted (ADS1100).The PIC is the master and ADS1100 acts the slave.This A/D use the interface I2C to communicate with PIC.The connections are sda=PIN_C4 scl=PIN_C3. The power supply, the pull-up resistor and SDA,SCL of the ADS1100 are correctly. The I2c address is 1001 010X according to manual.
Good so,the only one device that transmits for SDA is the PIC.Start communication, the PIC send an address byte for SDA ,and when a master has finished ,the A/D not send the bit acknowledge.
This is my code
Code: |
#include <16F877.h>
#use delay(clock=20000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3,FORCE_HW)
long r=0;
#include <LCD.c>
void main()
{
while(1)
{
lcd_init();
i2c_start();
i2c_write(0x94); //I2C Address
i2c_write(0x80); //Configuration Register
r=i2c_read();
i2c_stop();
}
}
|
Why not ADS1100 send a bit acknowledge? |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 11, 2005 5:26 am |
|
|
I2C, does not allow what you are showing. A single transaction, can only ever read or write, not change direction half way. The direction is controlled by the bottom bit in the address. So to 'set' a register address, then 'read', what has to happen is that you set up a 'write' (with the bit = 0 as you have), transfer the register address, then abort the transaction. Then setup a 'read' (start, and send the device address again, with the read bit set), then read the reply.
Look at the example file for talking to an I2C memory, to see how this works.
Best Wishes |
|
|
John Ilicitean
Joined: 07 Jul 2005 Posts: 27 Location: Rotova
|
|
Posted: Thu Oct 13, 2005 10:50 am |
|
|
Thank You!
but or it does not work or I have not understood it. In the "read" , the bit acknowlegged appears by the Master (PIC16f877),but in the "write" the bit acknowledge by ADS1100 it continues without appearing.It wants to say it what ADS1100 doesn't work.
This is my new code:
Code: |
#include <16F877.h>
//#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3,FORCE_HW)
byte r=0;
void main()
{
while(1)
{
i2c_write(0x94); //To prepare for write
i2c_write(0x94); //I2C address
i2c_start();
i2c_write(0x95); //I2C address again
r=i2c_read(); //read the reply
i2c_stop();
}
}
|
It possible what does not to use correctly the bus for the setup "write" in the ADS1100???????? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 13, 2005 12:06 pm |
|
|
There is sample C source code here, for the ADS1100.
On the following page, click on the link that says:
"Download associated code files (slaa206.zip, 11 Kbytes)"
http://focus.ti.com/docs/mcu/catalog/resources/appnoteabstract.jhtml?familyId=342&abstractName=slaa206
The i2c routines are in i2c_Master.s43, which is just a text file.
This code is not completely easy to understand. But it does give
some hints that the ADS1100 data sheet doesn't show clearly, such
as how to use i2c operations to do a 16-bit read from the chip). |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 14, 2005 4:54 am |
|
|
Making a couple of comments.
First, you are getting confused over the idea of a device address, and a register address. The normal sequence for a read with I2C, is:
start
send device address
send register address
re-start
send device address with 'read' bit set
read
read
read
stop
Now the 1100, has a 'shortcut', in that it should always start reading from register address 0, after a full start (so you should not need to do the initial 'write' setup).
Second comment though, is are you _sure_ of the device address. You talk about this being 'according to the manual', but in fact the devices are available with any address value in the low three bits. If you order the device with '4' here, the chips actually address as 0b1001100x.
Best Wishes |
|
|
Guest
|
|
Posted: Tue Oct 18, 2005 11:22 am |
|
|
Hello!!
First,thank you for help me.
After, to explain what I have done.I have continued the normal sequence of i2c.Also I have changed the device address.And acknowledged bit , for the ADS1100, it does not appear.
this is my last code: Code: |
#include <16F877.h>
//#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)
byte r,y,x=0;
void main()
{
while(1)
{
i2c_start();
i2c_write(0x92); //device addres with the low bit=0
i2c_write(0x9c); //Configuration Register
i2c_start();
i2c_write(0x93); //device addres with the low bit=1
r=i2c_read();
y=i2c_read();
x=i2c_read();
i2c_stop();
delay_ms(11);
}
}
|
|
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Oct 18, 2005 12:24 pm |
|
|
Try this code. It compiles fine and should increment through each possible address of the A/D. It will then place the address, that responded, into variable 'z'. You can check it to see which address responded. I don't have one of the ADS1100 parts but this 'should' work. After reading through the data sheet it should read the output register and then the configuration register.
Code: |
#include <16F877.h>
//#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)
byte z,i,r,y,x=0;
void main()
{
while(1)
{
i2c_start();
for(i = 0x91; i < 0xA0; i =+ 0x02)
{
if(!i2c_write(x)); //device addres with the low bit=0
{
r=i2c_read();// read output register upper byte
y=i2c_read();// read output register lower byte
x=i2c_read();// read configuration register
z=i;
}
}
i2c_stop();
delay_ms(11);
}
}
|
Hope it helps(works).
Ronald |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 18, 2005 12:38 pm |
|
|
What about the NAK on the last i2c read ? |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Oct 18, 2005 2:09 pm |
|
|
The data sheet, for the ADS1100, shows the master sending an ACK on the last read. I'm not sure if this is correct since the standard would send a NACK but since the data sheet shows an ACK from the Master I left it like it is.
Ronald |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 18, 2005 2:22 pm |
|
|
I noticed that too, but in their sample code here, at the link which says
"download associated code files",
http://focus.ti.com/docs/apps/catalog/resources/appnoteabstract.jhtml?abstractName=slaa206
there is a text file called I2C_Master.s43 and it does a NACK on the
last read.
Code: | ;---------------------------------------------------------
; unsigned int I2CRead16(unsigned char Addr)
;
; Reads two bytes (16 bit) of data transmitted from I2C slave
;
; IN: R12 I2C slave address
; OUT: R12 00000h - 0ffffh I2C device data
;-----------------------------------------------------------------
I2CRead16 push.w R15 ; Save R15
setc ; Set carry for "READ" and
rlc.w R12 ; left-shift into address
call #I2C_Start ; Send Start
call #I2C_TX ; Send Address+RD and Ack
call #I2C_RX ; Read Data and Ack
call #I2C_ACKn ; Acknowledge Byte Rcv'd
call #I2C_RX ; Read Data and Ack
call #I2C_NACKn ; NOT Acknowledge Byte Rcv'd
call #I2C_Stop ; Send Stop
pop.w R15 ; Restore R15
ret |
|
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Tue Oct 18, 2005 2:34 pm |
|
|
By all means, try it both ways and check the results.
If there spec is in error let them know. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Oct 18, 2005 4:17 pm |
|
|
Sounds like a plan.
Ok then, John, if my first code example doesn't work quite right then try this one. Just a minor change here.
Code: |
#include <16F877.h>
//#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)
byte z,i,r,y,x=0;
void main()
{
while(1)
{
i2c_start();
for(i = 0x91; i < 0xA0; i =+ 0x02)
{
if(!i2c_write(x)); //device addres with the low bit=0
{
r=i2c_read();// read output register upper byte
y=i2c_read();// read output register lower byte
x=i2c_read(0);// read configuration register and send a NACK
z=i;
}
}
i2c_stop();
delay_ms(11);
}
}
|
This one just sends a NACK which indicates that the master is finished talking to this particular part.
Ronald
You know you're getting old when you start forgetting to zip your zipper up. You know you're getting even older when you start forgetting to zip your zipper down. |
|
|
John Ilicitean
Joined: 07 Jul 2005 Posts: 27 Location: Rotova
|
|
Posted: Thu Oct 20, 2005 3:26 am |
|
|
Hello!!
I have tried both codes and none does work's.
For another way,I do not understand that I must do with the file I2C_Master.s43 .I must change this code language of compiler?????Or
I must put this file in my code????.Say to me that I must do with I2C_Master.s43 . |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Oct 20, 2005 8:27 am |
|
|
DOH! Big mistake here. I entered the wrong variable here.
Quote: |
if(!i2c_write(x)); //device addres with the low bit=0
|
It should have been
Code: |
if(!i2c_write(i)); //device address
|
Try that one. With it trying to write 'x' as the address it would always be writing a '0'(zero) to the PIC. My bad. I had 'x' as the variable for the for() loop and then realized that 'x' was already defined and then changed it in the for() loop but forgot to change it in the i2c command.
Ronald |
|
|
John Ilicitean
Joined: 07 Jul 2005 Posts: 27 Location: Rotova
|
|
Posted: Fri Oct 21, 2005 3:44 am |
|
|
Thank's for the explanation, but the slave continued without working.
Because it in the previous commentary to ask for that I must do with the file I2C_Master.s43.
Because in this way,the ADS1100, continued without send the bit acknowledged. |
|
|
|
|
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
|