Reading Data from LK404-55 over I2C serial bus.
There are a few problems in the I2C.C code posted earlier. Here is a corrected version.
Russ
===========================================
Russ
===========================================
Code: Select all
/*
* Routines to drive a standard I2C bus.
*/
#include <stdio.h>
#include "\JKMicro\H\i2c.h"
#include "\JKMicro\H\Ports186.h"
#define SCL PORTA
#define SCLBIT 0x00
#define SDA PORTB
#define SDABIT 0x00
/*
* I2C Routines derived from the pseudo code by V. Himpe,
* and are likewise released into the Public Domain by:
*
* Russell W. Ranshaw
*
* For more information, visit:
* http://www.ping.be/~ping0751/i2cfaq/i2cindex.htm
*
*/
/*
* I2Cinit is to be called immediately after power up.
* This is normally the only I2C routine to be called
* directly by the application.
*/
void I2Cinit (void) {
int n;
I2Chighsda ();
I2Clowscl ();
for (n = 0; n < 3; n++) {
I2Cstop ();
}
}
void I2Cstart (void) {
I2Chighscl ();
I2Chighsda ();
I2Clowsda ();
I2Clowscl ();
I2Chighsda ();
}
void I2Cstop (void) {
I2Clowsda ();
I2Clowscl ();
I2Chighsda ();
}
int I2Cgetbyte(void)
{
int i_byte = 0, n;
SetInputPort (SDA);
for (n=0; n<8; n++)
{
I2Chighscl();
if (GetPortBit (SDA, SDABIT))
{
i_byte = (i_byte << 1) | 0x01; /* msbit first */
}
else
{
i_byte = i_byte << 1;
}
I2Clowscl();
}
I2Chighsda ();
return(i_byte);
}
void I2Cputbyte(int o_byte)
{
int n;
for(n=0; n<8; n++)
{
if(o_byte&0x80)
{
I2Chighsda();
}
else
{
I2Clowsda();
}
I2Chighscl();
I2Clowscl();
o_byte = o_byte << 1;
}
I2Chighsda();
}
void I2Cgiveack(void)
{
I2Clowsda();
I2Chighscl();
I2Clowscl();
I2Chighsda();
}
void I2Cgetack (void) {
int n;
I2Chighsda ();
I2Chighscl ();
SetInputPort (SDA);
/* Wait until Slave pulls SDA low */
/* Note: The pseudocode does not have the for loop.
* It was added to prevent a lock up situation.
*
* Actually, there should be more error checking and reporting
* in this code. For example, this routine should indicate a
* missed ACK.
*/
for (n = 0; n < 100; n--) {
if (GetPortBit (SDA, SDABIT) == 0)
break;
}
I2Clowscl ();
SetOutputPort (SDA);
}
void I2Chighsda(void)
{
SetOutputPort (SDA);
SetPortBit (SDA, SDABIT);
}
void I2Clowsda(void)
{
SetOutputPort (SDA);
ClearPortBit (SDA, SDABIT);
}
void I2Chighscl(void)
{
SetOutputPort (SCL);
SetPortBit (SCL, SCLBIT);
}
void I2Clowscl(void)
{
SetOutputPort (SCL);
ClearPortBit (SCL, SCLBIT);
}
/*
* Routine to send an address on the I2C bus. To indicate
* adr is a 10-bit address, set the high-order bit (0x8000).
*/
void I2Csendadr (int adr, int rw) {
I2Cstart ();
if ((adr & 0x8000) != 0) {
/* Send two MSBs of the ten bit address */
I2Cputbyte (0xF0 | rw | ((adr > 8) & 0x06));
I2Cgetack ();
I2Cputbyte (adr & 0xFF);
} else {
I2Cputbyte (adr | rw);
}
I2Cgetack ();
}
/* Read num bytes from device adr into buf */
void I2Cread (int adr, int num, char *buf) {
I2Csendadr (adr, 1);
while (num-- > 0) {
*buf++ = I2Cgetbyte ();
if (num > 0) I2Cgiveack ();
}
I2Cstop ();
}
/* Write num bytes to device adr from buf */
void I2Cwrite (int adr, int num, char *buf) {
I2Csendadr (adr, 0);
while (num-- > 0) {
I2Cputbyte (*buf++);
I2Cgetack ();
}
I2Cstop ();
}
Russ
Have you tried Renewable Energy yet?
Have you tried Renewable Energy yet?