|
|
View previous topic :: View next topic |
Author |
Message |
hello188
Joined: 02 Jun 2010 Posts: 74
|
i2c_write() problem |
Posted: Tue May 15, 2012 4:46 pm |
|
|
Hi, my compiler version is 4.127
Code: |
//main.c
#include <16F1518.h>
#fuses HS, NOWDT, NOPUT, NOPROTECT, NOBROWNOUT, NOIESO, NOFCMEN, STVREN, DEBUG
#use delay(clock = 14745600)
#USE I2C(MASTER, SCL = PIN_B2, SDA = PIN_B1, FORCE_SW)
int16 adc_buffer;
void main(void){
int8 k;
int8 high_buffer,low_buffer, config;
int16 hey;
i2c_start();
i2c_write(0b11010000);
i2c_write(0b10011000);//Start continuous conversion
i2c_stop();
while(1){
i2c_start();
i2c_write(0b11010001);
high_buffer = i2c_read();
low_buffer = i2c_read(0);
config = i2c_read(0);
i2c_stop();
hey = high_buffer<<8;
hey += low_buffer;
adc_buffer = hey;
}
}
|
My target board has MCP3420 AD converter on board and I am trying to test if it's reading the analog value correctly.
I composed above code and tried to test on the ICD3 debugger in debug mode.
However, the debugger gets stuck in the first i2c_write call. and never proceed from the call.
When I stop the debugger, it always stops on #USE I2C(MASTER, SCL = PIN_B2, SDA = PIN_B1, FORCE_SW) compiler directive.
When I use step-in function on debugger, it gets stuck on that directive forever.
I know that the hardware may be the problem.
However, even if it is so, I am afraid the program should proceed.
Even if a single I2C component fails, the rest of the functionalities has to be unaffected.
A single component failure can not result in the whole system failure.
My question is, does CCS built-in I2C function provide some kind of mechanism to proceed to next part of the code even if the I2C slave component failed to respond or malfunction in any other ways? For example, some kind of time-out on waiting for ACK response?
Thank you |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Tue May 15, 2012 7:34 pm |
|
|
two items
1) do you have the correct pullup resistors on the I2C bus lines based on speed, distance,voltage,etc. ?
2) There's an I2C bus test program here( PCM Programmers ?) you should copy and use to test your devices with. It will confirm that the device does exist and the PIC can communicate with it. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 15, 2012 8:26 pm |
|
|
Quote: | My target board has MCP3420 AD converter.
|
According to Google, this part number does not exist.
Quote: | There's an I2C bus test program here
|
Here is an i2c bus scanner program that will report the addresses of any
i2c slave devices that it finds on the bus. Modify the #include, #fuses,
and the #use statements so it will work with your board. Then run it
and see what devices it finds:
http://www.ccsinfo.com/forum/viewtopic.php?t=47707&start=21
Quote: |
i2c_start();
i2c_write(0b11010001);
high_buffer = i2c_read();
low_buffer = i2c_read(0);
config = i2c_read(0);
i2c_stop();
|
This is almost certainly wrong. You have two NACKs in there. Only the
last i2c_read() should have a NACK.
Quote: | However, the debugger gets stuck in the first i2c_write call
|
It's probably stuck in the loop inside i2c_write() that checks for clock
stretching by the slave. This can happen if you're missing the pull-up
resistor on the SCL line. (You need them on both SCL and SDA).
Quote: | My question is, does CCS built-in I2C function provide some kind of mechanism proceed to next part of the code even if the I2C slave component failed to respond. For example, some kind of time-out. |
No, it doesn't have that feature. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed May 16, 2012 3:29 am |
|
|
On recovery, this is where a watchdog is probably the way to go.
You write your code, so the variables are not initialised when you boot, read the 'restart cause', and if this is 'power on reset', then initialise your variables/hardware, and start the code. If it is not, then perform a test on the voltage levels of the two I2C lines. If either is 'low' (implying the I2C bus has hung, with the slave device clock stretching), then disable your I2C code, and continue without re-initialising anything.
Other thing to remember, is that devices _acknowledge_, when selected. So (for instance):
Code: |
int1 device_found=FALSE;
i2c_start();
if (i2c_write(0b11010000) == 0) {
//Here the slave acknowledged, so perform the I2C code
i2c_write(0b10011000);//Start continuous conversion
device_found=TRUE;
}
i2c_stop();
|
Then only try to read from the device, if 'device_found' is TRUE.
Possibly the device is a 3421?. The top four address bits are right for this device, but the next three depend on what is set at the factory. Are you _sure_ your example has these set to 000?.
Best Wishes |
|
|
|
|
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
|