




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一、学习目标1.掌握I2C总线协议。2.掌握AT24C02的使用方法。3.掌握读懂时序写程序的方法。。二、学习任务在日常生活中,经常要碰到人机接口,如键盘接口、触摸屏接口等。在银行柜台串口都有输入密码的小键盘,这就是一种典型的人机接口。本项目的任务是设计一电子密码锁,通过键盘设置设置密码,通过键盘可以修改密码,通过键盘输入密码,进行开锁。本项目任务分解为具体2个学习任务:任务一I2C总线的模拟;任务二电子密码锁系统实现。三、任务分解任务一I2C总线的模拟【任务描述】通过对I2C总线的模拟,实现向串行存储芯片AT24C02写入该芯片的地址,返回应答信号0,向串行存储芯片AT24C02写入一个非该芯片的地址,返回应到信号1,用LCD1602显示两种对比结果。【任务分析】学习I2C总线技术,并模拟I2C总线,以及液晶驱动技术,前面所学知识,实现电子密码锁系统的实现。【相关知识】一、I2C串行总线的组成及工作原理
I2C-BUS
I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL。I2C总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
每个接到I2C总线上的器件都有唯一的地址。主机与其它器件间的数据传送可以是由主机发送数据到其它器件,这时主机即为发送器。由总线上接收数据的器件则为接收器。
在多主机系统中,可能同时有几个主机企图启动总线传送数据。为了避免混乱,I2C总线要通过总线仲裁,以决定由哪一台主机控制总线。
数据位的有效性规定
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。 I2C总线的数据传送起始和终止信号
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。
连接到I2C总线上的器件,若具有I2C总线的硬件接口,则很容易检测到起始和终止信号。对于不具备I2C总线硬件接口的有些单片机来说,为了检测起始和终止信号,必须保证在每个时钟周期内对数据线SDA采样两次。
接收器件收到一个完整的数据字节后,有可能需要完成一些其它工作,如处理内部中断服务等,可能无法立刻接收下一个字节,这时接收器件可以将SCL线拉成低电平,从而使主机处于等待状态。直到接收器件准备好接收下一个字节时,再释放SCL线使之为高电平,从而使数据传送可以继续进行。
数据传送格式字节传送与应答
每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
IO口模拟子程序(1)起始信号voidStart_I2c(void){SDA=1;//发送起始条件的数据信号
DelayNus(2);SCL=1;DelayNus(6);//起始条件建立时间大于4.7us,延时
SDA=0;//发送起始信号
DelayNus(6);//起始条件建立时间大于4.7us,延时
SCL=0;//钳住I2C总线,准备发送或接收数据}(2)终止信号voidStop_I2c(void){SDA=0;DelayNus(2);SCL=1;DelayNus(6);//起始条件建立时间大于4.7us,延时
SDA=1;DelayNus(6);}
从机地址(SlaveAddress)I2C总线不需要额外的地址译码器和片选信号。多个具有I2C总线接口的器件都可以连接到同一条I2C总线上,它们之间通过器件地址来区分。主机是主控器件,它不需要器件地址,其它器件都属于从机,要有器件地址。必须保证同一条I2C总线上所有从机的地址都是唯一确定的,不能有重复,否则I2C总线将不能正常工作。D7~D1位组成从机的地址。D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据例:
AT24C系列E2PROM芯片地址的固定部分为1010,A2、A1、A0引脚接高、低电平后得到确定的3位编码。形成的7位编码即为该器件的地址码。子地址带有I2C总线的器件除了有从机地址(SlaveAddress)外,还可能有子地址。从机地址是指该器件在I2C总线上被主机寻址的地址,而子地址是指该器件内部不同部件或存储单元的编址。例如,带I2C总线接口的E2PROM就是拥有子地址器件的典型代表。
应答在I2C总线传输数据过程中,每传输一个字节,都要跟一个应答状态位。接收器接收数据的情况可以通过应答位来告知发送器。应答位的时钟脉冲仍由主机产生,而应答位的数据状态则遵循“谁接收谁产生”的原则,即总是由接收器产生应答位。主机向从机发送数据时,应答位由从机产生;主机从从机接收数据时,应答位由主机产生。I2C总线标准规定:应答位为0表示接收器应答(ACK),常常简记为A;为1则表示非应答(NACK),常常简记为A。发送器发送完LSB之后,应当释放SDA线(拉高SDA,输出晶体管截止),以等待接收器产生应答位基本的数据传输格式在图4和图5中,各种符号的意义为:S:起始位(START)SA:从机地址(SlaveAddress),7位从机地址W:写标志位(Write),1位写标志R:读标志位(Read),1位读标志A:应答位(Acknowledge),1位应答/A:非应答位(NotAcknowledge),1位非应答D:数据(Data),每个数据都必须是8位P:停止位(STOP)阴影:主机产生的信号无阴影:从机产生的信号重复起始条件(RepeatedSTARTcondition)主机与从机进行通信时,有时需要切换数据的收发方向(例如,访问某一具有I2C总线接口的E2PROM存储器时,主机先向存储器输入存储单元的地址信息(发送数据),然后再读取其中的存储内容(接收数据))在切换数据的传输方向时,可以不必先产生停止条件再开始下次传输,而是直接再一次产生开始条件。I2C总线在已经处于忙的状态下,再一次直接产生起始条件的情况被称为重复起始条件。重复起始条件常常简记为Sr。读/写一字节子程序voidSendByte(unsignedcharc){unsignedchari;for(i=0;i<8;i++){if((c<<i)&0x80)SDA=1;//判断发送位
elseSDA=0;DelayNus(2);SCL=1;DelayNus(6);SCL=0;DelayNus(6);}}unsignedcharRcvByte(void){unsignedchari;unsignedcharc=0;SDA=1;for(i=0;i<8;i++){SCL=0;//置时钟线为低,准备接收数据位
DelayNus(6);//时钟低电平周期大于4.7μsSCL=1;DelayNus(2);c<<=1;if(SDA){c+=1;}//读数据位,将接收的数据存c}SCL=0;returnc;}三、串行E2PROM存储器24C02初步认识串行E2PROM是在各种串行器件应用中使用较频繁的器件,和并行E2PROM相比,串行E2PROM容量小、数据传送速度较低,但因其体积较小,引脚较少,功耗低,特别适合于需要存放非挥发数据,速度要求不高,引脚少的单片机应用系统。1.引脚功能VCC:电源+5V。VSS:地线。SCL:串行时钟输入端,用于发送数据或接收数据时产生所需的时钟。SDA:串行数据I/O端,用于输入和输出串行数据。该引脚是漏极开路的端口,需接上拉电阻到VCC。WP:写保护端,该引脚提供了硬件数据保护,当WP接地时,允许对芯片执行写操作;当WP接VCC时,则对芯片实施写保护。A0、A1、A2:器件地址输入端,用于多个器件级联时设置器件地址,当这些脚悬空时默认值为0,对于24C02可级联8个器件,如果线路上只有一片24C02,这三个地址输入脚A0、A1、A2可悬空或连接到GND。例:如果A2、A1、A0所接的电平为101,由于24C02的器件标识为1010,那么,该芯片的读地址为0xab,写地址为0xaa。【任务实施】单片机向24C02发送一字节数据对应的程序代码如下:Lcd1602.c文件代码:#include<reg52.h>#include<intrins.h>#defineLCD1602_DBP0sbitLCD1602_RS=P2^0;sbitLCD1602_RW=P2^1;sbitLCD1602_E=P2^2;/*等待液晶是否忙*/bitLcd_bz()//测试忙函数,1-忙,0-不忙{bitresult;LCD1602_DB=0xFF;LCD1602_RS=0;LCD1602_RW=1;LCD1602_E=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(LCD1602_DB&0x80);//bit7等于1表示液晶正忙LCD1602_E=0;returnresult;}/*向LCD1602液晶写入一字节命令,cmd-待写入命令值*/voidLcdWriteCmd(unsignedcharcmd){while(Lcd_bz());//判断LCD是否忙碌
LCD1602_RS=0;LCD1602_RW=0;LCD1602_DB=cmd;LCD1602_E=1;LCD1602_E=0;}/*向LCD1602液晶写入一字节数据,dat-待写入数据值*/voidLcdWriteDat(unsignedchardat){while(Lcd_bz());//判断LCD是否忙碌
LCD1602_RS=1;LCD1602_RW=0;LCD1602_DB=dat;LCD1602_E=1;LCD1602_E=0;}/*设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标*/voidLcdSetCursor(unsignedcharx,unsignedchary){unsignedcharaddr;
if(y==0)//由输入的屏幕坐标计算显示RAM的地址
addr=0x00+x;//第一行字符地址从0x00起始
elseaddr=0x40+x;//第二行字符地址从0x40起始
LcdWriteCmd(addr|0x80);//设置RAM地址}/*在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针*/voidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str){LcdSetCursor(x,y);//设置起始地址
while(*str!='\0')//连续写入字符串数据,直到检测到结束符
{LcdWriteDat(*str++);}}/*初始化1602液晶*/voidInitLcd1602(){LcdWriteCmd(0x38);//16*2显示,5*7点阵,8位数据接口
LcdWriteCmd(0x0C);//显示器开,光标关闭
LcdWriteCmd(0x06);//文字不动,地址自动+1LcdWriteCmd(0x01);//清屏}main.c代码:#include<reg51.h>//包含51单片机寄存器定义的头文件#include<intrins.h>//包含_nop_()函数定义的头文件#defineucharunsignedchar#defineuintunsignedint#definedelay5us(){_nop_();_nop_();_nop_();_nop_();}sbitSDA=P3^4;//将串行数据总线SDA位定义在为P3.4引脚sbitSCL=P3^3;//将串行时钟总线SDA位定义在为P3.3引脚bitack=0;//此应答信号为单片机发送数据时,24C02作出的应到信号externvoidInitLcd1602();externvoidLcdShowStr(ucharx,uchary,uchar*str);bitI2CAddresing(ucharaddr);bitSendByte(ucharaddr);voidmain(){ ucharstring[10];InitLcd1602();//初始化液晶
ack=I2CAddresing(0xa0);//发送AT24c02的器件地址
string[0]='5'; string[1]='0'; string[2]=':'; string[3]=(unsignedchar)ack+'0'; string[4]='\0'; LcdShowStr(0,0,string); ack=I2CAddresing(0x62);//发送非AT24c02的器件地址
string[0]='6'; string[1]='2'; string[2]=':'; string[3]=(unsignedchar)ack+'0'; string[4]='\0'; LcdShowStr(8,0,string);while(1);}//开始位voidstart(){SDA=1;//SDA初始化为高电平"1"SCL=1;//开始数据传送时,要求SCL为高电平"1"delay5us();//延时5usSDA=0;//SDA的下降沿被认为是开始信号delay5us();//延时5usSCL=0;//SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)}//停止位voidstop(){SDA=0;//SDA初始化为低电平"0"_nSCL=1;//结束数据传送时,要求SCL为高电平"1"delay5us();//延时5usSDA=1;//SDA的上升沿被认为是结束信号delay5us();//延时5usSDA=0;SCL=0;}/**************************************************函数功能:发送一字节子函数***************************************************/bitSendByte(ucharc) {ucharn; for(n=0;n<8;n++)//一字节为8位,循环8次
{if(c&0x80)//先高后低,将数据线SDA置1或清0 SDA=1; else SDA=0; SCL=1;//SCL为高,通知从机开始接收数据
delay5us(); SCL=0;//SCL变低,准备发送下一位数据准备下一位要发送的数据
c=c<<1;//准备下一位要发送的数据} SDA=1; delay5us(); SCL=1;//SCL变低,准备发送下一位数据准备下一位要发送的数据
delay5us(); if(SDA==1)//该24C02产生应答了,0表示收到,1表示未收到
ack=0; else ack=1;//24C02如应答了0表示收到,为符合一般规则,将ack标志信号置为1 SCL=0; returnack; }/**************************************************函数功能:启动一次地址发送操作***************************************************/bitI2CAddresing(unsignedcharaddr){ack=0;start();ack=~SendByte(addr);//取反表示恢复at24c02实际有应答就为0,不取反实际有应答就为1stop();returnack;}【进阶提高】向AT24C02指定地址地址"0x36"中写入数据"0x0f",然后从指定地址"0x36中读取数据并送P1口显示。AT24C02发送与接收单字节数据对应的程序代码如下:#include<reg51.h>//包含51单片机寄存器定义的头文件#include<intrins.h>//包含_nop_()函数定义的头文件#defineucharunsignedchar#defineuintunsignedint#defineOP_READ0xa1//器件地址以及读取操作,0xa1即为10100001B#defineOP_WRITE0xa0//器件地址以及写入操作,0xa1即为10100000BsbitSDA=P3^4;//将串行数据总线SDA位定义在为P3.4引脚sbitSCL=P3^3;//将串行时钟总线SDA位定义在为P3.3引脚bitack_mk;//应答标志位,有应答为1,无应答为0/*****************************************************函数功能:延时5us***************************************************/voidDelay5us(){_nop_();_nop_();_nop_();_nop_();}voiddelay1ms(){unsignedchari,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}/***************************************************函数功能:开始数据传送***************************************************/voidStart()//开始位{SDA=1;//SDA初始化为高电平"1"SCL=1;//开始数据传送时,要求SCL为高电平"1"Delay5us();//延时5usSDA=0;//SDA的下降沿被认为是开始信号Delay5us();//延时5usSCL=0;//SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)}/***************************************************函数功能:结束数据传送***************************************************/voidStop()//停止位{SDA=0;//SDA初始化为低电平"0"_nSCL=1;//结束数据传送时,要求SCL为高电平"1"Delay5us();//延时5usSDA=1;//SDA的上升沿被认为是结束信号
Delay5us();//延时5usSDA=0;SCL=0;}//单片机非应答信号voidI2C_nAck(void){SCL=0; //为产生脉冲准备
SDA=1; //产生应答信号
Delay5us(); //延时你懂得
SCL=1;Delay5us(); SCL=0;Delay5us(); //产生高脉冲 }/**************************************************函数功能:发送一字节***************************************************/voidSendByte(ucharc) {ucharn; for(n=0;n<8;n++)//一字节为8位,循环8次
{if(c&0x80)//先高后低,将数据线SDA置1或清0 SDA=1; else SDA=0; SCL=1;//SCL为高,通知从机开始接收数据
Delay5us(); SCL=0;//SCL变低,准备发送下一位数据准备下一位要发送的数据
c=c<<1;//准备下一位要发送的数据} SDA=1;//一字节发送完后释放数据线
Delay5us(); SCL=1;//SCL由低变高,产生一个时钟
Delay5us(); if(SDA==1)//如果SDA=1,则发送失败。
ack_mk=0; else ack_mk=1;//如果SDA=0,则发送成功。
SCL=0;//SCL变低。
}/**************************************************函数功能:接收一字节***************************************************/
ucharRcvByte(){ ucharn,c;{for(n=0;n<8;n++)//一字节为8位,循环8次,先高后低
{SDA=1;//置数据线SDA为高,进入接收方式
SCL=1;//SCL由低变高,产生一个时钟
if(SDA==0)//根据数据线SDA的状态,将c的最高位清0或置1 c=c&0x7f; else c=c|0x80; c=_crol_(c,1);//将c循环左移一位,为接收下一位准备
SCL=0;//时钟线SCL清0 } return(c); }}/***************************************************函数功能:向AT24Cxx中的指定地址写入数据入口参数:add(储存指定的地址);dat(储存待写入的数据)***************************************************/voidWriteSet(unsignedcharadd,unsignedchardat)//在指定地址addr处写入数据WriteCurrent{Start();//开始数据传递
SendByte(OP_WRITE);//选择要操作的AT24Cxx芯片,并告知要对其写入数据
SendByte(add);//写入指定地址
SendByte(dat);//向当前地址(上面指定的地址)写入数据
Stop();//停止数据传递
delay1ms();//1个字节的写入周期为1ms,最好延时1ms以上}/***************************************************函数功能:从AT24Cxx中的指定地址读取数据入口参数:set_addr出口参数:x***************************************************/ucharReadSet(unsignedcharset_addr)//在指定地址读取{ucharData;Start();//开始数据传递
SendByte(OP_WRITE);//选择要操作的AT24Cxx芯片,并告知要对其写入数据
if(ack_mk==0)return(0);//如果没能应答,操作失败
SendByte(set_addr);//写入指定地址
if(ack_mk==0)return(0);//如果没能应答,操作失败
Start();
SendByte(OP_READ); //表示进行读操作
if(ack_mk==0)return(0);//如果没能应答,操作失败
Data=RcvByte();I2C_nAck();Stop();return(Data);//从指定地址读出数据并返回}/***************************************************函数功能:主函数***************************************************/main(void){SDA=1;//SDA=1,SCL=1,使主从设备处于空闲状态
SCL=1;WriteSet(0x36,0x0f);//在指定地址"0x36"中写入数据"0x0f"P1=ReadSet(0x36);//从指定地址"0x36中读取数据并送P1口显示
while(1);}任务二电子密码锁设计实现【任务描述】在日常的生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。若使用传统的机械式钥匙开锁,人们常需携带多把钥匙,使用极不方便,且钥匙丢失后安全性即大打折扣。在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替了传统的机械式密码锁,电子密码锁具有安全性高、成本低、功耗低、易操作等优点。电子密码锁是一种通过密码输入来控制电路或是芯片工作,从而控制机械开关的闭合,完成开锁、闭锁任务的电子产品。它的种类很多,有简易的电路产品,也有基于芯片的性价比较高的产品。现在应用较广的电子密码锁是以芯片为核心,通过编程来实现的。其性能和安全性已大大超过了机械锁。【任务分析】学习I2C总线技术,并模拟I2C总线,以及液晶驱动技术,前面所学知识,比较综合的运用。本任务先实现单片机向AT24C02发送4组数据,再将这4组数据从AT24C02取出送液晶显示,最后实现电子门密码锁系统。【相关知识】本任务要用到十六进数组用液晶的显示的问题,下面通过实例加以说明:用8-14所示电路,把数组InputData[4]={0x55,0x34,0x56,0xab};中的4个值用液晶1602给显示出来。Lcd1602.c代码请参阅任务1。main.c代码:#include<reg51.h>//包含51单片机寄存器定义的头文件#include<intrins.h>//包含_nop_()函数定义的头文件#defineucharunsignedchar#defineuintunsignedintexternvoidInitLcd1602();externvoidLcdShowStr(ucharx,uchary,uchar*str);ucharcodeInputData[4]={0x55,0x34,0x56,0xab};uchardisp1[10]={0};//转为液晶显示voidirwork(void){uchari;
disp1[0]=InputData[0]/16;disp1[1]=InputData[0]%16;disp1[2]=InputData[1]/16;disp1[3]=InputData[1]%16;disp1[4]=InputData[2]/16;disp1[5]=InputData[2]%16;disp1[6]=InputData[3]/16;disp1[7]=InputData[3]%16;disp1[8]='\0';
for(i=0;i<8;i++){ if(disp1[i]>=10)switch(disp1[i]){case10:disp1[i]='A'; break; case11:disp1[i]='B'; break; case12:disp1[i]='C'; break; case13:disp1[i]='D'; break; case14:disp1[i]='E'; break; case15:disp1[i]='F'; break;}else{ disp1[i]=disp1[i]+'0';}}}/***************************************************函数功能:主函数***************************************************/main(void){InitLcd1602();//初始化液晶
while(1){irwork();LcdShowStr(0,0,disp1);//发送的数据送液晶显示
}}【任务实施】对应的代码部分是实现单片机向AT24C02发送4组数据,再将这4组数据从AT24C02取出送液晶显示。在KeilC51中调试下面代码:lcd1602.c参阅任务1.main.c对应的代码:#include<reg51.h>//包含51单片机寄存器定义的头文件#include<intrins.h>//包含_nop_()函数定义的头文件#defineucharunsignedchar#defineuintunsignedintsbitSDA=P3^4;//将串行数据总线SDA位定义在为P3.4引脚sbitSCL=P3^3;//将串行时钟总线SDA位定义在为P3.3引脚externvoidInitLcd1602();externvoidLcdShowStr(ucharx,uchary,uchar*str);unsignedcharDisp1[10];unsignedcharDisp2[10];unsignedcharDisp3[8]={0,0,1,1,2,2,3,3};ucharcodeInputData[4]={0x55,0x34,0x56,0xab};ucharOutputData[4]={0};bitack_mk;//应答标志位,有应答为1,无应答为0/*****************************************************函数功能:延时5us***************************************************/voidDelay5us(){_nop_();_nop_();_nop_();_nop_();}voidDelayMS(uintValMS){ uintuiVal,ujVal; for(uiVal=0;uiVal<ValMS;uiVal++) for(ujVal=0;ujVal<120;ujVal++);}/***************************************************函数功能:开始数据传送***************************************************/voidStart()//开始位{SDA=1;//SDA初始化为高电平"1"SCL=1;//开始数据传送时,要求SCL为高电平"1"Delay5us();//延时5usSDA=0;//SDA的下降沿被认为是开始信号Delay5us();//延时5usSCL=0;//SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)}/***************************************************函数功能:结束数据传送***************************************************/voidStop()//停止位{SDA=0;//SDA初始化为低电平"0"_nSCL=1;//结束数据传送时,要求SCL为高电平"1"Delay5us();//延时5usSDA=1;//SDA的上升沿被认为是结束信号
Delay5us();//延时5usSDA=0;SCL=0;}//单片机接收时单片机产生应答信号voidI2C_Ack(void){SCL=0; //为产生脉冲准备
SDA=0; //产生应答信号
Delay5us(); //延时你懂得
SCL=1;Delay5us(); SCL=0;Delay5us(); //产生高脉冲
SDA=1; //释放总线}//单片机非应答信号voidI2C_nAck(void){SCL=0; //为产生脉冲准备
SDA=1; //产生应答信号
Delay5us(); //延时你懂得
SCL=1;Delay5us(); SCL=0;Delay5us(); //产生高脉冲 }/**************************************************函数功能:发送一字节***************************************************/voidSendByte(ucharc) {ucharn; for(n=0;n<8;n++)//一字节为8位,循环8次
{if(c&0x80)//先高后低,将数据线SDA置1或清0 SDA=1; else SDA=0; SCL=1;//SCL为高,通知从机开始接收数据
Delay5us();
SCL=0;//SCL变低,准备发送下一位数据准备下一位要发送的数据
c=c<<1;//准备下一位要发送的数据
} SDA=1;//一字节发送完后释放数据线
Delay5us(); SCL=1;//SCL由低变高,产生一个时钟
Delay5us(); if(SDA==1)//如果SDA=1,则发送失败。
ack_mk=0; else ack_mk=1;//如果SDA=0,则发送成功。
SCL=0;//SCL变低。
}/**************************************************函数功能:接收一字节***************************************************/
ucharRcvByte(){ ucharn,c;{for(n=0;n<8;n++)//一字节为8位,循环8次,先高后低
{SDA=1;//置数据线SDA为高,进入接收方式
SCL=1;//SCL由低变高,产生一个时钟
if(SDA==0)//根据数据线SDA的状态,将c的最高位清0或置1 c=c&0x7f; else c=c|0x80; c=_crol_(c,1);//将c循环左移一位,为接收下一位准备
SCL=0;//时钟线SCL清0
} return(c); }}/**************************************************函数功能:发送多字节***************************************************/bitSendStr(ucharsla,ucharsuba,uchar*s,ucharn){uchari;Start(); //发起始信号,启动总线
SendByte(sla);//发送器件地址
if(ack_mk==0)return(0);//没能应答,操作失败
SendByte(suba);//发送器件子地址
if(ack_mk==0)return(0);//没能应答,操作失败
for(i=0;i<n;i++)//循环n次
{SendByte(*s); if(ack_mk==0)return(0);//没能应答,操作失败
s++;//指向下一个字节
} Stop();//发结束信号,结束本次数据传送
return(1);}/**************************************************函数功能:接收多字节***************************************************/bitRcvStr(ucharsla,ucharsuba,uchar*s,ucharn){ uchari;Start();//发起始信号,启动总线
SendByte(sla);//发送器件地址if(ack_mk==0)return(0);//如果没能应答,操作失败
SendByte(suba);//发送器件子地址if(ack_mk==0)return(0);//如果没能应答,操作失败
Start();//再次发起始信号
SendByte(sla+1); //sla+1表示进行读操作if(ack_mk==
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电线电缆专用材料项目可行性研究报告
- 2025年软件测试经验总结与试题及答案
- 2025年计算机二级C语言知识点试题及答案
- 风险管理在企业文化中的体现试题及答案
- JAVA文件处理与流操作知识试题及答案
- 2025年计算机二级C语言考试要点试题及答案
- 2025年二级ACCESS考试考场Tips试题及答案
- 2025年二级ACCESS考试细节试题及答案解析
- 赋能未来2025年税法考试试题及答案
- 电梯安装合同协议书范本
- 2024北京丰台区四年级(下)期末数学试题及答案
- 2025至2030年多功能背封包装机项目投资价值分析报告
- 餐厅送货协议合同
- 竞聘资产管理部部长岗位
- 2025衢州辅警考试题库
- 七年级下册 第四单元 专题学习活动 孝亲敬老从我做起 课件
- 雨水泵站专项施工方案
- 2025年铁塔安全考试试题及答案
- 新《城镇燃气设施运行、维护和抢修安全技术规程》考试题库(含答案)
- 端午节活动:五彩绳
- 2025年度会计人员继续教育会计法律法规答题活动测试100题答案
评论
0/150
提交评论