![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
epv
Joined: 23 Feb 2008 Posts: 8
|
problem with I2C master on 16f88 |
Posted: Sat Feb 23, 2008 4:43 am |
|
|
I've just started playing with i2c, and I'm having a hard time with making this chip speak i2c.
I'm using the sw implementation, since 16f88 can only do i2c slave in hardware.
If I use the PCM compiler's builtin "#use i2c..." (PCM compiler version 4.049;8/6/2007, this is the latest version on linux) it hangs forever without transferring any data. I've been experimenting with it trying to make it talk to an i2c LCD module, but the same thing happens trying to access the i2c 24lc16 eeprom on an Olimex PG4 board, too.
Code: |
#include <16F88.h>
#fuses INTRC_IO, NOWDT, NOMCLR, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 8000000)
#use i2c(master, sda=PIN_A0, scl=PIN_A1)
void main()
{
i2c_start();
i2c_write(0x50); // 0x50 is the LCD module's address
// i2c_start(); // should this be here or not? doesn't work either way
i2c_write(0x41); // print "A"
i2c_stop();
while(1);
} |
No output..
If I don't use the #use i2c or the builtin i2c_*() functions and instead manually bit-bang out the i2c conversation it works, on the same chip, same pins, same LCD module, etc...
Code: | #include <16F88.h>
#fuses INTRC_IO, NOWDT, NOMCLR, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 8000000)
#include <stdlib.h>
#define SDA PIN_A0
#define SCL PIN_A1
#define LCDADDR 0x50
void i2cstop(void)
{
output_low(SDA);
output_low(SCL);
output_high(SDA);
}
void i2cinit(void)
{
int n;
output_high(SDA);
output_low(SCL);
for (n=0; n<3; n++)
i2cstop();
}
void i2cstart(void)
{
output_high(SCL);
output_high(SDA);
output_low(SDA);
output_low(SCL);
output_high(SDA);
}
void i2cgetack(void)
{
output_high(SDA);
output_high(SCL);
while (input(SDA) != 0) ;
output_low(SCL);
output_low(SDA); // should already be, but set it to output
}
void i2cgiveack(void)
{
output_low(SDA);
output_high(SCL);
output_low(SCL);
output_high(SDA);
}
void i2cputbyte(int obyte)
{
int n;
for (n=0; n<8; n++) {
if (obyte & 0x80)
output_high(SDA);
else
output_low(SDA);
output_high(SCL);
output_low(SCL);
obyte = obyte << 1;
}
output_high(SDA);
}
void i2csendaddr(int adr, int rw)
{
i2cstart();
if((adr & 0x8000) != 0) {
i2cputbyte(0xF0 | rw | ((adr > 8) & 0x06));
i2cgetack();
i2cputbyte(adr & 0xFF);
} else {
i2cputbyte(adr | rw);
}
i2cgetack();
}
void i2cwrite(int adr, int num, char *buf) {
i2csendaddr(adr, 0);
while(num-- > 0) {
i2cputbyte(*buf++);
i2cgetack();
}
i2cstop();
}
void lcdcommand(int cmd, int num, int arg1, int arg2) {
char buf[6];
buf[0] = LCDCOMMAND;
buf[1] = cmd;
buf[2] = arg1;
buf[3] = arg2;
i2cwrite(LCDADDR, num + 1, buf);
}
void lcdwrite (int dat) {
char buf [2];
buf [0] = (char) dat;
i2cwrite(LCDADDR, 1, buf);
}
void main() {
i2cinit();
delay_ms(100);
printf(lcdwrite, "Hello, world. \n ");
while(1);
} |
(those functions were mostly cribbed from user RussCA on lcdforums.com, to give due credit)
The above code successfully writes a "Hello, world." to the display, so I am pretty sure there's not a hardware problem.
Additionally, I get the same thing going on in a simulator (gpsim) trying to write to an emulated i2c eeprom... the i2c builtins just hang, seem to be polling SDA forever.
I am more than happy to be told I am clueless and doing it wrong - but before I drive myself nuts trying to figure it out, could it be that there's a problem with the linux version of the compiler, or a problem that was fixed since version 4.049?
thanks for any help or advice,
eric |
|
![](templates/subSilver/images/spacer.gif) |
epv
Joined: 23 Feb 2008 Posts: 8
|
fixed... |
Posted: Sat Feb 23, 2008 8:53 pm |
|
|
Well, my problem was a confluence of a number of factors. One was that the Olimex PG4 board has a pullup on SDA, but lacks one for SCL. Why? I dunno. When I added a pullup for SCL, I was able to read/write the 24LC16 with the *_ext_eeprom() routines, which of course just use the builtin i2c functions.
The other problem was that I was apparently talking to the i2c LCD incorrectly, and it was ignoring me until I got it's format figured out.
Anyway, I feel less frustrated now. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|