📄 i2c.c
字号:
//sla:器件地址,suda:子地址,*dat:接收或发送缓冲,count:接收或发送的字节数,bs:0接收或1发送,bytes:子地址 1为16bit 0为8bit
#include <reg764.h>
#include <intrins.h>
sbit SDA=P1^3;
sbit SCL=P1^2;
void Nop() { _nop_();_nop_();_nop_();_nop_(); } //空指令大于4.7us
void Start_I2c(void) { SDA=1; SCL=1; Nop(); SDA=0; Nop(); SCL=0; SDA=1; } //起动总线
void Stop_I2c(void) { SDA=0; Nop(); SCL=1; Nop(); SDA=1; } //结束总线
/******************************************
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;
bit SendByte(unsigned char dat)
{
ACC=dat;
SDA=a7;SCL=1;SCL=0;
SDA=a6;SCL=1;SCL=0;
SDA=a5;SCL=1;SCL=0;
SDA=a4;SCL=1;SCL=0;
SDA=a3;SCL=1;SCL=0;
SDA=a2;SCL=1;SCL=0;
SDA=a1;SCL=1;SCL=0;
SDA=a0;SCL=1;SCL=0;
SDA=1;SCL=1;
CY=SDA;
SCL=0;
return CY;
}
unsigned char RcvByte(bit i)
{
SCL=1;a7=SDA;SCL=0;
SCL=1;a6=SDA;SCL=0;
SCL=1;a5=SDA;SCL=0;
SCL=1;a4=SDA;SCL=0;
SCL=1;a3=SDA;SCL=0;
SCL=1;a2=SDA;SCL=0;
SCL=1;a1=SDA;SCL=0;
SCL=1;a0=SDA;SCL=0;
SDA=i; SCL=1; SCL=0; SDA=1;
return(ACC);
}
*********************************************************/
bit SendByte(unsigned char c) //字节发送
{
unsigned char i;
for(i=8;i;i--)
{
c<<=1; //无论C51怎样实现这个操作,始终会使CY=c^7;
SDA=CY;
SCL=1; Nop();
SCL=0; Nop();
}
SDA=1; Nop();
SCL=1; Nop();
CY=SDA;
SCL=0; Nop();
return CY;
}
unsigned char RcvByte(bit a) //字接接收
{
register char dat, i=8;
while(i--)
{
SCL=1; Nop();
dat=(dat<<1)|SDA;
SCL=0; Nop();
}
SDA=a; SCL=1; Nop(); SCL=0; SDA=1; Nop(); //应答
return dat;
}
void delay_i2c(void) // >100us
{
unsigned char i=100; //200us
while(i--) ;
}
/***************************************************有器件地址,立即地址多字节读写 */
bit I2C_A(unsigned char sla,unsigned char data *dat,bit bs,unsigned char count)
{
unsigned char i=255;
while(i--)
{
if(i!=254) delay_i2c();
Start_I2c(); //启动总线
if(SendByte(sla|(~bs))) continue; //发送器件地址
while(count--)
{
if(!bs) { *dat=RcvByte(count?0:1); } //读取数据
else if(SendByte(*dat++)) return 0; //发送数据
}
Stop_I2c(); //结束总线
return 1;
}
return 0;
}
/***************************************************有器件地址,有子地址多字节读写 */
bit I2C_B(unsigned char sla,unsigned int suba,unsigned char data *dat,bit bs,bit bytes,unsigned char count)
{
unsigned char i=255;
while(i--)
{
if(i!=254) delay_i2c();
Start_I2c(); //启动总线
if(bytes)
{
if(SendByte(sla)) continue; //发送器件地址
if(SendByte(suba>>8)) continue; //发送器件子地址 16bit
}
else if(SendByte(((suba&0x77f)>>7|sla))) continue; //发送器件地址
if(SendByte(suba)) continue; //发送器件子地址 16bit & 8bit
if(!bs)
{
Start_I2c();
if(bytes)
{
if(SendByte(sla+1)) continue; //发送器件地址
}
else if(SendByte(((suba&0x77f)>>7|(sla+1)))) continue;
}
while(count--)
{
if(!bs) { *dat++=RcvByte(count?0:1); } //接收数据
else if(SendByte(*dat++)) return 0; //发送数据
}
Stop_I2c(); //结束总线
return 1;
}
return 0;
}
/*************************************************** END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -