51单片机I2C总线驱动程序
51单片机的I2C底层驱动程序(IO口模拟)

51单片机的I2C底层驱动程序(IO口模拟)/*Title:I2C for 80C51Author:yuyouliang51单片机(本人使用STC89C52单片机,12T模式)的I2C驱动程序,使用逻辑分析仪对该协议进行分析,发现波形比较美观,SCL 的频率在70KHz左右(11.0592M晶振),低于标准的100K,可以适应大多数的I2C器件。
如果感觉速度过快或过慢,可以自行修改延时。
希望可以给读者一个参考,给读者一些帮助!*//*i2c.h文件 */#ifndef __I2C_H_#define __I2C_H_sbit SCL = P2^1;sbit SDA = P2^0;void start_i2c(); //启动I2C总线:SCL高电平期间,SDA由高变低void stop_i2c(); //停止I2C总线:SCL高电平期间,SDA由低变高void send_i2c(unsigned char c); //主机发送一个字节,先发送最高位unsigned char receive_i2c(); //主机接收一个字节,先接收最高位void master_ack(bit ack); //主机非应答信号(填参数0)或应答信号(填参数1)void slave_ack(); //等待从机应答信号#endif/* i2c.c文件 */#include#include#include#define nop() _nop_()void start_i2c() //启动I2C总线:SCL高电平期间,SDA由高变低{SDA=1;SCL=1;nop();nop();nop();nop();SDA=0;SCL=0;}void stop_i2c() //停止I2C总线,SCL高电平期间,SDA由低变高{SDA=0;SCL=1;nop();nop();nop();nop();SDA=1;}void slave_ack() //等待从机应答信号,如果从机迟迟没有应答,则结束总线。
24LC65 I2C EEPROM字节读写驱动程序

24LC65 I2C EEPROM字节读写驱动程序[龙啸九天] [786次] 01-3-24 下午07:54:15/*————————————————————〖说明〗24LC65 I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接VCC。
现缺页写、页读,和CRC校验程序。
以下程序经过50台验证,批量的效果有待考察。
为了安全起见,程序中很多NOP是冗余的,希望读者能进一步精简,但必须经过验证。
51晶振为11.0592MHz〖文件〗24LC65.c ﹫2001/03/23〖作者〗龙啸九天 c51@ <a href= target=_blank></a> 〖修改〗修改建议请到论坛公布 <a href= target=_blank></a> 〖版本〗V1.00A Build 0323—————————————————————*/#define SDA P0_0#define SCL P0_1/*----------------------------------------------------------------------------调用方式:write_8bit(uchar ch) ﹫2001/03/23函数说明:内函数,私有,用户不直接调用。
------------------------------------------------------------------------------*/write_8bit(uchar ch){uchar i=8;SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();while (i--){SDA=(bit)(ch&0x80);_nop_();_nop_();_nop_();_nop_();_nop_();ch<<=1;SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();}_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/*--------------------------------------------------------------------------------调用方式:void ACK(void) ﹫2001/03/23函数说明:内函数,私有,用户不直接调用。
I2C总线8位远程IO扩展口芯片PCF8574的驱动程序

//......................................//名称: PCF8574(A).c I2C扩展8位I/O芯片的接口程序//编程: 不详//日期: 20111025////发现问题请指点,谢谢!//......................................//CPU: 89C55 11.0592MHz//环境:KeilC51 V8.01//引脚定义://CPU_P2.0--- P CF8574X_SC L 时钟// CP U_P2.1 ---PCF8574X_SDA 数据//CPU_P2.2 --- PC F8574X_INT中断//......................................#incl ude <Publi c.h>#incl ude <Intri ns.h>#inc lude"dela y_s.h"#in clude "pcf8574.h"//PCF8574(A)芯片指令的定义#defi ne PC F8574_WRIT E 0x40 //器件地址= 0111 A2 A1 A0r/w#defin e PCF8574_READ0x41//器件地址= 0111 A2 A1A0 r/w#de finePCF8574A_W RITE0x70//器件地址= 0111 A2 A1A0 r/w#de finePCF8574A_R EAD 0x71 //器件地址= 0111 A2 A1 A0 r/w#de fineP CF8574X_R EGIST ER_AD DR_MA X 7 //器件内部寄存器地址的最大值//内部函数s tatic void i2c_star t_con d(voi d);s tatic void i2c_stop_cond(void);st aticuchar i2c_read_byte(void);sta tic u chari2c_r ead_b yte_n ack(v oid);stat ic vo id i2c_wr ite_b yte(u charda);//============================================================== ===============//接口调用函数部分//*******************************************************//序号:// HD_PC F8574X_S01//功能://读出芯片的复位状态// is_pcf8574a=1 是A芯片// ad d_of_part器件的子地址 0~3//输出://端口的数据//********************************************************uch ar PC F8574X_rea d_io(uchar is_p cf8574a, u charadd_o f_par t){uchar i;i2c_s tart_cond();i f(is_pcf8574a !=0){i2c_wr ite_b yte(P CF8574A_RE AD |((add_of_pa rt <<1) &0x0E));//器件地址=0111 A2 A1 A0 r/w}else{i2c_write_byte(PCF8574_R EAD |((add_of_p art <<1) &0x0E));//器件地址=0100 A2 A1A0 r/w}i =i2c_re ad_by te_na ck();//顺序读的方式读出一个字节i2c_st op_co nd();ret urn(i);}//*******************************************************//序号:// H D_PCF8574X_S02//功能://写数据到I/O端口//输入://is_pcf8574a =1 是A芯片//add_of_p art:器件的子地址 0~7//dat:写入的字节//输出: // 无//********************************************************voidPCF8574X_w rite_io(uc har i s_pcf8574a, uch ar ad d_of_part, ucha r dat){i2c_s tart_cond();i f(is_pcf8574a !=0){i2c_wr ite_b yte(P CF8574A_WR ITE |((add_of_p art <<1) &0x0E)); //器件地址=0111A2 A1 A0 r/wel se{i2c_wri te_by te(PC F8574_WRIT E |((add_o f_par t <<1) &0x0E));//器件地址=0100 A2 A1 A0 r/w}i2c_write_byte(dat);i2c_st op_co nd();}//==============//内部调用函数部分//==============//----------------------------------------------//I2C发启始条件:时钟线为高时数据线发生下降沿跳变//----------------------------------------------sta tic v oid i2c_st art_c ond(v oid){CO DE_SC L_LOW;_D ELAY_NOP3;COD E_SDA_HIGH;_D ELAY_NOP3;COD E_SCL_HIGH;_D ELAY_NOP3;COD E_SDA_LOW;_DE LAY_N OP3;}//----------------------------------------//I2C 发结束条件:时钟线为高时数据线发生上升沿跳变//----------------------------------------st aticvoidi2c_s top_c ond(v oid){CO DE_SC L_LOW;_D ELAY_NOP3;COD E_SDA_LOW;_DE LAY_N OP3;CODE_SCL_HIGH;_DE LAY_N OP3;CODE_SDA_HIGH;_DE LAY_N OP3;}//----------------------------------------// I2C 读取一个中间字节的数据//----------------------------------------/*stat ic uc har i2c_re ad_by te(vo id){uch ar i;uch ar da=0;for(i =0;i<8;i++){da <<=1; //传输的数据高位在前C ODE_S CL_LO W;_DELA Y_NOP3;CODE_SCL_H IGH;//时钟为高时读数据//N OP3;if(JUDG E_PCF8574X_SDA) da++;}CODE_SCL_LOW;_DEL AY_NO P3;CODE_SDA_L OW; //发送应答位_DELA Y_NOP3;C ODE_S CL_HI GH;_DELA Y_NOP3;C ODE_S CL_LO W;_DELAY_NOP3;CO DE_SD A_HIG H;r eturn(da);}*///----------------------------------------// I2C读取一个结尾字节的数据//----------------------------------------stat ic uc har i2c_re ad_by te_na ck(vo id){uch ar i;uch ar da =0;for(i =0; i<8; i++){da<<=1;CO DE_SC L_LOW;_DELAY_NOP3;C ODE_S CL_HI GH;//NOP3;i f(JUD GE_PC F8574X_SDA) da++;}COD E_SCL_LOW;_DE LAY_N OP3;CODE_SDA_HIGH;_DE LAY_N OP3;CODE_SCL_HIGH;_DE LAY_N OP3;CODE_SCL_LOW;retu rn( d a );}//----------------------------------------// I2C 写入一个字节的数据//----------------------------------------stat ic vo id i2c_wri te_by te(uc har d a ){uch ar i;for(i =0; i<8; i++){COD E_SCL_LOW;if(da&0x80){COD E_SDA_HIGH;}el se{CODE_SDA_L OW;}CODE_SCL_H IGH;da<<=1;}CODE_SCL_L OW; //第8个SCL下降沿,写入8位数据_DELA Y_NOP3;C ODE_S DA_HI GH;_DELA Y_NOP3;C ODE_S CL_HI GH;}//============================================================== ===============//End O f Fil e。
C51实现I2C总线单主多从通信

设计论文
C51 实现 I2C 单主多从通信
专业: 航空电子信息
班级:
航电 1203
姓名:
陈瑞金
指 导 老 师 : 鄢立、程秀玲
时 间:
2014.04
1
陈瑞金
________________________________________________________________________________________________________________
五、程序的编写
1、设计思路--------------------------------------------------------------12
2、参考程序
a.主机程序------------------------------------------------------------14
2、关于 24C02 的读写---------------------------------------------------7
四、硬件电路
1、Proteurs 绘制的电路图----------------------------------------------8
2、Proteurs 仿真效果图------------------------------------------------10
当主机接收数据时,它收到最后一个数据字节后,必须向从机发出一个结束传送的信号。这个信号是由对从机 的“非应答”来实现的。然后,从机释放 SDA 线,以允许主机产生终止信号。
(2)数据帧率格式 I2C 总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。在起始信号后必须传送一个
I2C总线编程实例(k1-k4:写入、读取、加+、清零)【EEPROM-AT24C02】

I2C总线编程实例(k1-k4:写⼊、读取、加+、清零)【EEPROM-AT24C02】(1)AT24C02是⼀种EEPROM元器件,是⼀种只读寄存器,断电保持,可保存数据100年, 是⼀种可擦除读写的芯⽚,相当于ROM硬盘,在下⾯实验中充当从机⾓⾊;(2)51在下⾯实验中充当主机⾓⾊;(3)在IIC总线标准协议上,进⾏51单⽚机(主机)和AT24C02(从机)的相互读写数据的操作。
⼩结:51单⽚机和各种EEPROM芯⽚之间可以通过IIC总线标准协议进⾏数据交互(通信)的。
实验:四个独⽴按键对应四个不同的功能,k1:将数据写⼊单⽚机,断电保存k2:读取上次保存的数据,断电后仍可读取上次保存的数据k3:当前数据+1k4:当前数据清零------------------------------------------------------------- 采⽤多⽂件的框架模式 -------------------------------------------------------------i2c.h:/*这个⽂件进⾏宏定义:定义I2C串⾏总线的相关数据端⼝、⽅法函数,以及定义⼀些使⽤频率较⾼的元素*/#ifndef _I2C_H_ // 如果没有定义宏#define _I2C_H_ // 定义⼀个宏// 需要⽤到51单⽚机的管脚,所以需要引⼊库⽂件#include <reg52.h>// 查单⽚机原理图可知(其中,SCL是时钟线,SDA是数据线)sbit SCL=P2^1;sbit SDA=P2^0;/* 相关函数 */// I2C的起始信号函数void I2cStart();// I2C的终⽌信号函数void I2cStop();// I2C发送(写⼊)字节函数,成功返回1,失败返回0unsigned char I2cSendByte(unsigned char dat);// I2C接收(读取)字节函数,返回读取的数据unsigned char I2cReadByte();// AT24C02芯⽚的写⼊数据函数void At24c02Write(unsigned char addr, unsigned dat);// AT24C02芯⽚的读取数据函数,返回读取的数据unsigned char At24c02Read(unsigned char addr);#endif // 结束i2c.c:/* 这个⽂件专门针对I2C模块的编程,其他模块可以新建另外⼀个⽂件 */#include <i2c.h> // 引⼊I2C的库⽂件/******************************************************************************** 函数名 : Delay10us()* 函数功能 : 延时10us* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/void Delay10us() //误差 0usunsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);}/******************************************************************************** 函数名 : I2cStart()* 函数功能 : 起始信号:在SCL时钟信号在⾼电平期间SDA信号产⽣⼀个下降沿* 输⼊ : ⽆* 输出 : ⽆* 备注 : 起始之后SDA和SCL都为0,表⽰总线被主机占⽤*******************************************************************************/void I2cStart(){// 根据各个单⽚机的时序图来写SDA=1;Delay10us();SCL=1;Delay10us(); // 建⽴时间是SDA保持时间>4.7usSDA=0;Delay10us(); // 保持时间是>4usSCL=0;Delay10us();}/******************************************************************************** 函数名 : I2cStop()* 函数功能 : 终⽌信号:在SCL时钟信号⾼电平期间SDA信号产⽣⼀个上升沿* 输⼊ : ⽆* 输出 : ⽆* 备注 : 结束之后保持SDA和SCL都为1;表⽰总线处于空闲状态*******************************************************************************/void I2cStop(){// 根据各个单⽚机的时序图来写SDA=0;Delay10us();SCL=1;Delay10us(); // 建⽴时间是SDA保持时间>4.7usSDA=1;Delay10us(); // 保持时间是>4us}/******************************************************************************** 函数名 : I2cSendByte(unsigned char dat)* 函数功能 : 通过I2C发送⼀个字节。
I2C总线入门(很详细,很经典)

I2C总线入门1)最近学习51单片机,学到A/DQ/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF859仃,看了一下它的数据手册, 发现它并不是书上所说的并行传输数据,是使用I2C总线传输的。
搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。
! ≡tt f Itiief II R J Ih PHiLlPSt j ΓC bFC 口対由⅞⅛⅞κΓt r SDA IUB L f W r■I. SeiL閃離找L#參G [⅛总蠻H件嗣时Mtfl ι⅛X⅛ttStM'QUIA ft/i CPU 1√ Kf?IC ZlHh IC J J Ie Z糾幣町遊i;I^I ILW*s4t∣ιIkh i P"⅛.BtflK硏是Jl伯的内评.iaiT IT K以上是I2C总线的简单介绍。
就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口(如下图)2)接下来看如何使用I2C总线进行通信3. I S C总线通信格式图8,i+2 ⅛ PC总统上进彳J -次数撫传输的通信格式HJ. λ5WuJΓ IMPuJT λWλ√[T+ *1⅛∕'f ⅛ff融戟代答ftK >⅛祎:J*j*hrn⅛释止他号图S.I .2 I3C总纽上遊打谀散据传输的JfflG⅛A 以上是I2C 总线通信的格式。
由上图可以看出进行通信需要以下几个步骤S-Iead PDlPAOL1 8□ VCCAl匚⅛WPA2匚3GND匚4£AJNOITU迴VDDAINlI 2ISj AOUTAIN2 3]回” RE FAIN3 I 41^I3] AGNDPCF8591PAO ^5∏^↑2∖ EXTAt叵TrlOSCA2 T/JO)SeL^kVSS叵(VJ SDAIH2引脚图(Dlla.初始化I2C总线就是把SDA和SCL都变成高电平。
Void in it() 〃初始化{SDA=1;delay();SCL=1;delay();}delay ()为延时函数void delay() 〃延时4-5个微秒{;;}b.发送起始信号就是保持SCL为高电平,而SDA从高电平降为低电平(这是I2C总线的规定, 别问我为什么)void Start()// 起始信号{SDA=1;delay();SCL=1;delay();SDA=0;delay();}C.发送地址字(芯片的硬件地址)74地址12C总线象统中的每一片PCF859J通过发送有效地址封该黠件来激活。
软件模拟I2C总线的C51实现.

软件模拟I2C总线的C51实现摘要:介绍51系列单片机上的I2C总线主节点模拟程序,从而实现与具有I2C接口的器件通信。
1I2C总线简介1.1硬件结构I2C串行总线支持所有NMOS、CMOS、I2L工艺制造的器件。
从物理上看由两根双向I/O线组成,一根为数据线(SDA),一根为时钟线(SCL),通过这两根线把所有器件连接到总线上,并通过SDA和SCL在各器件间传递信息(根据地址识别每个器件)。
SDA和SCL通过上拉电阻接正电源,总线空闲时,两根线都是高电平。
这两根I/O线在电气上允许“线与”操作,其输出的驱动形式为集电极开路或漏极开路。
根据通信速度的不同,I2C总线分为三种工作模式:标准模式、快速模式和高速模式。
它们分别对应不同的波特率:100kb/s、400kb/s和3.4Gb/s。
总线上允许的设备数以总线上的电容量不超过400pF为限。
1.2数据传输I2C总线上数据为同步传输。
挂在I2C总线上的每一个器件都有一个独立的地址,而且在传输过程中有主节点和从节点的区分,主节点的作用是启动和结束一次通信,并负责控制总线时钟,总线上可以有多个主节点或多个从节点,但是在一次通信中只能有一个节点作为主节点。
主从机之间一次数据的传输称为一帧,由启动信号、地址信息、应答位及停止位组成。
其传送格式见图1。
2MCS-51与I2C总线芯片接口及程序2.18051经I2C总线扩展存储器PCF8582对于内部没有硬件I2C总线接口的51系列单片机,可以采用软件模拟的方法实现I2C总线接口功能。
硬件连接如图2所示。
用8051的P1.6和P1.7作为I2C总线的SCL利SDA信号,在总线上连接256*8的EEPROM芯片PCF8582。
8051单片机与PCF8582进行数据传递时,首先传送器件的从机地址SLA,格式如下:START为起始信号,从机地址的固定部分是4位——1010,可编程部分由,则该片的从机地址为引脚A2、A1、A0确定。
I2C总线读写程序通用

//==========================头文件加载===============================#include <reg52.h> //加载52系列单片机头文件//===========================端口声明================================sbit CLK=P3^6; //74hc574时钟信号线sbit G=P2^4; //74hc574使能sbit IIC_SDA=P2^6; //声明IIC总线的数据线接在单片机的P2。
5端口。
sbit IIC_SCL=P2^5; //声明IIC总线的时钟线接在单片机的P2。
7端口。
unsigned char tabl[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x0BF,0x8C};//0,1,2,3,4,5,6,7,8,9,-,P//===========================函数声明================================ void display(unsigned char aa);void delay(unsigned int t);void delay_IIC(void);void IIC_Init(void);void IIC_start(void);void IIC_stop(void);bit IIC_Tack(void);void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data);unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr);void IIC_write_byte(unsigned char Data);unsigned char IIC_read_byte(void);//============================主函数================================= void main() //主函数{unsigned char Data=2,addr=0x01;//—-——-—--—————————-——--————-系统初始化——-—-—--—-—-—————-—---———-IIC_Init();//初始化IIC总线。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
51单片机I2C总线驱动程序
SI2I2C 总线是PHLIPS 公司推出的一种串行总线,是具备多主机系统所需
的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C 总线只有两根
双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
一.I2C 系统结构每个接到I2C 总线上的器件都有唯一的地址。
主机与其它器
件间的数据传送可以是由主机发送数据到其它器件,这时主机即为发送器。
由
总线上接收数据的器件则为接收器。
二.数据位的有效性规定I2C 总线进行数据传送时,时钟信号为高电平期间,
数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线
上的高电平或低电平状态才允许变化。
三.字节传送与应答每一个字节必须保证是8 位长度。
数据传送时,先传送最
高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有
9 位)。
四.驱动程序#define uchar unsigned char#define uint unsigned int#define somenop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_(),_nop_()sbit SCL=P2;sb it SDA=P2;123451.起始信号和终止信号
SCL 线为高电平期间,SDA 线由高电平向低电平的变化表示起始信号;SCL
线为高电平期间,SDA 线由低电平向高电平的变化表示终止信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用
的状态;在终止信号产生后,总线就处于空闲状态
void I2C_Start() //起始{SCL=1;somenop();SDA=1;somenop(); SDA=0;somenop();SCL=0;somenop();}void I2C_Stop() //终止{ SDA=0;somenop();SCL=1;somenop();SDA=1;somenop();}12345678910111213141。