历史上的今天
今天是:2025年04月23日(星期三)
2020年04月23日 | 51单片机——I2C总线驱动程序
2020-04-23 来源:eefocus
为方便移植,采用多文件工程的方式。
void Delay10us()//延时10us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿
void I2cStart()//为方便与其他函数衔接,起始之后SDA和SCL都为0,虽然这与I2C总线空闲状态不符,但并不影响程序运行
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();//建立时间是SDA保持时间>4.7us
SDA=0;
Delay10us();//保持时间是>4us
SCL=0;
Delay10us();
}
终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
void I2cStop()//结束之后保持SDA和SCL都为1;表示总线空闲
{
SDA=0;
Delay10us();
SCL=1;
Delay10us();//建立时间大于4.7us
SDA=1;
Delay10us();
}
I2cSendByte(unsigned char dat) : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定
unsigned char I2cSendByte(unsigned char dat)//发送成功返回1,发送失败返回0
{
unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。
for(a=0;a<8;a++)//要发送8位,从最高位开始
{
SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号
dat=dat<<1;
Delay10us();
SCL=1;
Delay10us();//建立时间>4.7us
SCL=0;
Delay10us();//时间大于4us
}
SDA=1;//¥¥¥
Delay10us();
SCL=1;
while(SDA)//等待应答,也就是等待从设备把SDA拉低
{
b++;
if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
{
SCL=0;
Delay10us();
return 0;
}
}
SCL=0;
Delay10us();
return 1;
}
I2cReadByte() :使用I2c读取一个字节
unsigned char I2cReadByte()
{
unsigned char a=0,dat=0;
SDA=1; //¥¥¥
Delay10us();
for(a=0;a<8;a++)//接收8个字节
{
SCL=1;
Delay10us();
dat<<=1;
dat|=SDA;
Delay10us();
SCL=0;
Delay10us();
}
return dat;
}
在以上两个函数中,在“¥¥¥”处,都将SDA置为1,这是将SDA线释放。原因如下:
I2C的数据和时钟线上都有一个上拉电阻,电阻的另一端接一个高电平。当I2C工作时,SDA上的电平取决于SDA上的数据。当I2C不工作时,因为集成电路的输入端为高阻状态,SDA上的电压就取决于电阻另一端的高电平了,因此I2C在释放总线后,SDA就等于1了。
对于I2C总线的解释:https://blog.csdn.net/cax1165/article/details/86755169
void At24c02Write(unsigned char addr,unsigned char dat) :往24c02的一个地址写入一个数据
void At24c02Write(unsigned char addr,unsigned char dat)
{
I2cStart();
I2cSendByte(0xa0);//发送写器件地址
I2cSendByte(addr);//发送要写入内存地址
I2cSendByte(dat); //发送数据
I2cStop();
}
unsigned char At24c02Read(unsigned char addr) :读取24c02的一个地址的一个数据
unsigned char At24c02Read(unsigned char addr)
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0); //发送写器件地址
I2cSendByte(addr); //发送要读取的地址
I2cStart();
I2cSendByte(0xa1); //发送读器件地址
num=I2cReadByte(); //读取数据
I2cStop();
return num;
}
多文件工程 头文件
#ifndef __I2C_H_
#define __I2C_H_
#include sbit SCL=P2^1; sbit SDA=P2^0; void I2cStart(); void I2cStop(); unsigned char I2cSendByte(unsigned char dat); unsigned char I2cReadByte(); void At24c02Write(unsigned char addr,unsigned char dat); unsigned char At24c02Read(unsigned char addr); #endif
上一篇:51单片机实验18:蜂鸣器
史海拾趣
|
本帖最后由 paulhyde 于 2014-9-15 02:54 编辑 包括测试程序,原理图,是买的一块开发板上给的。 [ 本帖最后由 chbaaic 于 2008-10-30 11:52 编辑 ] … 查看全部问答> |
|
百利通公司总部设在硅谷,是Nasdaq上市公司,在晶体振荡器领域位居世界前十大。百利通公司在香港和美国都设有研发中心,拥有一批经验丰富的专业设计人员。随着产品线的扩充和区域市场的成熟,先后在台湾、香港、上海设立公司,凭借其遍布全球的销售 ...… 查看全部问答> |
|
采用生物识别技术的门禁系统在安防行业应用已经越来越多,包括银行、监狱、部队等单位已经采用生物识别的门禁系统来加强其管理的安全性和使用的方便性。由于生物识别技术已经开始达到大规模的应用水平,包括产品价格、品质和技术都已经相对成熟 ...… 查看全部问答> |
|
大家好: 请教大家一个问题: 在微软window mobile 的windows media player下的右软键菜单下添加一个菜单项,该怎么添加? 微软是否提供相应的接口? 有谁知道 ...… 查看全部问答> |
|
程序大概这样的,一个试图列表里显示了CF卡中所有的文件,鼠标焦点可以放在文件上,但现在想做一个选取功能,就是,当鼠标单击了一个文件就能直接或按另一个按钮读出他的名字,这样好去CF卡中查找这个文件并对这个文件操作。问题是,怎么读出文件的 ...… 查看全部问答> |
|
公司名称: Carrier Access 公司网址: http://www.carrieraccess.com 电子邮箱: lshi@carrieraccess.com,简历请注明信息出处 工作地点: 上海 外语要求: 英文良好 简历接收方式: 英文及中文 学历: 本科以上 职位描述: -Candidates will ha ...… 查看全部问答> |
|
void FloatToByte(float floatNum,unsigned char* byteArry){ char* pchar=(char*)&floatNum; for(int i=0;i<sizeof(float);i++) { &nb ...… 查看全部问答> |




