📄 iic.c
字号:
/******************************************************************************
* CPU: Winbond W79E834
* Purpose: IIC.c
* Creator: Ningweiming
* Version: Revision: 0
* File Name: $Workfile: iic.c $
******************************************************************************/
#include "all_func.h"
#include "main_func.h"
unsigned char i2cSlaveAddress = 0xA0;
unsigned char I2C_Data_buf[6];
#define i2c_half_delay()
#define i2c_delay() {unsigned char i=0;while (i!=7)i++;};
#define SCL_H() {SCL_PIN = 1;} /* SCL high */
#define SCL_L() {SCL_PIN = 0;} /* Pull SCL down */
#define SDA_H() {SDA_PIN = 1;} /* SDA high using external pull-up (SDA is input)*/
#define SDA_L() {SDA_PIN = 0;} /* Pull SDA down */
unsigned char SDA_IN(void)
{
SDA_H();
if (SDA_PIN == 0x00) return(0);
else return(1);
}
unsigned char i2c_error = 0; /* Last error */
/*
* Makes sure that the bus is in a known condition. Returns 1 on success,
* 0 if some other device is pulling on the bus.
*/
void i2c_init(void)
{
SCL_H();
SDA_H();
i2c_error = 0;
}
unsigned char i2c_start(void)
{
SCL_H(); /* EHO: 15-07-2003 in case of repeated start, first scl high */
SDA_L();
_nop_();
_nop_();
_nop_();
_nop_();
// i2c_delay();
SCL_L();
return 0;
}
void i2c_stop(void)
{
SDA_L(); /* Pull SDA down if it was not down */
_nop_();
_nop_();
_nop_();
_nop_();
i2c_delay();
SCL_H();
_nop_();
_nop_();
_nop_();
_nop_();
i2c_delay();
SDA_H();
}
void i2c_bit_out(bit bout)
{
SDA_PIN=bout;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL_H();
_nop_();
_nop_();
_nop_();
_nop_();
// i2c_delay();
_nop_();
_nop_();
SCL_L();
}
unsigned char i2c_bit_in(void)
{
unsigned char bin;
unsigned char i=0;
_nop_();
_nop_();
SCL_H(); /* Let SCL go up */
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
bin = SDA_IN(); /* Read in data */
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL_L();
return bin;
}
/*
* Send one byte on the bus. No start or stop conditions are generated here,
* but i2c_error will be set according to the result.
* Returns 0 on success, 1 if we lose arbitration or if the slave doesn't
* acknowledge the byte. Check i2c_error for the actual result on error.
*/
unsigned char I2cSentByte(unsigned char dat)
{
unsigned char bit_count;
bit_count = 8;
while(bit_count)
{
if (dat & 0x80)
{
SDA_PIN=1;
}
else
{
SDA_PIN=0;
}
_nop_();
_nop_();
_nop_();
SCL_H();
dat <<= 1;
bit_count--;
SCL_L();
}
SDA_PIN=1;
_nop_();
_nop_();
_nop_();
SCL_H();
_nop_();
_nop_();
_nop_();
SCL_L();
return 0;
}
/*
* Reads one byte in from the slave. Ack must be 1 if this is the last byte
* to be read during this transfer, 0 otherwise (as per I2C bus specification,
* the receiving master must acknowledge all but the last byte during a
* transfer).
*/
unsigned char I2cReadByte(unsigned char ack)
{
unsigned char bit_count, byte_in;
bit_count = 8;
byte_in = 0;
while(bit_count)
{
byte_in <<= 1;
SCL_H(); /* Let SCL go up */
if(SDA_PIN==1)
{
byte_in|=1;
}
else byte_in|=0;
SCL_L();
bit_count--;
}
if(ack==0)
{
SDA_PIN=0;
}
else SDA_PIN=1;
SCL_H();
_nop_();
_nop_();
_nop_();
_nop_();
SCL_L();
SDA_H();
return byte_in;
}
unsigned char I2C_Write_Byte(unsigned char map, unsigned char dat)
{
return (I2C_Write_Buf(map, &dat, 1));
}
unsigned char I2C_Read_Byte(unsigned char map)
{
unsigned char tmp;
unsigned char result;
/* we do not want to overwrite I2C_Data_buf[0] */
tmp = I2C_Data_buf[0];
I2C_Read_Buf(map, 1);
result = I2C_Data_buf[0];
/* set back the old data */
I2C_Data_buf[0] = tmp;
return (result);
}
/* read data is availeble in RX_Data_recv_array */
unsigned char I2C_Read_Buf (unsigned char map, unsigned char rx_count)
{
if ( I2C_Write_Buf (map, &map, 0))/* second map addres is dummy pointer no data writtten only i2cSlave address and map address*/
{
if (i2c_error != I2CERR_LOST) i2c_stop();
return 1;
}
SDA_H(); /* One of these may be low now, in which case the next */
SCL_H(); /* start condition wouldn't be detected so make */
i2c_delay(); /* sure that they're up and wait for one delay slot */
if (i2c_recv(rx_count)) return 1;
return (i2c_error ? 1 : 0);
}
/*
* Read in 'count' bytes from slave 'addr'.
* Returns 0 on success.
*/
unsigned char i2c_recv(unsigned char count)
{
unsigned char byteptr, byte_in;
if (i2c_start()) return 1;
i2c_error = 0;
byteptr = 0;
byte_in = i2cSlaveAddress | 0x01;
if (I2cSentByte(byte_in)) //send device address
{
if (i2c_error == 1) i2c_stop();
return i2c_error;
}
while(count)
{
if (--count)
{
byte_in = I2cReadByte(0);
}
else
{
byte_in = I2cReadByte(1); /* No ACK during last byte */
}
I2C_Data_buf[byteptr] = byte_in;
byteptr++;
}
i2c_stop();
return (i2c_error ? 1 : 0);
}
/***************************************
* addr: first writed address
* *buf: data buffer first address
* count: byte numbers
****************************************/
unsigned char I2C_Write_Buf (unsigned char addr, unsigned char *buf, unsigned char count)
{
unsigned char byte_out;
if (i2c_start()) return 1; //start I2C
i2c_error = 0;
byte_out = i2cSlaveAddress & 0xFE;
if (I2cSentByte(byte_out)) //send device address
{
if (i2c_error == 1)
{
i2c_stop();
}
return i2c_error;
}
byte_out = addr;
count = count+1;
while(count)
{
if (I2cSentByte(byte_out)) //send sub address
{
if (i2c_error == 1)
{
i2c_stop();
}
return i2c_error;
}
else byte_out = *buf++;//send data
i2c_delay();
count--;
}
i2c_stop();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -