View previous topic :: View next topic |
Author |
Message |
elise
Joined: 07 Jan 2009 Posts: 1
|
i2c_read problem (using AD5241 and PIC18F4550) |
Posted: Wed Jan 07, 2009 11:43 am |
|
|
I am not sure why I keep reading 0XFF from my slave device potentiometer AD5241. I can write to it through i2C with no problem.
To write:
Code: | i2c_start();
i2c_write(0b01011000);
i2c_write(0b00011000);
i2c_write(value);
i2c_stop(); |
first write is for the slave address. Last bit low means write
2nd write is for 2nd frame instruction
3rd write is for an int8 value
This works.
To read:
Code: | i2c_start();
i2c_write(0b01011001);
value = i2c_read(0);
i2c_stop(); |
First write: slave address with last bit high to read
datasheet of AD5241 clearly says 'data byte follow immediately after the acknowledgment of the slave address. data is transmitted over the serial bus in nine clock pulses (8 bits followed by a No acknowledge bit )
Doing my read routine, I always read 0XFF. What am I doing wrong?
Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 07, 2009 3:02 pm |
|
|
According to the AD5641 data sheet, if you do the write operation
followed by the read operation, then it should work. In your test
program, do you have the 1st block of code and then the 2nd block of
code placed immediately after it ?
1. Post a short test program so we can see what you are doing.
It should have an #include, #fuses, #use delay, and main().
In other words, a complete (but short) compilable program.
2. Post if you have pull-up resistors on the SDA and SCL lines.
3. Post your compiler version. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Sun Oct 17, 2010 11:29 am |
|
|
PCM,
I'm experiencing the same issue, but with an AD5242 (two pot part.)
Details:
4.7K Pull-ups on SCL and SDA.
3.249
Test program:
Code: |
//
// MCMC_LED_i2c_test.c
//
#include <18F2620.h>
#use delay(clock=10000000)
#fuses HS,NOPROTECT,PUT,NOLVP,BORV28,NOWDT
#define LED_GREEN PIN_A0
#define LED_YELLOW PIN_A1
#define LED_RED PIN_A2
#use I2C(master,sda=PIN_B0,scl=PIN_B1)
void Set_Resistance(int8 Value)
{
delay_ms(1);
i2c_start();
i2c_write(0b01011000);
i2c_write(0b00000000);
i2c_write(Value);
delay_ms(1);
i2c_write(0b01011000);
i2c_write(0b10000000);
i2c_write(Value);
i2c_stop();
delay_ms(1);
}
int8 Read_Resistance(int1 Address)
{
int8 Value = 0;
delay_ms(1);
i2c_start();
if(Address)
{
i2c_write(0b01011000);
i2c_write(0b10000000);
i2c_write(0b01011001);
Value = i2c_read(0);
}
else
{
i2c_write(0b01011000);
i2c_write(0b00000000);
i2c_write(0b01011001);
Value = i2c_read(0);
}
i2c_stop();
delay_ms(1);
return Value;
}
void main() {
int8 Brightness = 128;
int8 Set_Bright = 0;
while (TRUE)
{
//-------------------------------------------------------------
Set_Resistance(Brightness);
// Brightness = Brightness << 1;
// if(Brightness > 255) Brightness = 1;
Set_Bright = Read_Resistance(0);
if(Set_Bright == Brightness)
{
output_high(LED_GREEN);
delay_ms(500);
output_low(LED_GREEN);
}
else
{
output_high(LED_RED);
delay_ms(500);
output_low(LED_RED);
}
delay_ms(500);
output_toggle(LED_YELLOW); //heartbeat
}
} |
Any suggestions of where to look?
Thanks,
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 17, 2010 1:12 pm |
|
|
I looked at the data sheet for the AD5242. I modified your code as
shown below. I think it has a better chance to work.
Code: |
#define AD5242_WRT_ADDR 0x58
#define AD5242_RD_ADDR 0x59
// Set both channels to the same value.
void Set_Resistance(int8 Value)
{
i2c_start();
i2c_write(AD5242_WRT_ADDR);
i2c_write(0x00); // Channel 0
i2c_write(Value);
i2c_stop();
i2c_start();
i2c_write(AD5242_WRT_ADDR);
i2c_write(0x80); // Channel 1
i2c_write(Value);
i2c_stop();
}
//-------------------------------
// Readback the pot setting for the specified channel (0 or 1).
int8 Read_Resistance(int8 Address)
{
int8 Value;
int8 channel;
if(Address)
channel = 0x80;
else
channel = 0x00;
i2c_start();
i2c_write(AD5242_WRT_ADDR);
i2c_write(channel);
i2c_start(); // Re-start
i2c_write(AD5242_RD_ADDR);
Value = i2c_read(0);
i2c_stop();
return(Value);
} |
|
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Sun Oct 17, 2010 2:16 pm |
|
|
PCM programmer wrote: | I looked at the data sheet for the AD5242. I modified your code as
shown below. I think it has a better chance to work. |
Works like a champ! Thanks a bunch for taking the time to look at it.
I was wondering about the starts and stops after looking at the data sheet comm diagrams, but wasn't sure what would require a another start or both a stop and a start.
John |
|
|
|