直接上代码了,测试通过的
iic.h
- #ifndef _I2C_H_
- #define _I2C_H_
- #include & lt; pic.h & gt;
- #include “define.h”
- /* I2c pin */
- #define I2C_SDA (PORTCbits.RC4)
- #define I2C_SCL (PORTCbits.RC3)
- #define I2C_SDA_DIR (TRISCbits.TRISC4)
- #define I2C_SCL_DIR (TRISCbits.TRISC3)
- /* I2C clock delay time */
- #define I2C_DELAY_VALUE 35
- /* wait time between two I2C transport */
- #define I2C_STOP_WAIT_VALUE 350
- /* I2C init */
- void I2C_Init();
- /* I2C sent data */
- uchar I2C_Puts
- (
- unsigned char SlaveAddr,
- unsigned int SubAddr,
- unsigned char SubMod,
- uchar *dat,
- unsigned int Size
- );
- /* I2C receive data */
- uchar I2C_Gets
- (
- unsigned char SlaveAddr,
- unsigned int SubAddr,
- unsigned char SubMod,
- uchar *dat,
- unsigned int Size
- );
- #endif /* _I2C_H_ */
引脚是RC3和RC4,时间间隔修改I2C_DELAY_VALUE的数值即可。
iic.c
- #include “I2C.h”
- /* variable for delay time */
- uchar I2C_Delay_t;
- /* delay time function */
- #define I2C_Delay() \
- { \
- I2C_Delay_t = (I2C_DELAY_VALUE); \
- while ( –I2C_Delay_t != 0 ) ; \
- }
- /*
- * Name: I2C_Init()
- * Function: initiate I2C bus
- * Description:
- */
- void I2C_Init()
- {
- I2C_SCL_DIR = 0;
- I2C_SCL = 1;
- I2C_Delay();
- I2C_SDA_DIR = 0;
- I2C_SDA = 1;
- I2C_Delay();
- }
- /*
- * Name: I2C_Start()
- * Function: start I2C
- * Description: SDA changes from high to low while SCL stay high. I2C bus stay busy after the function.
- */
- void I2C_Start()
- {
- I2C_SDA = 1;
- I2C_Delay();
- I2C_SCL = 1;
- I2C_Delay();
- I2C_SDA = 0;
- I2C_Delay();
- I2C_SCL = 0;
- I2C_Delay();
- }
- /*
- * Name: I2C_Write(char dat)
- * Function: sent a byte to the bus
- * Parameter: dat, the data sent to the bus
- */
- void I2C_Write( uchar dat )
- {
- unsigned char t = 8;
- do
- {
- /* I2C_SCL = 0; */
- if ( dat & amp; 0x80 )
- I2C_SDA = 1;
- else
- I2C_SDA = 0;
- /* I2C_SDA = (dat&0x80); */
- dat < < = 1;
- /* I2C_Delay(); */
- I2C_SCL = 1;
- I2C_Delay();
- I2C_SCL = 0;
- I2C_Delay();
- }
- while ( –t != 0 );
- }
- /*
- * Name: I2C_Read()
- * Function: read a byte form the slave
- * Return: a byte data
- */
- uchar I2C_Read()
- {
- uchar dat = 0;
- uchar t = 8;
- /* I2C_SDA = 1; // set SDA high before read */
- I2C_SDA_DIR = 1; /* set SDA pin input */
- do
- {
- I2C_SCL = 1;
- I2C_Delay();
- dat < < = 1;
- if ( I2C_SDA )
- dat |= 0x01;
- I2C_SCL = 0;
- I2C_Delay();
- }
- while ( –t != 0 );
- /* I2C_SCL = 0; */
- I2C_SDA_DIR = 0; /* set SDA pin output */
- return(dat);
- }
- /*
- * Name: I2C_GetAck()
- * Function: check ack form the slave
- * Return: 0, get ack
- * 1, ack error
- * Description: the slave sent an ACK after every byte. The slave sent an noACK after the last byte.
- */
- uchar I2C_GetAck()
- {
- uchar ack;
- I2C_SDA = 1;
- I2C_SDA_DIR = 1; /* set SDA pin input */
- I2C_Delay();
- I2C_SCL = 1;
- I2C_Delay();
- /*
- * for(ack=0; ack<255; ack++)
- * { // waiting for SDA get down
- * if(I2C_SDA)
- * continue;
- * }*/
- ack = I2C_SDA;
- /* I2C_Delay(); */
- I2C_SCL = 0;
- I2C_SDA_DIR = 0; /* set SDA pin output */
- I2C_Delay();
- /*
- * if(255 == ack)
- * return 1;
- */
- return(ack);
- }
- /*
- * Name: I2C_PutAck()
- * Function: sent ack or noack to the slave
- * Return: 0, get ack
- * 1, ack error
- * Description: the slave sent an ACK after every byte. The slave sent an noACK after the last byte.
- */
- void I2C_PutAck( uchar ack )
- {
- I2C_SDA = ack;
- I2C_Delay();
- I2C_SCL = 1;
- I2C_Delay();
- I2C_SCL = 0;
- I2C_Delay();
- }
- /*
- * Name: I2C_Stop()
- * Function: stop the bus
- * Description: SDA changes from low to high while SCL stays high will stop the bus.
- */
- void I2C_Stop()
- {
- unsigned int t = I2C_STOP_WAIT_VALUE;
- I2C_SDA = 0;
- I2C_Delay();
- I2C_SCL = 1;
- I2C_Delay();
- I2C_SDA = 1;
- I2C_Delay();
- while ( –t != 0 )
- ; /* need delay between stop and next start */
- }
- /*
- * Name: I2C_Puts()
- * Function: sent serial dates to the slave
- * Parameter: SlaveAddr, address of the slave (no R/W bit)
- * SubAddr: child address of the slave
- * SubMod: mode of child address.0-no child address, 1-a byte child address, 2-two bytes child address.
- * *dat: the data to sent
- * Size: the length of datas
- * Return: 0, sent successfully
- * 1, error
- * Description: SubAddr can be any number if the slave has no child address while SubMod should be zero.
- */
- uchar I2C_Puts(
- unsigned char SlaveAddr,
- unsigned int SubAddr,
- unsigned char SubMod,
- uchar *dat,
- unsigned int Size
- )
- {
- unsigned char i;
- uchar a[3];
- /* check size */
- if ( 0 == Size )
- return(0);
- /* address for the slave */
- a[0] = (SlaveAddr & lt; < 1);
- /* check the mode of child address */
- if ( SubMod & gt; 2 )
- SubMod = 2;
- /* check the child address */
- switch ( SubMod )
- {
- case 0:
- break;
- case 1:
- a[1] = (char) (SubAddr);
- break;
- case 2:
- a[1] = (char) (SubAddr & gt; > 8);
- a[2] = (char) (SubAddr);
- break;
- default:
- break;
- }
- /* sent address of the slave. */
- SubMod++;
- I2C_Start();
- for ( i = 0; i < SubMod; i++ )
- {
- I2C_Write( a[i] );
- if ( I2C_GetAck() )
- {
- I2C_Stop();
- /* PORTBbits.RB6 = 1; */
- return(1);
- }
- }
- /* sent datas */
- do
- {
- I2C_Write( *dat++ );
- if ( I2C_GetAck() )
- break;
- }
- while ( –Size != 0 );
- /* stop the bus after sent all datas */
- I2C_Stop();
- if ( Size == 0 )
- {
- return(0);
- }else {
- return(1);
- }
- }
- /*
- * Name: I2C_Gets()
- * Function: receive datas from the slave
- * Parameters: SlaveAddr, address of the slave (no R/W bit)
- * SbuAddr, child address of the slave
- * SubMod, the mode of the child address. 0-no child address, 1-one byte child address, 2-double bytes child address
- * *dat, the datas received
- * Size, the length of datas
- * Return: 0, receive successful
- * 1, error
- * Description: SubAddr can be any number if the slave has no child address while SubMod should be zero.
- */
- uchar I2C_Gets(
- unsigned char SlaveAddr,
- unsigned int SubAddr,
- unsigned char SubMod,
- uchar *dat,
- unsigned int Size
- )
- {
- uchar i;
- uchar a[3];
- /* check the length */
- if ( 0 == Size )
- return(0);
- /* get address of the slave */
- a[0] = (SlaveAddr & lt; < 1);
- /* check the mode of child address */
- if ( SubMod & gt; 2 )
- SubMod = 2;
- /* sent address of the slave and child address if the slave has child address */
- if ( SubMod != 0 )
- {
- /* check child address */
- if ( 1 == SubMod )
- {
- a[1] = (uchar) (SubAddr);
- }else {
- a[1] = (uchar) (SubAddr & gt; > 8);
- a[2] = (uchar) (SubAddr);
- }
- /* sent address of the slave first, then sent child address */
- SubMod++;
- I2C_Start();
- for ( i = 0; i < SubMod; i++ )
- {
- I2C_Write( a[i] );
- if ( I2C_GetAck() )
- {
- I2C_Stop();
- /* PORTBbits.RB6 = 1; */
- return(1);
- }
- }
- }
- /* start the bus, whatever the slave has child address */
- I2C_Start();
- I2C_Write( a[0] + 1 );
- if ( I2C_GetAck() )
- {
- I2C_Stop();
- return(1);
- }
- /* receive datas */
- for (;; )
- {
- *dat++ = I2C_Read();
- if ( –Size == 0 )
- {
- I2C_PutAck( 1 );
- break;
- }
- I2C_PutAck( 0 );
- }
- /* receive over, stop the bus */
- I2C_Stop();
- return(0);
- }