📄 vi2c_c51.c
字号:
/********************************************************************
VI2C_C51.C
此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据
及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的
与用户程序连接并扩展.....
注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作
一定的修改....
********************************************************************/
#include <reg51.h> /*include head file*/
#include <intrins.h>
#include "VI2C_C51.h"
#define uchar unsigned char /*宏定义*/
#define uint unsigned int
#define _Nop() _nop_();_nop_();_nop_() /*define null operate*/
/*constant/ variable define */
/*endport define*/
sbit SDA=P1^0; /*IIC data bit*/
sbit SCL=P1^1; /*IIC clock control*/
/*status flag*/
bit ack; /*response flag bit */
/*******************************************************************
起start bus function
function original: void Start_I2c();
function: start I2C bus,
********************************************************************/
void Start_I2c()
{
SDA=1; /*data start */
_Nop();
SCL=1;
_Nop(); /*start condition setup up time 4.7us, delay*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; /*tx start signal*/
_Nop(); /*start condition locked time big than 4us*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; /*keep I2C bus, ready tx or rx data*/
_Nop();
_Nop();
}
/*******************************************************************
end bus function
name: void Stop_I2c();
function: end I2C bus,
********************************************************************/
void Stop_I2c()
{
SDA=0; /*tx stop data condition signal*/
_Nop(); /*tx stop clock condition signal*/
SCL=1; /*setup time >4us */
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; /*tx I2C bus stop signal*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
byte data transmit function
original: void SendByte(uchar c);
function: data c Tx-out, data or address, tx done wait response,
and status bit operate. error: ack=0, right ack=1.
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*transmit data length is 8 bit*/
{
if((c<<BitCnt)&0x80)SDA=1; /*check tx bit*/
else SDA=0;
_Nop();
SCL=1; /*set SCL to high, infor device rx data*/
_Nop();
_Nop(); /*hold time >4us */
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1; /*8bit tx done, ready rx ack bit*/
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1; /*check whether rx response bit*/
SCL=0;
_Nop();
_Nop();
}
/*******************************************************************
bit data rx function
original: uchar RcvByte();
function: rx device transmit data, and check bus error(ack=0)
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; /*set SDA to input mode*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0; /*set SCL=0, ready receive data bit*/
_Nop();
_Nop(); /*SCL hold time>4.7us*/
_Nop();
_Nop();
_Nop();
SCL=1; /*set SCL=1, SDA data viable*/
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; /*read SDA, rx data bit input to retc */
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
response sub-function
original: void Ack_I2c(bit a);
function: main control response signal(allow ack or no ack)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; /*ack or no ack*/
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); /*SCL hold time>4us */
_Nop();
_Nop();
_Nop();
SCL=0; /*clean SCL, keep I2C bus to continue rx*/
_Nop();
_Nop();
}
/*******************************************************************
write tx byte data function to has no sub-address device
original: bit ISendByte(uchar sla,ucahr c);
function: from start bus to tx address, data, end bus all process.
sla, c tx content, return 1 operate succeed.
note: before use must end bus.
********************************************************************/
bit ISendByte(uchar sla,uchar c)
{
Start_I2c(); /*启start bus*/
SendByte(sla); /*tx device address*/
if(ack==0)return(0);
SendByte(c); /*tx data*/
if(ack==0)return(0);
Stop_I2c(); /*end bus*/
return(1);
}
/*******************************************************************
write tx data to has sub-address device function
original: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
function: from start bus to tx address, data, end bus all process.
sla, suba, c tx content, return 1 operate succeed.
note: before use must end bus.
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*start bus*/
SendByte(sla); /*tx device address*/
if(ack==0)return(0);
SendByte(suba); /*tx device sub-address*/
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s); /*tx data*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*stop bus*/
return(1);
}
/*******************************************************************
read RX data function for has no sub-address
original: bit IRcvByte(uchar sla,ucahr *c);
功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地
址sla,返回值在c.
如果返回1表示操作成功,否则操作有误。
note: before use end the bus
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
Start_I2c(); /*启start bus*/
SendByte(sla+1); /*tx device address*/
if(ack==0)return(0);
*c=RcvByte(); /*read data*/
Ack_I2c(1); /*tx no-ack bit*/
Stop_I2c(); /*stop bus*/
return(1);
}
/*******************************************************************
read mult. byte data function has sub-address
original: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
function: read data function
note: before use must end bus
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*start bus*/
SendByte(sla); /*tx device address*/
if(ack==0)return(0);
SendByte(suba); /*tx sub-address*/
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte(); /*tx data*/
Ack_I2c(0); /*tx ack bit*/
s++;
}
*s=RcvByte();
Ack_I2c(1); /*tx not ack bit*/
Stop_I2c(); /*stop bus*/
return(1);
}
/*******************************************************************
********************************************************************
********************************************************************
*******************************************************************/
/**********************************************************
write tx data to has not sub-address device function
original: bit ISendStr2(uchar sla,uchar *suba,ucahr *s,uchar no);
function: from start bus to tx address, data, end bus all process.
sla, suba, c tx content, return 1 operate succeed.
note:16 bit sub-address
********************************************************************/
bit ISendStr2(uchar sla,uchar *suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); //启start bus
SendByte(sla); //tx device address
if(ack==0)return(0);
SendByte(*suba); //tx device sub-address
if(ack==0)return(0);
SendByte(*(suba+1)); //tx device sub-address
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s); //tx data
if(ack==0)return(0);
s++;
}
Stop_I2c(); //end bus
return(1);
}
/*******************************************************************
Read rx data to has sub-address device function
original: bit ISendStr2(uchar sla,uchar suba,ucahr *s,uchar no);
function: from start bus to tx address, data, end bus all process.
sla, suba, c tx content, return 1 operate succeed.
note:16 bit sub-address
********************************************************************/
bit IRcvStr2(uchar sla,uchar *suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); //启start bus
SendByte(sla); //TX device address
if(ack==0)return(0);
SendByte(*suba); //TX device sub-address
if(ack==0)return(0);
SendByte(*(suba+1)); //TX deveice sub-address
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte(); //tx data
Ack_I2c(0); //tx ack bit
s++;
}
*s=RcvByte();
Ack_I2c(1); //tx not ack bit
Stop_I2c(); //end bus
return(1);
}
/*******************************************************************
read mult data function for has sub address device
original: bit IwCheck(uchar sla)
function: check whether device reponse, check device write cycle
whether end and device whether exist.
********************************************************************/
bit IwCheck(uchar sla)
{
Start_I2c(); /*启start bus*/
SendByte(sla); /*tx device address*/
if(ack==0)return(0);
Stop_I2c(); /*end bus*/
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -