📄 iicbusc.c
字号:
#include "52init.h"
#define iicnop 2
bit bACK;
sbit pSDA=P3^6;
sbit pSCL=P3^7;
void iicdelay(uchar delay_num) //22.1184 the loop time is 0.543us
{
uchar i,k; //delay_num 8us/num
for(i=delay_num;i>0;i--)
{
for(k=15;k>0;k--)
{;}
}
}
void iicStart()
{
uchar i;
pSDA=1;//发送起始条件的数据信号
pSCL=1; //发送起始条件的时钟信号
while(pSCL==0){;}
for(i=0;i<iicnop;i++){_nop_();}//起始条件建立时间大于0.6us, 延时,看IIC 总线的datasheet
pSDA=0;
for(i=0;i<iicnop;i++){_nop_();}
pSCL=0;//钳定总线,开始发送数据
}
void iicStop()
{
uchar i;
pSDA=0;//发送结束条件的数据信号
pSCL=1;//发送结束条件的时钟信号
while(pSCL==0){;}
pSDA=1;
for(i=0;i<iicnop;i++){_nop_();}
for(i=0;i<iicnop;i++){_nop_();}
pSCL=0;
}
/**************对IIC总线产生应答******************/
void iicMack()
{
uchar i;
pSDA=0;
pSCL=1;
for(i=0;i<iicnop;i++){_nop_();}
pSCL=0;
pSDA=1;
}
/**************不对IIC总线产生应答*******************/
void iicMnack()
{
uchar i;
pSDA=1;
pSCL=1;
for(i=0;i<iicnop;i++){_nop_();}
pSCL=0;
pSDA=0;
}
/**************检查应答位*******************/
void iicCack() //8位发送完后释放数据线,准备接收应答位
{
uchar i;
pSDA=1;
pSCL=1; //在scl为1的时候等待sda值的变化,在器件接受到数据后会把sda拉低
bACK=0;
if(pSDA==0)//当从器件接受到了ack 就会将pSDA 置低
{
pSCL=0;
for(i=0;i<iicnop;i++){_nop_();}
}
else
{//若pSDA=1表示从器件没有应答,
bACK=1;//值非应答标志位为1
pSCL=0;
for(i=0;i<iicnop;i++){_nop_();}
}
}
void iicwrbyt0()//向某一位写0
{
uchar i;
pSDA=0;
pSCL=1;
for(i=0;i<iicnop;i++){_nop_();} //保证时钟高电平周期大于0.6 μs
pSCL=0; // SCL为低电平时,SDA才能改变
}
void iicwrbyt1()//向某一位写1
{
uchar i;
pSDA=1;
pSCL=1;
for(i=0;i<iicnop;i++){_nop_();} //保证时钟高电平周期大于0.6 μs
pSCL=0; // SCL为低电平时,SDA才能改变
pSDA=0;
}
void iicwrbyt(uchar WrData)//SDA线上的数据必须在时钟的高电平周期保持稳定
{
uchar i,j;
if((WrData&0x80)>0) //判断发送位是1还是0 ,是1 SDA置1 ,是0 SDA 置0
{pSDA=1;}
else
{pSDA=0;}
pSCL=1; //置时钟线为高,通知被控器开始接收数据位
while(pSCL==0){;}
for(i=0;i<iicnop;i++){_nop_();}//保证时钟高电平周期大于0.6 μs
pSCL=0;//SCL为低电平时,SDA才能改变
pSDA=0;
WrData=_crol_(WrData,1);
for(j=1;j<8;j++)
{
if((WrData&0x80)>0)
{iicwrbyt1();}
else
{iicwrbyt0();}
WrData=_crol_(WrData,1);
}
}
uchar iicrdbyt()
{
uchar RdData=0xff,j;
for(j=0;j<8;j++)
{
pSDA=1;
pSCL=1;
if(pSDA==0)
{
RdData=RdData&0x7f;
RdData=_crol_(RdData,1);
pSCL=0;
}
else
{
RdData=RdData|0x80;
RdData=_crol_(RdData,1);
pSCL=0;
}
}
return(RdData);
}
void iic24cxxwr(uchar WrAddr,uchar WrData)
{
do{
do{
do{
iicStart();
iicwrbyt(0xa0);
iicCack();
}while(bACK==1);
iicwrbyt(WrAddr);
iicCack();
}while(bACK==1);
iicwrbyt(WrData);
iicCack();
}while(bACK==1);
iicStop();
}
void saa7114wr(uchar addr7114,uchar data7114)
{
do{
do{
do{
iicStart();//iic 启动
iicwrbyt(0x40);//控制字节
iicCack();//应答信号位,用来告诉发送器,已经收到了这个字节,传输成bACK值为0
}while(bACK==1);//如果应答位为1 ,说明接受器没有接受到此信号,数据传输失败
iicwrbyt(addr7114);//将要写入字节的地址
iicCack();
}while(bACK==1);//容错机制
iicwrbyt(data7114);//要写入的数据
iicCack();
}while(bACK==1);//容错机制
iicStop();//iic 停止
}
uchar saa7114rd(uchar addr7114)
{
uchar temp;
do{
do{
do{
iicStart();
iicwrbyt(0x40);//发送SAA7114 写地址
iicCack();
}while(bACK==1);
iicwrbyt(addr7114);//发生SAA7114 子地址
iicCack();
}while(bACK==1);
iicStart();//如果是读要重新启动IIC 总线
iicwrbyt(0x41);//发送SAA7114 读地址
iicCack();
}while(bACK==1);
temp=iicrdbyt();
iicStop();
return(temp);
}
void saa7121wr(uchar addr7121,uchar data7121)
{
do{
do{
do{
iicStart();
iicwrbyt(0x88);
iicCack();
}while(bACK==1);
iicwrbyt(addr7121);
iicCack();
}while(bACK==1);
iicwrbyt(data7121);
iicCack();
}while(bACK==1);
iicStop();
}
uchar saa7121rd(uchar addr7121)
{
uchar temp;
do{
do{
do{
iicStart();
iicwrbyt(0x88);
iicCack();
}while(bACK==1);
iicwrbyt(addr7121);
iicCack();
}while(bACK==1);
iicStart();
iicwrbyt(0x89);
iicCack();
}while(bACK==1);
temp=iicrdbyt();
iicStop();
return(temp);
}
void iic4272wr(uchar WrAddr,uchar WrData)
{
do{
do{
do{
iicStart();
iicwrbyt(0x20);
iicCack();
}while(bACK==1);
iicwrbyt(WrAddr);
iicCack();
}while(bACK==1);
iicwrbyt(WrData);
iicCack();
}while(bACK==1);
iicStop();
}
uchar iic4272rd(uchar RdAddr)
{
uchar temp;
do{
do{
do{
iicStart();
iicwrbyt(0x20);
iicCack();
}while(bACK==1);
iicwrbyt(RdAddr);
iicCack();
}while(bACK==1);
iicStart();
iicwrbyt(0x21);
iicCack();
}while(bACK==1);
temp=iicrdbyt();
iicStop();
return(temp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -