iic.c
来自「基于STC12C5410AD单片机的IIC总线读写C语言程序」· C语言 代码 · 共 297 行
C
297 行
/********************************************************
* 文件名称:
* IIC.c
* 文件说明:
* 使用口线模拟IIC
*********************************************************/
/****************声明引用的外部变量***********************/
extern unsigned char Intake_Grade; //进风等级
extern unsigned char Exhaust_Grade; //出风等级
extern unsigned char Tempture_Targ; //目标温度
extern unsigned char Humidity_Targ; //目标湿度
/*********************************************************
* 数据定义
*********************************************************/
bit bdata ack;
unsigned char SlvAdr; //被控器地址
unsigned char SubAdr; //被控器单元地址
unsigned char ByteCnt; //待发送字节数
unsigned char addr_Buf; //高地址缓冲
unsigned char Ack_Flag; //应答标识
unsigned char eep_rcvbuf[EEP_DATBUF]; //定义接收数据缓冲
unsigned char eep_sndbuf[EEP_DATBUF]; //定义发送数据缓冲
/*端口定义*/
sbit SDA = P1^5; //模拟数据传送位
sbit SCL = P1^6; //模拟时钟控制位
sbit WP = P1^7; //芯片写保护控制位
/*********************************************************
* 启动IIC
*********************************************************/
void start_iic(void)
{
WP = 0; //取消芯片写保护
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 1; //发送起始条件的数据信号
_Nop();
SCL = 1;
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 0;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0;
_Nop();
_Nop();
}
/*********************************************************
* 结束IIC
*********************************************************/
void stop_iic(void)
{
SDA = 0;
_Nop();
SCL = 1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 1;
_Nop();
_Nop();
_Nop();
_Nop();
//WP = 1; //芯片写保护
}
/**********************************************
名称:void SendByte(unsigned c)
描述:字节数据传送函数
功能:将数据c发送出去,可以是地址也可以是数据,发送完毕等待应答
发送数据正常ack=1, ack=0表示被控器无应答或损坏
***********************************************/
void SendByte(unsigned char c)
{
uchar bitcnt;
uchar tmp=0x80;
for(bitcnt=0;bitcnt<8;bitcnt++)
{
if(c&tmp)SDA = 1;
else SDA = 0;
_Nop();
SCL = 1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0;
tmp = tmp>>1;
}
_Nop();
_Nop();
SDA = 1; //8位发送完毕后释放数据线,准备接收应答位
_Nop();
_Nop();
SCL = 1;
_Nop();
_Nop();
_Nop();
if(SDA == 1)ack = 0; //判断是否接收到应答信号
else
{ack = 1;//Flash_InSetFlag = 1;
}
SCL = 0;
_Nop();
_Nop();
}
/***************************************
名称:RcvByte()
描述:字节数据传送函数
功能:用来接受从器件传来的数据,并判断总线错误
******************************************/
unsigned char RcvByte()
{
uchar retc;
uchar bitcnt;
retc = 0;
SDA = 1; //置数据线为输入方式
for(bitcnt=0;bitcnt<8;bitcnt++)
{
_Nop();
SCL = 1; //置时钟线为高使数据线上数据有效
_Nop();
_Nop();
_Nop();
_Nop();
retc = retc<<1;
if(SDA==1)retc = retc+1;
_Nop();
_Nop();
SCL = 0; //置时钟线为低准备接收数据
_Nop();
_Nop();
_Nop(); //时钟低电平周期大于4.7μs
_Nop();
}
SCL = 0;
_Nop();
_Nop();
return(retc);
}
/****************************************
名称:Ack_iic(bit a)
描述:应答子程序
功能:主控器进行应答信号(可以是应答或非应答信号)
*****************************************/
void Ack_iic(bit a)
{
if(a==0)SDA = 0; //在此发出应答或非应答信号
else SDA = 1;
_Nop();
_Nop();
_Nop();
SCL = 1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0;
_Nop();
_Nop();
}
/*****************************************
名称:ISendByte
描述:向无子地址器件发送字节数据函数
功能:从启动总线到发送地址,数据,总线结束的全过程,
bit ISendByte(uchar sla,uchar c)
{
start_iic(); //启动总线
SendByte(sla);
if(ack==0)return(0); //发送器件地址
SendByte(c);
if(ack==0)return(0); //发送数据
stop_iic();
return(1);
}
*****************************************/
/************************************************
名称:ISendStr
描述:向有子地址器件发送多字节数据
功能:
入口参数:sla 器件地址,suba 子地址,s 指向发送的内容,num 发送的字节数
出口参数:1表示操作成功,否则操作有误
************************************************/
bit ISendStr(uchar sla, uchar suba, uchar *s, uchar num)
{
uchar i;
start_iic(); //启动总线
SendByte(sla); //发送器件地址
if(ack==0){return(0);}
SendByte(suba); //发送器件子地址
if(ack==0){return(0);}
for(i=0;i<num;i++)
{
SendByte(*s);
if(ack==0) {return(0);}
s++;
}
stop_iic();
return(1);
}
/***********************************************
名称:IRcvByte(unsigned char sla,unsigned char *c)
描述:向无子地址器件读字节数据函数
说明:从启动总线到发送地址,读数据,结束总线的全过程,从器件地址sla
返回值在c.如果返回1表示成功,否则操作有误
bit IRcvByte(unsigned char sla,unsigned char *c)
{
start_iic(); //启动总线
SendByte(sla+1);
if(ack==0)return(0);
*c = RcvByte();
Ack_iic(1);
stop_iic();
return(1);
}
***********************************************/
/***********************************************
名称:IRcvByte(unsigned char sla,unsigned char *c)
描述:向有子地址器件读取多字节数据函数
说明:从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件地址sla
子地址suba,读出的内容放入s指向的存储区.读num个字节,如果返回1表示成功,否则操作有误
***********************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar num)
{
uchar i;
start_iic(); //启动总线
SendByte(sla); //发送器件地址和写命令
if(ack==0)return(0);
SendByte(suba); //写子地址
if(ack==0)return(0);
start_iic(); //启动总线
SendByte(sla+1); //发送器件地址和读命令
if(ack==0){return(0);Flash_InSetFlag = 1;}
for(i=0;i<num-1;i++)
{
s[i]=RcvByte();
Ack_iic(0);
}
s[i]=RcvByte(); //接受最后一个字节后发送非应答信号
Ack_iic(1);
stop_iic();
return(1);
}
void ReadSysPara(void) //读取系统参数
{
IRcvStr(at24c02,0x00,eep_rcvbuf,4);
Intake_Grade = eep_rcvbuf[0];
Exhaust_Grade = eep_rcvbuf[1];
Tempture_Targ = eep_rcvbuf[2];
Humidity_Targ = eep_rcvbuf[3];
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?