51单片机I2C总线驱动程序

合集下载

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

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字节读写驱动程序

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的驱动程序

I2C总线8位远程IO扩展口芯片PCF8574的驱动程序

//...‎.....‎.....‎.....‎.....‎.....‎.....‎.....‎//名称‎: PCF‎8574(‎A).c ‎I2C扩展‎8位I/O‎芯片的接口‎程序//‎编程: 不‎详//日‎期: 20‎11102‎5//‎//发现‎问题请指点‎,谢谢!‎//...‎.....‎.....‎.....‎.....‎.....‎.....‎.....‎//CP‎U: 89‎C55 1‎1.059‎2MHz‎//环境:‎Keil‎C51 ‎V8.01‎//引脚‎定义:/‎/CPU‎_P2.0‎--- ‎P CF85‎74X_S‎C L 时钟‎// C‎P U_P2‎.1 --‎-PCF‎8574X‎_SDA ‎数据//‎CPU_‎P2.2 ‎--- P‎C F857‎4X_IN‎T中断‎//...‎.....‎.....‎.....‎.....‎.....‎.....‎.....‎#inc‎l ude ‎<Publ‎i c.h>‎#inc‎l ude ‎<Intr‎i ns.h‎>#in‎c lude‎"del‎a y_s.‎h"#i‎n clud‎e "pc‎f8574‎.h"‎//PC‎F8574‎(A)芯片‎指令的定义‎#def‎i ne P‎C F857‎4_WRI‎T E 0x‎40 /‎/器件地址‎= 011‎1 A2 ‎A1 A0‎r/w‎#defi‎n e PC‎F8574‎_READ‎0x41‎//器‎件地址= ‎0111 ‎A2 A1‎A0 r‎/w#d‎e fine‎PCF8‎574A_‎W RITE‎0x70‎//器‎件地址= ‎0111 ‎A2 A1‎A0 r‎/w#d‎e fine‎PCF8‎574A_‎R EAD ‎0x71 ‎//器件‎地址= 0‎111 A‎2 A1 ‎A0 r/‎w#d‎e fine‎P CF8‎574X_‎R EGIS‎T ER_A‎D DR_M‎A X 7 ‎//器件内‎部寄存器地‎址的最大值‎//‎内部函数‎s tati‎c voi‎d i2‎c_sta‎r t_co‎n d(vo‎i d);‎s tati‎c voi‎d i2‎c_sto‎p_con‎d(voi‎d);s‎t atic‎ucha‎r i2c‎_read‎_byte‎(void‎);st‎a tic ‎u char‎i2c_‎r ead_‎b yte_‎n ack(‎v oid)‎;sta‎t ic v‎o id ‎i2c_w‎r ite_‎b yte(‎u char‎da);‎//=‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎= ====‎=====‎=====‎=//接‎口调用函数‎部分//‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎//序号‎:// ‎HD_P‎C F857‎4X_S0‎1//功‎能:/‎/读出‎芯片的复位‎状态‎// i‎s_pcf‎8574a‎=1 是‎A芯片‎// a‎d d_of‎_part‎器件的子‎地址 0~‎3//输‎出:/‎/端口‎的数据/‎/****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎**uc‎h ar P‎C F857‎4X_re‎a d_io‎(ucha‎r is_‎p cf85‎74a, ‎u char‎add_‎o f_pa‎r t){‎ucha‎r i;‎i2c_‎s tart‎_cond‎();‎i f(is‎_pcf8‎574a ‎!=0)‎{‎i2c_w‎r ite_‎b yte(‎P CF85‎74A_R‎E AD |‎((add‎_of_p‎a rt <‎<1) &‎0x0E)‎);//器‎件地址=0‎111 A‎2 A1 ‎A0 r/‎w}‎else‎{‎i2c‎_writ‎e_byt‎e(PCF‎8574_‎R EAD ‎|((ad‎d_of_‎p art ‎<<1) ‎&0x0E‎));//‎器件地址=‎0100 ‎A2 A1‎A0 r‎/w}‎i =‎i2c_r‎e ad_b‎y te_n‎a ck()‎;/‎/顺序读的‎方式读出一‎个字节‎i2c_s‎t op_c‎o nd()‎;re‎t urn(‎i);}‎//*‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎****‎//序号:‎// ‎H D_PC‎F8574‎X_S02‎//功能‎://‎写数据‎到I/O端‎口//输‎入:/‎/is‎_pcf8‎574a ‎=1 是A‎芯片/‎/ad‎d_of_‎p art:‎器件的‎子地址 0‎~7//‎dat‎:写入‎的字节/‎/输出: ‎// ‎无//*‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎void‎PCF8‎574X_‎w rite‎_io(u‎c har ‎i s_pc‎f8574‎a, uc‎h ar a‎d d_of‎_part‎, uch‎a r da‎t){‎i2c_‎s tart‎_cond‎();‎i f(is‎_pcf8‎574a ‎!=0)‎{‎i2c_w‎r ite_‎b yte(‎P CF85‎74A_W‎R ITE ‎|((ad‎d_of_‎p art ‎<<1) ‎&0x0E‎)); /‎/器件地址‎=0111‎A2 A‎1 A0 ‎r/we‎l se‎{i‎2c_wr‎i te_b‎y te(P‎C F857‎4_WRI‎T E |(‎(add_‎o f_pa‎r t <<‎1) &0‎x0E))‎;//器‎件地址=0‎100 A‎2 A1 ‎A0 r/‎w}‎i2c‎_writ‎e_byt‎e(dat‎);‎i2c_s‎t op_c‎o nd()‎;}‎//===‎=====‎=====‎=//内‎部调用函数‎部分//‎=====‎=====‎====‎//--‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎----‎//I2C‎发启始条‎件:时钟线‎为高时数据‎线发生下降‎沿跳变/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎--st‎a tic ‎v oid ‎i2c_s‎t art_‎c ond(‎v oid)‎{C‎O DE_S‎C L_LO‎W;_‎D ELAY‎_NOP3‎;CO‎D E_SD‎A_HIG‎H;_‎D ELAY‎_NOP3‎;CO‎D E_SC‎L_HIG‎H;_‎D ELAY‎_NOP3‎;CO‎D E_SD‎A_LOW‎;_D‎E LAY_‎N OP3;‎}/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-//I‎2C 发结‎束条件:时‎钟线为高时‎数据线发生‎上升沿跳变‎//--‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎---s‎t atic‎void‎i2c_‎s top_‎c ond(‎v oid)‎{C‎O DE_S‎C L_LO‎W;_‎D ELAY‎_NOP3‎;CO‎D E_SD‎A_LOW‎;_D‎E LAY_‎N OP3;‎COD‎E_SCL‎_HIGH‎;_D‎E LAY_‎N OP3;‎COD‎E_SDA‎_HIGH‎;_D‎E LAY_‎N OP3;‎}/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-// ‎I2C 读‎取一个中间‎字节的数据‎//--‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎---/‎*sta‎t ic u‎c har ‎i2c_r‎e ad_b‎y te(v‎o id)‎{uc‎h ar i‎;uc‎h ar d‎a=0;‎for(‎i =0;‎i<8;‎i++)‎{‎da <‎<=1; ‎//传输‎的数据高位‎在前‎C ODE_‎S CL_L‎O W;‎_DEL‎A Y_NO‎P3;‎CODE‎_SCL_‎H IGH;‎//时‎钟为高时读‎数据‎//‎N OP3;‎if‎(JUD‎G E_PC‎F8574‎X_SDA‎) da+‎+;}‎COD‎E_SCL‎_LOW;‎_DE‎L AY_N‎O P3;‎CODE‎_SDA_‎L OW; ‎//发‎送应答位‎_DEL‎A Y_NO‎P3;‎C ODE_‎S CL_H‎I GH;‎_DEL‎A Y_NO‎P3;‎C ODE_‎S CL_L‎O W;‎_DELA‎Y_NOP‎3;C‎O DE_S‎D A_HI‎G H;‎r etur‎n(da)‎;}*‎///-‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎----‎// I2‎C读取一‎个结尾字节‎的数据/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-sta‎t ic u‎c har ‎i2c_r‎e ad_b‎y te_n‎a ck(v‎o id)‎{uc‎h ar i‎;uc‎h ar d‎a =0;‎for‎(i =‎0; i<‎8; i+‎+){‎da‎<<=1‎;C‎O DE_S‎C L_LO‎W;‎_DELA‎Y_NOP‎3;‎C ODE_‎S CL_H‎I GH;‎‎//NOP‎3;‎i f(JU‎D GE_P‎C F857‎4X_SD‎A) da‎++;‎}CO‎D E_SC‎L_LOW‎;_D‎E LAY_‎N OP3;‎COD‎E_SDA‎_HIGH‎;_D‎E LAY_‎N OP3;‎COD‎E_SCL‎_HIGH‎;_D‎E LAY_‎N OP3;‎COD‎E_SCL‎_LOW;‎ret‎u rn( ‎d a );‎}/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-// ‎I2C 写‎入一个字节‎的数据/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-sta‎t ic v‎o id i‎2c_wr‎i te_b‎y te(u‎c har ‎d a )‎{uc‎h ar i‎;fo‎r(i =‎0; i<‎8; i+‎+){‎CO‎D E_SC‎L_LOW‎;i‎f(da&‎0x80)‎{‎CO‎D E_SD‎A_HIG‎H;‎}e‎l se‎{‎CODE‎_SDA_‎L OW;‎}‎CODE‎_SCL_‎H IGH;‎da‎<<=1‎;}‎CODE‎_SCL_‎L OW; ‎//第8‎个SCL下‎降沿,写入‎8位数据‎_DEL‎A Y_NO‎P3;‎C ODE_‎S DA_H‎I GH;‎_DEL‎A Y_NO‎P3;‎C ODE_‎S CL_H‎I GH;‎}//‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎== ===‎=====‎=====‎==/‎/End ‎O f Fi‎l e‎‎。

C51实现I2C总线单主多从通信

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】

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总线入门(很详细,很经典)

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实现.

软件模拟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总线读写程序通用

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总线。

8051模拟i2C总线24c02读写源代码C语言

8051模拟i2C总线24c02读写源代码C语言
I2C_Start();
WriteI2CByte(0xa0);
acktemp=Check_Acknowledge();
WriteI2CByte(addr);/*address*/
acktemp=Check_Acknowledge();
I2C_Start();
WriteI2CByte(addr);/*address*/
acktemp=Check_Acknowledge();
WriteI2CByte(thedata);/*thedata*/
acktemp=Check_Acknowledge();
I2C_Stop();
实例1
/* 51系列单片机在使用时,有时需要模拟I2C总线_nbsp; */
/* 这里举出一个实例(读写串行EEPROM芯片at24C02_nbsp; */
/************************************************************************/
Write_A_Page(myarray2,0x18);
mybyte=Read_One_Byte(0x20);
Read_N_Bytes(rdarray,16,0x10);
}
实例2
/********************************** I2C总线驱动 *************************************
}
void SEND_1(void)
{
/*发逿,在SCL为高电平时使SDA信号为高*/
SDA=1;
SCL=1;
DELAY(DELAY_TIME);

单片机课程设设计--------单总线和I2C总线结合实现数.

单片机课程设设计--------单总线和I2C总线结合实现数.

单片机课程设计题目 :单总线和 I2C 总线结合实现数字温度计实验班级:设计者:指导教师 :单总线和 I2C 总线结合实现数字温度计实验一、实验目的通过本实验 ,理解掌握单总线器件和 I2C 总线器件的应用 ,熟悉串行总线的操作技巧。

二、实验设备及器件IBM PC 机一台DP-51PROC 单片机综合仿真实验仪一台三、实验内容1. 编写程序 ,通过单片机的 P3.3 口控制一个 DS18B20 完成数字温度的采集 ,然后用程序处理采集到的数据结果。

2. 编写程序 ,通过 I2C 总线器件 ZLG7290 实现温度数据的输出显示。

3. 结合以上两部分程序 ,编程实现数字式温度计的程序设计。

四、实验要求熟练掌握单总线方式器件的应用,熟悉I2C总线协议,学习I2C器件的使用方法。

五、实验过程和步骤(一、新建工程文件1、点击工具栏 Project 选项,在下拉菜单中选择 New Project 命令 ,弹出项目文件保存对话框 ,输入项目名后 ,点击保存按钮。

2、在工程建立完毕以后,uVision 会弹出器件选择窗口,选择相应的器件型号。

如想修改 ,可点击工具栏 Project 选项,在下拉菜单中选择 Select Device forTarget …Target ?命令。

3、点击工具栏 File 选项,选中 New 命令,新建文件 ,输入源程序。

4、把文件保存到磁盘中,如用汇编语言编写程序用.asm为扩展名,如用C语言编写程序用 .c 为扩展名。

5、添加该文件到工程中 ,在 Projectwindos 窗口内 ,选中 Source Group1 然后点击鼠标右键 ,选择 Add files to Group “Source Group1 ”,选择刚才创建的源程序文件 ,单击 Add 按钮。

(二、程序文件的编译、链接1. 安装B4区JP12接口上的短路帽,将B4区的DQ 与A2区INT1(P3.3相连。

2. 安装 D5 区 JP1 接口上的短路帽 ,将 D5 区的 SDA、 SCL 分别与 A2 区的 P17、P16 相连。

IIC串口(精)

IIC串口(精)

②在总线上挂接的I2C接口器件,有标志本器件类别的器件类型码(内臵4bit)和器件片选地址(引脚设定,P196)。

③在单主控器的IIC总线中,无论发送还是接收,SCL均由主控方提供,单向,由主控器传送给从器件;而SDA是双向的。

挂接在总线上的集成电路总数仅受总线总电容≤400pF的限制。

⑤I2C总线协议支持三种工作模式:标准S(100Kbit/s)、快速F(400Kbit/s)、高速Hs(3.4Mbit/s)。

我们这一讲从以下三个方面来初步认识I2C总线协议,并以具有I2C接口的EEPROM存储器芯片24CWxx的应用为例来具体理解和认识基于IIC总线的系统扩展。

⒈ I2C接口的电原理结构:①凡具有I2C接口的器件,其内部双向口线均为漏极(或集电极)开路输出电路/带缓冲的输入电路。

所有器件,包括主控器的输出口线均以“线与方式”挂接在I2C 总线上,总线上有上拉电阻(5~10kΩ)。

双向口线和“线与”方式,便于总线双向数据传输和控制权转移。

某器件要在SDA线上输出1,或要放弃对SDA线的控制,均应向SDA线输出1。

②在具有I2C总线接口的器件内,均有实现I2C通信协议的控制逻辑;51单片机基本型89C51没有这种控制逻辑,但可以用编程方式来模拟这种控制逻辑;51系列中的8XC550/552/752等增强性机种内就预构了具备I2C控制逻辑的I2C通信模块。

⒉信息结构:①I2C串行通信基于“位传输”,即通信传输中的底层单位是“位”。

但“位”不独立存在,必须由多个“位”组成一定格式的“基本单位”,并以这个基本单位进行I2C通信。

所谓“基本单位”与异步串行通信中的“帧”相当(不完全相同),我们就借用“帧”这个概念了。

通信中,主从双方有序组织多个“帧”进行“交互式通信”,以完成信息传送。

②“帧”组成格式:由8bit数据位(高位在前,低位在后)、应答位ACK(或非应答位NACK)构成,根据通信开始或结束的需要,在“帧”的前后拼装开始信号S或停止信号P。

51单片机程序

51单片机程序

(一)A/D的应用//拧动电位器,会在数码管的前三位显示0-255之间的数值。

这就是把模拟电压转换成数字信号。

//有些拧动电位器后数码管数可能不会动态变化,请用户按下实验板上的S22复位按键可更新数据//这种显象产生的原因是和AD芯片自身的一些特性有关。

#include<reg51.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit adrd=P3^7; //IO口定义sbit adwr=P3^6;sbit diola=P2^5;sbit dula=P2^6;sbit wela=P2^7;unsigned char j,k,adval;void delay(unsigned char i) //延时程序{for(j=i;j>0;j--)for(k=125;k>0;k--);}uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, //数码管编码0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void display(uchar bai_c,uchar sh_c,uchar g_c) //显示程序{P0=table[bai_c]; //显示百位dula=1;dula=0;P0=0xfe;wela=1;wela=0;delay(5);dula=0;P0=table[sh_c]; //显示十位dula=1;dula=0;wela=0;P0=0xfd;wela=1;wela=0;delay(5);P0=table[g_c]; //显示个位dula=1;dula=0;P0=0xfb;wela=1;wela=0;delay(5);}void main() // 主程序{uchar a,A1,A2,A2t,A3;while(1){wela=1;P0=0; //选通ADCSadwr=0; //AD写入(随便写个什么都行,主要是为了启动AD转换)_nop_();adwr=1;P0=0xff; //关闭ADCSdelay(10);wela=0; //关闭有AD片选信号锁存器的锁存端以防止在操作数码管时使AD的片选发生变化for(a=20;a>0;a--) //需要注意的是ADC0804在写和读之间的时间间隔要足够长否则无法读出数据{ //这里把显示部分放这里的原因也是为了增加写读之间的时间间隔display(A1,A2,A3);} //送去显示各位。

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码STC 51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码原文:(改自周立功软件包)#include <reg51.h>#include <intrins.h>#define uchar unsigned char /*宏定义*/#define uint unsigned intextern void Delay1us(unsigned char );sbit SDA=P1^6; /*模拟I2C数据传送位*/sbit SCL=P1^7; /*模拟I2C时钟控制位*/bit ack; /*应答标志位*//************************************************************** *****起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.*************************************************************** *****/void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/Delay1us(1);SCL=1;Delay1us(5); /*起始条件建立时间大于4.7us,延时*/SDA=0; /*发送起始信号*/Delay1us(5); /* 起始条件锁定时间大于4μs*/SCL=0; /*钳住I2C总线,准备发送或接收数据 */Delay1us(2);}/************************************************************** *****结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.*************************************************************** *****/void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/Delay1us(1); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4us*/Delay1us(5);SDA=1; /*发送I2C总线结束信号*/Delay1us(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(uchar c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

51单片机i2c读写程序的详细讲解

51单片机i2c读写程序的详细讲解

51单片机i2c读写程序的详细讲解下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。

文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!《51单片机i2c读写程序的详细讲解》一、概述51单片机是一种常用的单片机,在很多应用中使用的最多的是i2c接口,那么如何在51单片机上进行i2c的读写操作呢?下面将详细讲解i2c读写操作的程序设计过程。

模拟I_2C总线实现AVR与MCS_51单片机通讯

模拟I_2C总线实现AVR与MCS_51单片机通讯
2 I C; M CS- 51; AVR; 总线
中图分类号 : TN 913 文献标识码 : A 文3
Simu la ting th e I2 C to Realize AVR and the M CS- 51 Comm unication GAN H u i (T echnical Institute of YiChun University, YiChun J iangX i 336000, China ) Abstrac : t T he I C has the connection si m ply , the easy tooperate , T his techno logy obta ined the w idespread app lication in the industry
第 30 卷
2 uchar rdbyt ( ) /* 从 I C 总线上读 取 1 个数据字节 * /
{ ucha r nn= 0x f,f mm = 0x80 , uu= 0x7 ; f uchar ; j for ( j= 0; SDA = 1; nn= else nn= } re turn ( nn); } ( nn | mm ); nn= cro l ( nn, 1) ; SCL = 0;
2 2 2 2 2 2 2
( 或接收器 ), 这取决 于它所 要完成 的功能。 CPU 发出 的控 制信号分为 地址码 和控 制量两 部分 , 地 址码 用来选 址 , 即 接通需要控 制的电 路 , 确定 控制 的种类 ; 控制量 决定 该调 整的类别及 需要调 整的 量。这样 , 各 控制 电路虽 然挂 在同 一条总线上 , 却彼此独立 , 互不相关。 I2 C 总线在传 送数据 过程中共有三种 类型 信 号 , 它们 分别 是 : 起 始 信号、 结束 信号和应答信 号。起始 信 号 : 电平时 , SCL 为高 电平 时 , SDA 由高 SCL 为低 电平向低电平跳 变 , 开 始 传送 数据。 结束 信 号 :

i2c总线(pfc8563)驱动子法度模范集[精华]

i2c总线(pfc8563)驱动子法度模范集[精华]

I2C总线(PFC8563)驱动子程序集;I2C总线说明:;I2_SDA =1时,即总线空闲;I2_SDA =0时,即总线忙,即正在使用; 本程序集在I2_SDA =0时,使I2_SCL=0,;此时即可改变I2_SDA 的数据,或接受I2_SDA 数据的改变;I2_SCL=0时,数据是可以改变的;I2_SCL=1时,数据的改变视为控制信号,如0到1则为停止控制;如1到0则为启动控制;========================================================== =;I2C总线(PFC8563)驱动子程序集I2_SCL EQU P2.6I2_SDA EQU P2.7I2ADDRW EQU 0A2HI2ADDRR EQU 0A3HI2TIMER EQU 02HI2TIMERN EQU 07HORG 0000HJMP MAINORG 0030HMAIN:MOV SP,#80HMOV R0,#20HCALL I2_WRTIME ;写时间初始值ED:MOV R0,#28H ;此处断点,不停执行,观测CALL I2_RDTIME ;读时间值JMP ED;================================================== 开始I2CU总线子程序I2_START: SETB I2_SDANOPSETB I2_SCLNOP ;建立起始条件的时间大于4.7usNOPNOPNOPNOPCLR I2_SDA ;起始条件NOPNOPNOPNOPNOPCLR I2_SCL ;钳隹总线NOPRET;===================================================结束I2CU总线子程序I2_STOP: CLR I2_SDANOPSETB I2_SCL ;结束总线时间大于4usNOPNOPNOPNOPNOPSETB I2_SDA ;结束总线NOPNOPNOPNOPRET;=============================================发送应答信号子程序:即发送0I2_SDACK: CLR I2_SDANOPNOPSETB I2_SCLNOPNOPNOPNOPNOPCLR I2_SCLSETB I2_SDANOPNOPRET;===========================================发送非应答信号子程序,即发送1I2_SDNACK: SETB I2_SDANOPNOPSETB I2_SCLNOPNOPNOPNOPNOPCLR I2_SCLCLR I2_SDANOPNOPRET;==================================================== ;检查应答子程序,即读应答信号:若读出结果为0;证明有应答,即总线上有器件响应,否则可能无器件或器件坏;出口参数:;FO=O有应答I2_CHKACK: SETB I2_SDANOPNOPSETB I2_SCLNOPNOPNOPNOPCLR F0MOV C, I2_SDAJNC CENDSETB F0CEND: CLR I2_SCLRET;=============================================发送字节子程序;入口参数;A: 被发送数;占用资源:;R2;说明:每写一字节要调用一次I2_CHKACK取应答位I2_WRBYTE: MOV R2, #08HI2_WRBYTELP1: RLC AMOV I2_SDA, CNOPSETB I2_SCLNOPNOPNOPNOPNOPCLR I2_SCLDJNZ R2, I2_WRBYTELP1NOPNOPRET;==================================================读取字节子程序;出口参数:;A: 读出的数;占用资源;R2;说明: 每读取一字节要发送一应答/非应答位I2_RDBYTE: MOV R2, #08HI2_RDLP: SETB I2_SDANOPSETB I2_SCLNOPNOPMOV C, I2_SDANOPCLR I2_SCLRLC ANOPNOPNOPNOPDJNZ R2, I2_RDLPRET;===================================BCD码转二进制子程序;入口参数:;A: BCD码;出口参数;A: 二进制数;占用资源: A R2 R3BCD2BIN: MOV R3, AANL A, #0F0HRR AMOV R2, ARR ARR AADD A, R2MOV R2, AMOV A, R3ANL A, #0FHADD A, R2RET;========================================写8563万年历子程序;入口参数:;R0: 参数区首址: 参数区格式(秒分钟小时日星期月年,BCD码表示);占用资源:;A;R0;R2;R3I2_WRTIME:CALL I2_START ;发送起始条件MOV A, #I2ADDRWCALL I2_WRBYTE ;发送8563地址 CALL I2_CHKACK ;检查应答JB F0,I2_WRTIMEMOV A, #I2TIMER ;发送8563时间寄存器地址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_WRTIMEMOV R3, #I2TIMERNI2_WRTIMELP1:MOV A, @R0CALL I2_WRBYTE ;向8563写时间CALL I2_CHKACKJB F0,I2_WRTIMEINC R0DJNZ R3, I2_WRTIMELP1CALL I2_STOP ;发送停止条件 RET;===================================读8563万年历子程序;入口参数:;R0: 参数区首址(格式同上);出口参数:参数区存放万年历数据(二进制);占用资源:;A;R0;R2;R3I2_RDTIME:CALL I2_START ;发送起始条件MOV A, #I2ADDRW ;发送8563写地址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_RDTIMEMOV A, #I2TIMER ;发送8563时间寄存器首址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_RDTIMECALL I2_START ;发送起始条件MOV A, #I2ADDRR ;发送8563读地址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_RDTIMEMOV R3, #I2TIMERN-1I2_RDTIMELP1:CALL I2_RDBYTE ;读取8563万年历数据MOV @R0, ACALL I2_SDACK ;发送应答信号INC R0DJNZ R3, I2_RDTIMELP1CALL I2_RDBYTE ;读取8563万年历年数据MOV @R0, ACALL I2_SDNACK ;发送非应答信号 CALL I2_STOP ;发送停止条件 RET;等长一点: acc = 0 时,为 errorI2_CHKACK:SETB I2_SDANOPNOPSETB I2_SCLCLR F0MOV A, #20I2_CHKACK_L1:JNB I2_SDA, I2_CHKACK_L2DJNZ ACC, I2_CHKACK_L1SETB F0I2_CHKACK_L2:CLR I2_SCLRETEND。

51单片机模拟I2C总线的C语言实现

51单片机模拟I2C总线的C语言实现

51单⽚机模拟I2C总线的C语⾔实现I2C(Inter-Integrated Circuit)总线是⼀种由PHILIPS公司开发的两线式串⾏总线,⽤于连接微控制器及其外围设备。

I2C总线产⽣于在80年代,最初为⾳频和视频设备开发,如今主要在服务器管理中使⽤,其中包括单个组件状态的通信。

例如管理员可对各个组件进⾏查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇。

可随时监控内存、硬盘、⽹络、系统温度等多个参数,增加了系统的安全性,⽅便了管理。

⼀、I2C总线特点 I2C总线最主要的优点是其简单性和有效性。

由于接⼝直接在组件之上,因此I2C总线占⽤的空间⾮常⼩,减少了电路板的空间和芯⽚管脚的数量,降低了互联成本。

总线的长度可⾼达25英尺,并且能够以10Kbps的最⼤传输速率⽀持40个组件。

I2C总线的另⼀个优点是,它⽀持多主控 (multimastering), 其中任何能够进⾏发送和接收的设备都可以成为主总线。

⼀个主控能够控制信号的传输和时钟频率。

当然,在任何时间点上只能有⼀个主控。

⼆、I2C总线⼯作原理2.1、总线的构成及信号类型I2C 总线是⼀种串⾏数据总线,只有⼆根信号线,⼀根是双向的数据线SDA,另⼀根是时钟线SCL。

在CPU与被控IC之间、IC与IC之间进⾏双向传送,最⾼传送速率100kbps。

各种被控制电路均并联在这条总线上,但就像电话机⼀样只有拨通各⾃的号码才能⼯作,所以每个电路和模块都有唯⼀的地址,在信息的传输过程中,I2C总线上并接的每⼀模块电路既是主控器(或被控器),⼜是发送器(或接收器),这取决于它所要完成的功能。

CPU发出的控制信号分为地址码和控制量两部分,地址码⽤来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对⽐度、亮度等)及需要调整的量。

这样,各控制电路虽然挂在同⼀条总线上,却彼此独⽴,互不相关。

2.2、位的传输SDA 线上的数据必须在时钟的⾼电平周期保持稳定数据线的⾼或低电平状态只有在SCL 线的时钟信号是低电平时才能改变。

C51单片机10(I2C总线)

C51单片机10(I2C总线)

启动I2C总线
void start(void) { sda = 1; flash(); scl = 1; flash(); sda = 0; //在SCL高电平期间,SDA下降沿启动I2C总线 flash(); scl = 0; flash(); }
停止I2C总线
void stop() { sda = 0; flash(); scl = 1; flash(); sda = 1; //在SCL高电平期间,SDA上升沿停止I2C总线 flash(); }
CAT24WCXX系列E2PROM框图
CAT24WCXX系列E2PROM写入方式
• 字节写入 • 页写入——在一个写周期内编程写入一页
型号 CAT24WC01 CAT24WC02 CAT24WC04 CAT24WC08 CAT24WC16
容量(Kb) 1 2 4 8 16
类型码 1010 1010 1010 1010 1010
//把最高位移入CY //SCL低电平期间才允许SDA数据变化 //把CY送上SDA
uchar readx(void) { uchar i, j, k = 0; scl = 0; flash(); sda = 1; for(i=0; i<8; i++) { flash(); scl = 1; flash(); if(sda == 1) { j = 1; } else j = 0; k = (k << 1) | j; scl = 0; } flash(); return(k); }
4. 主器件发送“停止”信号,从器件启动内部写周期,
将数据写到数据区
I2C总线信息传送时序——页写
1. 2. 3. 4. 5. 6. 主器件发送“开始”信号和从器件地址,等待从器件送 回应答信号 主器件收到应答信号后,再发送器件内单元地址,写入 从器件,等待从器件送回应答信号 主器件收到应答信号后,发送1字节数据,写入从器件 指定存储单元,等待从器件送回应答信号 主器件收到应答信号后,再发送1字节数据,写入从器 件内部地址修正的后续存储单元 ……持续上述过程 一页写完后,主器件发送“停止”信号,从器件启动内 部写周期,将数据写到数据区(页长度见后续内容)

51单片机I2C通信程序

51单片机I2C通信程序

51单片机I2C通信程序#include#include#define ACK 0#define NOACK 1#define OUTPUT 1#define INPUT 0#define WRITE 0#define READ 1#define TRIALS 100#define ERR_CRC 2#define ERR_BUSY 1#define ERR_OK 0#define uchar unsigned char#define uint unsigned int#define uchar unsigned char#define uint unsigned intuchar EI2C1_SendChar(uchar DevAdr,uchar MemAdr,uchar Chr);uchar EI2C1_RecvChar(uchar DevAdr, uchar *Chr);uchar ReceiveRand(uchar DevAdr, uchar MemAdr, uchar* Chr);uchar PageWrite(uchar DevAdr, uchar MemAdr, uchar* Chr, uchar Siz); uchar SeqRead(uchar DevAdr, uchar MemAdr, uchar* ReceivedChr,uchar Siz);static void Delay(void);static void Write(uchar Data);static uchar Read(void);static bit GetAck(void); static void SetAck(bit Ack); static void start(void); static void stop(void);sbit SDA = P2^5;sbit SCL = P3^6;static void Delay(void){_nop_();_nop_();_nop_();}static void Write(uchar Data) {uchar Shift;uchar I;uchar timeout;Shift = 128;for (I = 8; I != 0; I--) {if (Data & Shift) {SDA = 1;}else {SDA = 0;}Shift >>= 1;SCL = 1;Delay();timeout = 255;while((SCL == 0)&&(timeout!=0)) {timeout--;}SCL = 0;Delay();}}static uchar Read(void){uchar Shift;uchar I;uchar timeout;Shift = 0;SDA = 1;for (I = 8; I != 0; I--) {SCL = 1;Delay();timeout = 255;while((SCL==0)&&(timeout!=0)) { /* WAIT FOR CLOCK HIGH PULSE */ timeout--;}Shift <<= 1;if (SDA) {Shift++;}SCL = 0;Delay();}return Shift;}static bit GetAck(void){uint timeout;SDA = 1; /* SDA HIGH */SCL = 1; /* CLOCK HIGH PULSE */Delay();timeout = 255;while((SCL==0)&&(timeout!=0)) { /* WAIT FOR CLOCK HIGH PULSE */ timeout--;}return(SDA); /* ACKNOWLEDGE V ALUE */}static void SetAck(bit Ack){uint timeout;if (Ack) {SDA = 1; /* MASTER NOACKNOWLEDGE - SDA HIGH */}else {SDA = 0; /* MASTER ACKNOWLEDGE - SDA LOW */ }SCL = 1; /* HIGH CLOCK PULSE */Delay();timeout = 255;while((SCL ==0 )&&(timeout!=0)) { /* WAIT FOR CLOCK HIGH PULSE */ timeout--;}SCL = 0; /* LOW CLOCK PULSE */SDA = 1; /* ACKNOWLEDGE END - SDA HIGH */}static void start(void){SDA = 1; /* SDA HIGH - START SETUP*/SCL = 1; /* CLOCK HIGH PULSE */Delay(); /* CLOCK HIGH PULSE & BUS FREE TIME */ SDA = 0; /* START CONDITION */Delay(); /* START HOLD TIME */SCL = 0; /* CLOCK LOW PULSE */Delay();}static void stop(void){SDA = 0; /* STOP SETUP */SCL = 1; /* CLOCK HIGH PULSE + STOP SETUP TIME */Delay();SDA = 1; /* STOP CONDITION */}uchar EI2C1_SendChar(uchar DevAdr,uchar MemAdr,uchar Chr){uchar Trial;bit Acknowledge;Trial = TRIALS;do {start();Write((uchar)(DevAdr + WRITE));Acknowledge = GetAck();--Trial;} while (Trial && Acknowledge);if (Acknowledge) { /* WRONG ACKNOWLEDGE */SCL = 0; /* CLOCK LOW PULSE */return ERR_BUSY;}else {SCL = 0; /* CLOCK LOW PULSE */Delay();}Write(MemAdr);if (GetAck()) { /* WRONG ACKNOWLEDGE */ SCL = 0; /* CLOCK LOW PULSE */stop();return ERR_BUSY;}else {SCL = 0; /* CLOCK LOW PULSE */Delay();}Write(Chr);if (GetAck()) { /* WRONG ACKNOWLEDGE */ SCL = 0; /* CLOCK LOW PULSE */stop();return ERR_BUSY;}else {SCL = 0; /* CLOCK LOW PULSE */Delay();}stop();return ERR_OK;}uchar EI2C1_RecvChar(uchar DevAdr, uchar *Chr){uchar Trial;bit Acknowledge;Trial = TRIALS;do {start();Write((uchar)(DevAdr + READ)); //写设备地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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。

相关文档
最新文档