中级会员
- 积分
- 478
- 金钱
- 478
- 注册时间
- 2018-10-7
- 在线时间
- 66 小时
|
发表于 2018-10-31 09:17:08
|
显示全部楼层
这里是我整理写的一份IIC通信的函数,解释都标记的很清楚,如果你没看明白,就照着IIC通信的时序图看就应该明白了
#include <reg52.h>
#include <iic.h>
sbit IIC_SDA=P2^6; //声明IIC总线的数据线接在单片机的P2.6端口。
sbit IIC_SCL=P2^7; //声明IIC总线的时钟线接在单片机的P2.5端口。
//void delay(unsigned int t)
//{//延时函数
// while(t){t--;}; //延时循环计数
//}
//-------------------------------------------------------------------
void delay_IIC(void)
{//IIC总线限速延时函数。
//该函数是空函数,延时4个机器周期。
;
;
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
IIC_SDA=1;//释放IIC总线的数据线。
IIC_SCL=1;//释放IIC总线的时钟线。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数
IIC_SDA=1;//拉高数据线
IIC_SCL=1;//拉高时钟线
delay_IIC();
IIC_SDA=0;//在时钟线为高电平时,拉低数据线,产生起始信号。
delay_IIC();
IIC_SCL=0;//拉低时钟线
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
IIC_SDA=0;//拉低数据线
delay_IIC();
IIC_SCL=1;//拉高时钟线。
delay_IIC();
IIC_SDA=1;//时钟时线为高电平时,拉高数据线,产生停止信号。
delay_IIC();
}
//-------------------------------------------------------------------
bit IIC_Tack(void)
{//接收应答信号函数
bit ack;//定义一个位变量,来暂存应答状态。
IIC_SDA=1;//释放数据总线,准备接收应答信号。
delay_IIC();
IIC_SCL=1;//拉高时钟线。
delay_IIC();
ack=IIC_SDA;//读取应答信号的状态。
delay_IIC();
IIC_SCL=0;//拉低时钟线。
delay_IIC();
return ack;//返回应答信号的状态,0表示应答,1表示非应答。
}
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC总线写入一个字节的数据函数
unsigned char i;
for(i=0;i<8;i++)//有8位数据
{
IIC_SDA=Data&0x80;//写最高位的数据
delay_IIC();
IIC_SCL=1; //拉高时钟线,将数写入到设备中。
delay_IIC();
IIC_SCL=0;//拉低时钟线,允许改变数据线的状态
delay_IIC();
Data=Data<<1;//数据左移一位,把次高位放在最高位,为写入次高位做准备
}
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//从IIC总线读取一个字节的数据函数
unsigned char i;
unsigned char Data; //定义一个缓冲寄存器。
for(i=0;i<8;i++)//有8位数据
{
IIC_SCL=1;//拉高时钟线,为读取下一位数据做准备。
delay_IIC();
Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
delay_IIC();
if(IIC_SDA)//如果数据线为高平电平。
Data=Data|0x1;//则给缓冲字节的最低位写1。
IIC_SCL=0;//拉低时钟线,为读取下一位数据做准备。
delay_IIC();
}
return Data;//返回读取的一个字节数据。
}
void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data)
{//向任意地址写入一个字节数据函数
IIC_start();//产生起始信号
IIC_write_byte(Daddr);//写入设备地址(写)
IIC_Tack();//等待设备的应答
IIC_write_byte(Waddr);//写入要操作的单元地址。
IIC_Tack();//等待设备的应答。
IIC_write_byte(Data);//写入数据。
IIC_Tack();//等待设备的应答。
IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr)
{//从任意地址读取一个字节数据函数
unsigned char Data;//定义一个缓冲寄存器。
IIC_start();//产生起始信号
IIC_write_byte(Daddr);//写入设备地址(写)
IIC_Tack();//等待设备的应答
IIC_write_byte(Waddr);//写入要操作的单元地址。
IIC_Tack();//等待设备的应答。
IIC_start();//产生起始信号
IIC_write_byte(Daddr+1);//写入设备地址(读)。
IIC_Tack();//等待设备的应答。
Data=IIC_read_byte();//写入数据。
IIC_stop();//产生停止符号。
//-------------------返回读取的数据--------------------
return Data;//返回读取的一个字节数据。
}
/*
*********************************************************************************************************
* 函 数 名: i2c_Ack
* 功能说明: CPU产生一个ACK信号
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
SDA = 0;//响应
i2c_Delay();
SCL = 1;
i2c_Delay();
SCL = 0;
i2c_Delay(); //在SCL为高电平期间SDA都为0即产生一个应答信号
SDA = 1; //释放总线
i2c_Delay();
}
/*
*********************************************************************************************************
* 函 数 名: i2c_NAck
* 功能说明: CPU产生1个NACK信号
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
SDA = 1;
i2c_Delay();
SCL = 1;
i2c_Delay();
SCL = 0;
i2c_Delay(); //在SCL为高电平期间SDA都为1即产生一个非应答信号
}
/*
*********************************************************************************************************
* 函 数 名: i2c_SendByte
* 功能说明: CPU向I2C总线设备发送8bit数据
* 形 参: _ucByte : 等待发送的字节
* 返 回 值: 无
*********************************************************************************************************
*/
/******
void i2c_SendByte(unsigned char _ucByte)
{
unsigned char i; //其实信号开始后SCL是被拉低的
for(i = 0; i < 8; i++)
{
if(_ucByte & 0x80)
SDA = 1;
else
SDA = 0;
SCL = 1;
i2c_Delay();
SCL = 0; //SCL等于0的时候写数据
if(i == 7) //最后一次时释放总线
{
SDA = 1;
}
_ucByte<<=1; //左移一位
i2c_Delay();
}
}
/*
*********************************************************************************************************
* 函 数 名: i2c_ReadByte
* 功能说明: CPU从I2C总线设备读取8bit数据
* 形 参: 无
* 返 回 值: 读到的数据
*********************************************************************************************************
*/
/***unsigned char i2c_ReadByte(void)
{
unsigned char i;
unsigned char value = 0;
for(i = 0; i < 8; i++)
{
value<<=1;
SCL = 1; //稳定状态的时候读数据
if(SDA == 1)
value++;
SCL = 0; //允许数据变化
i2c_Delay();
}
return value;
}
****/
/*
*********************************************************************************************************
* 函 数 名: i2c_WaitAck
* 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
* 形 参: 无
* 返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
unsigned char i2c_WaitAck(void)
{
unsigned char re; //应答信号等于0则应答正确,等于1则没有应答
SDA = 1; //释放总线,能让对方拉低
i2c_Delay();
SCL = 1; //此时刻开始,数据保持应答状态稳定
i2c_Delay();
if(SDA == 1)
{
re = 1; //没有应答
}
else
{
re = 0; //应答正确
}
SCL = 0;
i2c_Delay();
return re;
} |
|