📄 iic.c
字号:
/*************************************************//*****************I2C串行总线********************//****************2003年1月15日*******************//************WROTE BY ZLGMCU********************//************MODIFY BY WANGSW********************/ #include <intrins.h> #include "reg52x2.h" /*头文件的包含*/#include "define.h"#include "interrupt.h"#include "iic.h" /*端口位定义*/sbit SDA=P3^4; /*模拟I2C数据传送位*/sbit SCL=P3^5; /*模拟I2C时钟控制位*/ /*状态标志*/bool ack; /*应答标志位*/static void StartI2c(void);static void StopI2c(void);static bool SendByte(byte value);static byte RcvByte(void);static void AckI2c(bool bFlag);/**********************************************************************/static void StartI2c(){ SDA = 1; /*发送起始条件的数据信号*/ _nop_(); SCL = 1; _nop_(); SDA = 0; /*发送起始信号*/ _nop_(); SCL = 0; /*钳住I2C总线,准备发送或接收数据 */}static void StopI2c(){ SDA = 0; /*发送结束条件的数据信号*/ _nop_(); SCL = 1; /*结束条件建立时间大于4μs*/ _nop_(); SDA = 1; /*发送I2C总线结束信号*/}static bool SendByte(byte value){ byte data i; for(i = 0; i < 8; i++) /*要传送的数据长度为8位*/ { SCL = 0; if((value << i) & 0x80) /*取数据,并转串*/ { SDA = 1; } else { SDA = 0; } _nop_(); SCL = 1; /*置时钟线为高,通知被控器开始接收数据位*/ _nop_(); } SCL = 0; _nop_(); SDA = 1; /*8位发送完后释放数据线,准备接收应答位*/ _nop_(); SCL = 1; _nop_(); if(SDA) { ack = 0; } else { ack = 1; /*判断是否接收到应答信号*/ } _nop_(); SCL = 0; return(ack);}static byte RcvByte(){ byte data i; byte data retc; retc = 0; SDA = 1; /*置数据线为输入方式*/ for(i = 0; i < 8; i++) { SCL = 0; /*置时钟线为低,准备接收数据位*/ _nop_(); SCL = 1; /*置时钟线为高使数据线上数据有效*/ _nop_(); retc = retc << 1; if(SDA) { retc = retc + 1; /*读数据位,接收的数据位放入retc中 */ } } SCL = 0; return(retc);}static void AckI2c(bool bFlag){ if(bFlag) { SDA = 1; /*在此发出应答或非应答信号 */ } else { SDA = 0; } _nop_(); SCL = 1; _nop_(); SCL = 0; /*清时钟线,钳住I2C总线以便继续接收*/ }/***************************************************************/extern bool iic_send_byte(byte SlaveAddress, byte value){ StartI2c(); /*启动总线*/ if(!SendByte(SlaveAddress)) /*发送器件地址*/ { return(FALSE); } if(!SendByte(value)) /*发送数据*/ { return(FALSE); } StopI2c(); /*结束总线*/ return(TRUE);}extern bool iic_rcv_byte(byte SlaveAddress, byte value){ StartI2c(); /*启动总线*/ if(!SendByte(SlaveAddress + 1)) /*发送器件地址*/ { return(FALSE); } value = RcvByte(); /*读取数据*/ AckI2c(TRUE); /*发送非就答位*/ StopI2c(); /*结束总线*/ return(TRUE);}extern bool iic_send_str(byte SlaveAddress, byte address, byte *source, byte len) { byte i; StartI2c(); /*启动总线*/ if(!SendByte(SlaveAddress)) /*发送器件地址*/ { return(FALSE); } if(!SendByte(address)) /*发送器件子地址*/ { return(FALSE); } for(i = 0; i < len; i++) { if(!SendByte(*source)) /*发送数据*/ { return(FALSE); } source++; } StopI2c(); /*结束总线*/ return(TRUE);}extern bool iic_rcv_str(byte SlaveAddress, byte address, byte *source, byte len){ byte i; StartI2c(); /*启动总线*/ if(!SendByte(SlaveAddress)) /*发送器件地址*/ { return(FALSE); } if(!SendByte(address)) /*发送器件子地址*/ { return(FALSE); } StartI2c(); if(!SendByte(SlaveAddress+1)) { return(FALSE); } for(i = 0; i < len - 1; i++) { *source = RcvByte(); /*接收数据*/ AckI2c(FALSE); /*发送就答位*/ source++; } *source = RcvByte(); AckI2c(TRUE); /*发送非应位*/ StopI2c(); /*结束总线*/ return(TRUE);}extern bool iiv_send_long_str(byte SlaveAddress, word address, byte *source, byte len){ byte i; StartI2c(); /*启动总线*/ if(!SendByte(SlaveAddress)) /*发送器件地址*/ { return(FALSE); } if(!SendByte(HBYTE(address))) /*发送器件地址*/ { return(FALSE); } if(!SendByte(LBYTE(address))) /*发送器件子地址*/ { return(FALSE); } for(i = 0; i < len; i++) { if(!SendByte(*source)) /*发送数据*/ { return(FALSE); } source++; } StopI2c(); /*结束总线*/ return(TRUE);}extern bool iic_rcv_long_str(byte SlaveAddress, word address, byte *source, byte len){ byte i; StartI2c(); /*启动总线*/ if(!SendByte(SlaveAddress)) /*发送器件地址*/ { return(FALSE); } if(!SendByte(HBYTE(address))) /*发送器件子地址*/ { return(FALSE); } if(!SendByte(LBYTE(address))) /*发送器件子地址*/ { return(FALSE); } StartI2c(); if(!SendByte(SlaveAddress+1)) { return(FALSE); } for(i = 0; i < len - 1; i++) { *source = RcvByte(); /*发送数据*/ AckI2c(FALSE); /*发送就答位*/ source++; } *source = RcvByte(); AckI2c(TRUE); /*发送非应位*/ StopI2c(); /*结束总线*/ return(TRUE);}extern bool iic_24c64_write(word wAddr, byte *source, byte len){ byte idata i; byte idata j; byte idata temp; temp = (byte)wAddr & 0x1F; if((32-temp) > len) { return(iiv_send_long_str(CAT24WC64, wAddr, source, len)); } else { if(!iiv_send_long_str(CAT24WC64, wAddr, source, 32 - temp)) { return(FALSE); } } j = (len + temp -32) >> 5; //printf("%x\n", (word)j); wAddr = (wAddr & 0xFFE0) + 0x20; source = source + (32 - temp); if(j) { for(i = 0; i < j; i++) { delay(1000); if(!iiv_send_long_str(CAT24WC64, wAddr, source, 32)) { return(FALSE); } wAddr = wAddr + 0x20; source = source + 0x20; } } temp = (len + temp - 32) & 0x1F; //printf("%x\n", (word)wAddr); //printf("%x\n", (word)source); //printf("%x\n", (word)temp); if(temp) { delay(1000); return(iiv_send_long_str(CAT24WC64, wAddr, source, temp)); }}extern bool iic_24c64_read(word wAddr, byte *source, byte len){ return(iic_rcv_long_str(CAT24WC64, wAddr, source, len));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -