📄 driver_software_i2c.c
字号:
/**************************************************************************
文 件 名:IO_I2C.c
创 建 人:
创建日期:2008.07.12
组成部分:void I2C_Start(void)
void I2C_Stop(void)
bit I2C_SendData(uint8 send_data)
uint8 I2C_ReceiveData(void)
void I2C_ACK(bit ack)
bit I2C_SendString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
bit I2C_ReceiveString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
bit Write_Byte(uint8 addr,uint8 subaddr,uint8 info)
uint8 Read_Byte(uint8 addr,uint8 subaddr)
描 述:此文件用于对I2C总线的控制工作
修 改 人:
修改日期:
修改内容:
**************************************************************************/
#include "user.h"
#include "intrins.h"
#ifdef I2C
/**************************************************************************
函 数 名: void I2C_Start(void)
功能描述: 用于完成I2C总线的启动工作
全局变量: 无
局部变量: 无
参数说明: 无
输 入: 无
输 出: 无
创 建 人: city
创建日期: 2008.6.1
修 改 人:
日 期:
函数说明:
**************************************************************************/
void I2C_Start(void)
{
SDA=1; //数据线置高电平
_nop_();
SCL=1; //时钟线置高电平
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0; //时钟线置低电平,配合先前的高电平以产生下降沿启动总线
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/**************************************************************************
函 数 名: void I2C_Stop(void)
功能描述: 用于完成I2C总线的停止工作
全局变量: 无
局部变量: 无
参数说明: 无
输 入: 无
输 出: 无
创 建 人: city
创建日期: 2008.5.16
修 改 人:
日 期:
函数说明:
**************************************************************************/
void I2C_Stop(void)
{
_nop_();
SDA=0; //数据线置低电平
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_(); //时钟线置高电平
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1; //数据线置高电平,配合先前的低电平以产生上升降停止总线
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/**************************************************************************
函 数 名: bit I2C_SendData(uint8 send_data)
功能描述: 发送一个字节数据或地址出去
全局变量: 无
局部变量: count ack
参数说明: count为发送字节位数标志循环8位发送一个字节
输 入: send_data待发送的数据
输 出: ack为应答标志
创 建 人: city
创建日期: 2008.5.16
修 改 人: city
日 期: 2008.6.14
函数说明:
**************************************************************************/
bit I2C_SendData(uint8 send_data)
{
uint8 count;
bit ack;
for(count=8;count!=0;count--)
{
if((send_data&0x80)==0x80) //判断当前位为1则发送高电平状态
{
SDA=1; //反之发送低电平
}
else SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_(); //保持时钟高电平周期大于4us,此处为10us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
send_data=send_data<<1; //数据移位高位在前
}
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if(SDA==1)ack=0; //判断应答为0表示被控器件无应答或损坏
else ack=1; //判断应答为1表示发送数据正常
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
return (ack); //返回应答状态标志
}
/**************************************************************************
函 数 名: uint8 I2C_ReceiveData(void)
功能描述: 接收一个字节数据
全局变量: 无
局部变量: count;receivedata
参数说明:count为循环接收数据位次数;receivedtat为收到的数据保存参数
输 入: 无
输 出: receivedata
创 建 人: city
创建日期: 2008.5.16
修 改 人: city
日 期: 2008.6.14
函数说明: 函数不含应答功能
**************************************************************************/
uint8 I2C_ReceiveData(void)
{
uint8 count,receivedata;
SDA=1; //置数据线为输入方式
for(count=8;count!=0;count--)
{
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0; //时钟线置低,准备接收数据位
_nop_(); //时钟低电平周期大于4.7us,此处为10us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
receivedata=receivedata<<1; //循环移位
if(SDA==1) //判断收到的电平为高则对应数据位高置1
{
receivedata=receivedata+1;
}
_nop_();
_nop_();
_nop_();
_nop_();
}
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
return receivedata;
}
/**************************************************************************
函 数 名: void I2C_ACK(bit ack)
功能描述: 当主器件收好一个字节数据后给出应答或非应答
全局变量: 无
局部变量: 无
参数说明:无
输 入: ack
输 出: 无
创 建 人: city
创建日期: 2008.5.16
修 改 人: city
日 期: 2008.6.15
函数说明:
**************************************************************************/
void I2C_ACK(bit ack)
{
if(ack==0)SDA=0; //在此发出应答或非应答信号
else SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_(); //时钟低电平周期大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
_nop_();
}
/**************************************************************************
函 数 名: bit I2C_SendString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
功能描述: 完成一个指定器件的指定地址字符串的发送
全局变量: 无
局部变量: ack,i
参数说明:ack为应答标志,i用于保存len长度用于进行循环
输 入: addr器件地址,subaddr子器件地址,*s为待发送数据地址
len为发送数据长度
输 出: 返回应答标志
创 建 人: city
创建日期: 2008.5.16
修 改 人:
日 期:
函数说明:
*************************************************************************/
bit I2C_SendString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
{
bit ack;
uint8 i;
I2C_Start(); //启动I2C总线
ack=I2C_SendData(addr); //发送硬件地址(针对不同的元件硬件地址有所不同)
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
ack=I2C_SendData(subaddr); //发送器件子地址(若为存储器则为对应写入数据的地址)
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
for(i=len;i!=0;i--) //根据待发送数据长度循环发送指定数组中的数据
{
ack=I2C_SendData(*s); //发送对就地址中数据
s++; //移动数据指针
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
}
I2C_Stop(); //停止I2C总线
return(1); //返回状态标志1确定发送成功
}
/**************************************************************************
函 数 名: I2C总线接收字符串
功能描述:
全局变量: 无
局部变量: 无
参数说明:无
输 入: 无
输 出: 无
创 建 人: city
创建日期: 2008.5.16
修 改 人:
日 期:
函数说明:
**************************************************************************/
bit I2C_ReceiveString(uint8 addr,uint8 subaddr,uint8 *s,uint8 len)
{
bit ack;
uint8 i;
I2C_Start(); //启动I2C总线
I2C_SendData(addr); //发送硬件地址(针对不同的元件硬件地址有所不同)
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
I2C_SendData(subaddr); //发送器件子地址(若为存储器则为对应写入数据的地址)
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
I2C_Start(); //启动I2C总线
I2C_SendData(addr+1); //发送读指定硬件数据指令
if(ack==0)return(0);
for(i=len;i!=0;i--) //读取指定长度数据
{
*s=I2C_ReceiveData(); //读取数据到指定数组地址中
I2C_ACK(0); //返回应答
s++; //指向下一个保存的数据数组空间
}
*s=I2C_ReceiveData();
I2C_ACK(1); //返回应答标志
I2C_Stop(); //停止I2C总线
return(1); //返回状态
}
/**************************************************************************
函 数 名:
功能描述:
全局变量:
局部变量:
参数说明:
输 入:
输 出:
创 建 人:
创建日期:
修 改 人:
日 期:
函数说明:
**************************************************************************/
bit Write_Byte(uint8 addr,uint8 subaddr,uint8 info)
{
bit ack;
I2C_Start(); //启动I2C总线
ack=I2C_SendData(addr); //发送硬件地址(针对不同的元件硬件地址有所不同)
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
ack=I2C_SendData(subaddr); //发送器件子地址(若为存储器则为对应写入数据的地址
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
ack=I2C_SendData(info); //向已经确定的地址写入一个字节的数据
I2C_Stop(); //停止I2C总线
return(1);
}
/**************************************************************************
函 数 名:
功能描述:
全局变量:
局部变量:
参数说明:
输 入:
输 出:
创 建 人:
创建日期:
修 改 人:
日 期:
函数说明:
**************************************************************************/
uint8 Read_Byte(uint8 addr,uint8 subaddr)
{
bit ack;
uint8 info;
I2C_Start(); //启动I2C总线
I2C_SendData(addr); //发送硬件地址(针对不同的元件硬件地址有所不同)
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
I2C_SendData(subaddr); //发送器件子地址(若为存储器则为对应写入数据的地址
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
I2C_Start(); //启动I2C总线
I2C_SendData(addr+1); //发送读指定硬件数据指令
if(ack==0)return(0); //判断应答,为0表明没有收到应答则退出
info=I2C_ReceiveData(); //接收一个字节数据保存到info局部变量中
I2C_ACK(1); //返回应答标志
I2C_Stop(); //停止I2C总线
return(info); //返回接收到的数据
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -