现代电子技术综合实验.doc_第1页
现代电子技术综合实验.doc_第2页
现代电子技术综合实验.doc_第3页
现代电子技术综合实验.doc_第4页
现代电子技术综合实验.doc_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

题目:基于单片机的双路信号检测系统综合设计摘要本设计是基于MCS-51系列的单片机进行的双路信号检测系统的设计,可以同时对环境温度和0V2.5V直流电压进行检测的,电压的检测采用TLC549串行ADC器件;对温度的检测采用LM75A数字温度传感器;检测结果以动态扫描方式显示在一个8位LED数码显示器上,并且可以通过键盘对系统加以控制。具体实现功能为:程序运行后,LED显示器显示“P”,表示处于“待命”状态,按下“1”键进行电压测量并显示;按下“2”键进行温度测量并显示;按下“3”键电压与温度交替测量并显示;按下“8”键返回“待命”状态。概述: 单片机是在工业测控需要背景下产生的,在一个应用系统中,按照测控系统的特点和要求,单片机的应用可分为单机应用和多机应用两大类。单片机在单机应用领域中的主要工作内容有:智能产品、智能仪表、测控技术、智能接口等,几乎涉及我们生活中的方方面面。硬件电路设计:u 系统组成框图:LED数码显示器微控制器AT89C51键盘数字电压表TLC549数字温度计LM75Au 单元电路属性: 微控制器AT89C51功能:单片机是一种特殊的计算机,它是在一块半导体芯片上集成了CPU、存储器RAM、ROM以及输入与输出接口电路,这种芯片习惯上被称为单片微型计算机,简称单片机。目前在国外已被普遍称之为微控制器MCU。在一个应用系统中单片机只要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。本设计就是利用单片机的计算及存储功能,将数字温度计及TLC549采得的数据送予单片机处理并在数码管上显示。组成:每一片单片机应包括如下模块 l 中央处理器CPU;l 内部数据存贮器RAM,用以存放可以读写的数据,如运算的中间结果和最终结果等;l 内部指令存贮器ROM,用以存放程序,也可以存放一些原始数据和表格,但也有一些单片机内部不带ROM;l 四个8位的并行输入/输出端口,每个端口可以用作输入,也可以用作输出;l 二个或三个定时/计数器,可以用来对外部事物进行技术,也可以设置成定时器,并可以根据计数或定时的结果对计算机进行控制;l 内部中断控制系统;l 一个串行接口电路,是的数据可以一位一位串行地在计算机和外设之间传送;l 特殊功能寄存器;以上各个部分通过内部数据总线相连接 AT89C51管脚图电路原理图:单片机内部硬件结构图工作原理:1.引脚排列及功能(1)I/O口线l P0口8位、漏极开路的双向I/O口当使用片外存储器及外扩I/O口作为低字节地址/数据复用线。在编程时,P0口可用于接收指令代码字节;程序校验时,可输出指令字节。P0口也可用作同用I/O口使用,但需加上拉电阻。作为普通输入时,应输出锁存器配置1。l P1口8位、准双向I/O口,具有内部上拉电阻P1口是为用户准备的I/O双向口。在编程和校验时,可用作输入低8位地址。用作输入时,应先将输出锁存器置1。P1口可驱动4个TTL负载。l P2口8位、准双向I/O口,具有内部上拉电阻当使用外部存储器或外扩I/O口时,P2口输出高8位地址。在编程和校验时,P2口接收高字节地址和某些控制信号。l P3口8位、准双向I/O口,具有内部上拉电阻P3口可作为普通I/O口。用作输入时,应先将输出锁存器置1。在编程/校验时,P3口接收某些控制信号。它可驱动4个TTL负载。(2)控制信号线l RST复位输入信号,高电平有效。在振荡器稳定工作时,在RST脚施加两个机器周期以上的高电平,将器件复位。l EA/Vpp外部程序存储器访问允许信号EA。当EA信号接l 地时,对ROM的读操作限定在外部存储器,地址为0000HFFFFH;当EA接Vcc时,对ROM的读操作从内部程序存储器开始,并可延续至外部程序存储器。在编程时,该引脚可接触编程电压5V或12V。在编程校验时,该引脚可接VCC。l PSEN片内程序存储器读选通信号PSEN。在片外程序存储器取指期间,当PSEN有效时,程序存储器的内容被送至P0口;在访问外部RAM时,PSEN无效。l ALE/PROG低字节锁存信号ALE。在系统扩展时,ALE的下降沿将P0口输出的低8位地址锁存在外接的地址锁存器中,以实现低字节地址和数据的分时传送。此外,ALE端连续输出正脉冲,频率为晶振频率的1/6,可做外部定时脉冲使用。(3)外部晶振引线l XTAL1 片内振荡器反向放大器和时钟发生线路的输入端。使用片内振荡器时,连接外部石英晶体和微调电容。l XTAL2 片内振荡器反向放大器的输出端。当使用片内振荡器时,外接石英体和微调电容。 数字温度计LM75A功能:LM75A是一个使用了内置带隙温度传感器和-模数转换技术的温度-数字转换器。它也是一个温度检测器,可提供一个过热检测输出。LM75A有3个可选的逻辑地址管脚,使得同一总线上可同时连接8个器件而不发生地址冲突。组成:LM75A包含许多数据寄存器:配置寄存器(Conf),用来存储器件的某些配置,如器 芯片管脚图件的工作模式、OS工作模式、OS极性和OS故障队列等;温度寄存器(Temp),用来存储读取的数字温度;设定点寄存器(Tos & Thyst),用来存储可编程的过热关断和滞后限制,器件通过2线的串行I2C总线接口与控制器通信。LM75A还包含一个开漏输出(OS),当温度超过编程限制的值时该输出有效。电路原理图:芯片电路图 实验原理图工作原理:LM75A利用内置的分辨率为0.125的带隙传感器来测量器件的温度,并将模数转换得到的11位的二进制数的补码数据存放到器件Temp寄存器中。Temp寄存器的数据可随时被I2C总线上的控制器读出。读温度数据并不会影响在读操作过程中执行的转换操作。LM75A可设置成工作在两种模式:正常工作模式或关断模式。在正常工作模式中,每隔100ms执行一次温度-数字的转换,Temp寄存器的内容在每次转换后更新。在关断模式中,器件变成空闲状态,数据转换禁止,Temp寄存器保存着最后一次更新的结果;但是,在该模式下,器件的I2C接口仍然有效,寄存器的读/写操作继续执行。器件的工作模式通过配置寄存器的可编程位B0来设定。当器件上电或从关断模式进入正常工作模式时启动温度转换。 数字电压表TLC549功能:TLC549是TI公司生产的一种性价比非常高的8位A/D转换器,它以8位开关电容逐次逼近的方法实现A/D转换,其转换速度小于17us,它能方便地采用三线串行接口方式与各种微处理器连接,构成各种廉价的测控应用系统。 芯片管脚图组成:TLC549包括通用控制逻辑,可自动工作或在微处理器控制下工作的片内采样-保持电路,具有差分高阻抗基准电压输入端,易于实现比率转换、定标以及与逻辑和电源噪声隔离的电路。整个开关电容逐次逼近转换器电路的设计允许在小于17s的时间内以最大总误差为0.5最低有效位(LSB)的精度实现转换。电路原理图:TLC549系统功能框图 TLC549实验原理图工作原理:TLC549有片内系统时钟,该时钟与I/O CLOCK是独立工作的,无须特殊的速度或相位匹配。其工作时序为:当CS为高时,数据输出(DATA OUT)端处于高阻状态,此时I/O CLOCK不起作用。这种CS控制作用允许在同时使用多片TLC549时,共用I/O CLOCK,以减少多路(片)A/D并用时的I/O控制端口。一组通常的控制时序为:(1)将CS置低。内部电路在测得CS下降沿后,再等待两个内部时钟上升沿和一个下降沿后,然后确认这一变化,最后自动将前一次转换结果的最高位(D7)位输出到DATA OUT端上。(2)前四个I/O CLOCK周期的下降沿依次移出第2、3、4和第5个位(D6、D5、D4、D3),片上采样保持电路在第4个I/O CLOCK下降沿开始采样模拟输入。(3)接下来的3个I/O CLOCK周期的下降沿移出第6、7、8(D2、D1、D0)个转换位。(4)最后,片上采样保持电路在第8个I/O CLOCK周期的下降沿将移出第6、7、8(D2、D1、D0)个转换位。保持功能将持续4个内部时钟周期,然后开始进行32个内部时钟周期的A/D转换。第8个I/O CLOCK后,CS必须为高,或I/O CLOCK保持低电平,这种状态需要维持36个内部系统时钟周期以等待保持和转换工作的完成。如果CS为低时I/O CLOCK上出现一个有效干扰脉冲,则微处理器/控制器将与器件的I/O时序失去同步;若CS为高时出现一次有效低电平,则将使引脚重新初始化,从而脱离原转换过程。在36个内部系统时钟周期结束之前,实施步骤(1)(4),可重新启动一次新的A/D转换,与此同时,正在进行的转换终止,此时的输出是前一次的转换结果而不是正在进行的转换结果。若要在特定的时刻采样模拟信号,应使第8个I/O CLOCK时钟的下降沿与该时刻对应,因为芯片虽在第4个I/O CLOCK时钟下降沿开始采样,却在第8个I/O CLOCK的下降沿开始保存。 八段数码管:功能:数码管通过点亮和熄灭相应的二极管以达到显示所需内容的功能。组成:数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按能显示多少个“8”可分为1位、2位、4位等等数码管;该设计所采用的为8位8段数码管。电路原理图: a) 共阳极八段数码管 b)共阴极八段数码管b) 数码管公共端在中间d)数码管公共端在旁边实验原理图 工作原理:用数码管显示信息时,由于每个数码管至少需要8 个I/O口,如果需要多个数码管,则需要太多I/O 口,而单片机的I/O 口是有限的。在实际应用中,一般采用动态显示的方式解决此问题。动态显示是多个数码管,交替显示,利用人的视觉暂留作用使人看到多个数码管同时显示。在编程时,需要输出段选和位选信号,位选信号选中其中一个数码管,然后输出段码,使该数码管显示所需要的内容,延时一段时间后,再选中另一个数码管,再输出对应的段码,高速交替。在动态显示程序中,各个位的延时时间长短是非常重要的,如果延时时间长,则会出现闪烁现象;如果延时时间太短,则会出现显示暗且有重影。 键盘:每一个按键都通过上拉电阻接到高电平,当按键未按下时向单片机输入一个高电平,同时单片机对连接按键的I/O口不断扫描,若扫描到某端口为低电平,表明相应的按键按下,单片机可根据程序设定执行相应的功能。程序设计:l 模块化程序设计的思路介绍:根据所要实现的功能,可将总体设计划分为四个模块:单片机主体、数字温度计、模数转换器、键盘以及数码管部分。在设计过程中可先将各个模块调试通过以后整合得到最终结果。如:先把数码管显示部分调试好,将数字温度计模块加入,使数码管可以正确显示温度值,再将模数转换器部分加入,正常显示电压值。最后再把键盘部分程序编好,使得按下相应按键可实现相应功能。l 总的程序流程框图:系统初始化 调用显示子程序数码管显示P扫描键盘取得K值按键按下?按键按下?按键按下?按键按下?任意按键按下?调用显示子程序数码管显示温度值调用显示子程序数码管交替显示电压值和温度值任意按键按下? Y N Y N Y N Y N调用显示子程序数码管显示电压值 N Y任意按键按下? N Y N Y调用显示子程序数码管显示P任意按键按下? N Yl 各部分程序设计介绍: 数字温度计LM75A:程序流程图:读出LM75A寄存器中的数值字符型数值转换为10进制数值分离出百位、十位及个位数值,并在数码管显示系统初始化延时1S K=0? Y N结束所用函数功能: 函数:temSysInit() 功能:系统初始化 函数:LM75A_GetTemp 功能:读出LM75A的温度值返回:LM75A温度寄存器的数值(乘以0.125可得到摄氏度值) 函数:ByteToStr() 功能:字节型变量c转换为十进制字符串 函数:DispTemp() 功能:在数码管上显示出温度值较特殊的处理方式:因数码管位数有限,所以前四位用于温度值显示,后四位用于电压值显示,又因为常见温度正负都很难达到三位数,所以四位安排为:第一位用于显示温度符号,中间两位显示整数部分,第四位显示小数部分。故将ByteToStr()中对100取余一步去掉,并把DispTemp()函数中小数部分改为0-9,整数部分,小数点及小数部分的显示位置也做了调整。 数字电压表TLC549:程序流程图:系统初始化CS置高;I/O CLOCK低;移位计数器置0选TLC549;CS置低结束延时CS置高读DATA OUT I/O CLOCK置高选TLC549;CS置低1.4微妙后I/O CLOCK置高K=0?是第8位吗? N Y Y N所用函数功能: 函数:adcSysInit() 功能:系统初始化 函数:AdcInit() 功能:初始化ADC接口 函数:DispVol() 功能:将ADC值转换成电压值,并显示较特殊的处理方式:为防止电压显示与温度显示冲突,采用了二者交替显示的方式。 数码管部分:程序流程图:系统初始化数码管清除,位码置1延时位码加1,传送段码位码=8? N Y所用函数功能: 函数:DispInit() 功能:数码管扫描显示初始化 函数:DispClear() 功能:清除数码管的所有显示 函数:DispChar() 功能:在数码管上显示字符 参数:x:数码管的坐标位置(07) c:要显示的字符(仅限十进制数字和减号) 函数:DispStr() 功能:在数码管上显示字符串 参数:x:数码管的坐标位置(07) *s:要显示的字符串(字符仅限十进制数字和减号) 函数:DispDotOn() 功能:显示指定位的小数点参数:x为数码管坐标较特殊的处理方式:在DispChar()函数中加入一个新的条件语句用以显示P,在主程序中调用时,只要所选参数不在DispChar()函数所包含范围内即可显示P。系统调试: 硬件平台:采用SmartSOPC 实验箱和Quick51核心板。SmartSOPC多功能教学实验开发平台集众多种功能于一体,是SOPC、EDA、DSP、ARM、ARM7 SOC以及51教学实验、科研开发的最佳选择。开发平台采用核心板加主板的结构,更换核心板即可实现不同的功能。用户也可根据开放的接口来设计自己的核心板。基于标配QuickSOPC核心板的开发平台可进行SOPC、EDA、DSP的开发和实验。与一般的实验箱不同,SmartSOPC主板上大部分外设都不需要进行跳线设置,做实验时方便简单;此外每个外设的信号都设置了测试点,方面用户使用逻辑分析仪进行信号测量。Quick51正是跟SmartSOPC相配套的8051单片机核心板,是一款自由的、开放全部系统资源的单片机实验板。单片机芯片采用Philips最新推出的拥有64KB Flash的增强型8052内核单片机P89LV51RD2,工作电压3.3V。Quick51与SmartSOPC配合,可以做各种单片机教学实验,如LED点阵扫描显示、键盘检测、动态数码管、液晶屏、电机驱动、IC总线、红外收发、蜂鸣器、数字温度计、电子钟等等。 跳线连接情况:首先参照Quick51跳线设置表检查Quick51电路板上跳线JP1JP7是否为默认设置;1. Quick51实验板J14的PB-LE用杜邦线连接到J9;2. Quick51实验板的P1端口用8芯排线连接到SmartSOPC实验箱B3区的COM6;3. Quick51实验板的J11(PB端口)用8芯排线连接到SmartSOPC实验箱B3区的COM3;4. SmartSOPC实验箱C2区的SCL用杜邦线连接到Quick51实验板J5的T0;5. SmartSOPC实验箱C2区的SDA用杜邦线连接到Quick51实验板J5的T1;6. Quick51实验板J5的/INT0用杜邦线连接到SmartSOPC实验箱D4区的nCS;7. Quick51实验板J5的/INT1用杜邦线连接到SmartSOPC实验箱D4区的DAT;8. Quick51实验板J5的T0用杜邦线连接到SmartSOPC实验箱D4区的CLK;9. SmartSOPC实验箱JP6的KEY1、KEY2、KEY3、KEY8分别用短路帽短接;10. SmartSOPC实验箱B2区JP6中跳线全部断开。程序调试工具:Keil C51 Keil Vison系列是德国Keil Software(现已并入ARM公司)公司推出的51系列兼容单片机软件开发系统。Vison3是集成的可视化Windows操作界面,其提供了丰富的库函数和各种编译工具,能够对51系列单片机以及51系列兼容的绝大部分类型的单片机进行设计。Keil Vison系列可以支持单片机C51程序设计语言,也可以直接进行汇编语言的设计与编译。其主要特点有:支持汇编语言、C51语言等多种单片机设计语言;可视化的文件管理,界面友好;支持丰富的产品线,除了51及其兼容内核的单片机外,还新增加了对ARM内核产品的支持;具有完善的编译连接工具;具备丰富的仿真调试功能,可以仿真串口、A/D、D/A、定时器/计数器以及中断等资源,同时也可以和外部仿真器联合进行在线调试;内嵌RTX51实时多任务操作系统;支持在一个工作空间中进行多项目的程序设计;支持多级代码优化。 程序调试步骤: 首先将数字温度计、数字电压表、键盘扫描、数码管显示等模块程序 写好,在主程序中调试数码管显示程序,之后将数字温度计程序加入,使数码管可以正确显示温度值。将数字温度计部分程序屏蔽,再将数字电压表程序加入,调试正确使数码管可以正确显示电压值。再把程序进行修改,增加温度、电压值交替显示的功能。最后将键盘部分加入,使得按下相应键可以实现相应的功能。至此调试结束。参考文献:1单片微型计算机原理、接口及应用 徐惠民、安德宁编著北京邮电大学出版社 2000年10月版2百度文库周立功Quick51实验指导书3道客巴巴AT89C51中文资料48位串行模数转换器TLC549的应用 安源附录:程序代码: 主程序:/*main.c数字温度计、数字电压表*/#include Disp.h#include I2C.h#include #include #include VolTab.h#include #include /定义TLC549、LM75A、键盘操作接口sbit CS = P32;sbit DAT = P33;sbit CLK = P34;sbit KEY1 = P20;sbit KEY2 = P21;sbit KEY3 = P22;sbit KEY8 = P27;/*函数:Delay()功能:延时1ms65.536s参数:t0时,延时(t*0.001)st=0时,延时65.536s*/void Delay(unsigned int t)doTH0 = 0xFC;TL0 = 0x66;TR0 = 1;while ( !TF0 );TR0 = 0;TF0 = 0; while ( -t != 0 );/*函数:ReadAdc()功能:读取A/D转换结果返回:8位ADC代码*/unsigned char ReadAdc()unsigned char d;unsigned char n;CS = 0;n = 5;while ( -n != 0 );n = 8;dod = 1;if ( DAT ) d+;CLK = 1;CLK = 0;while ( -n != 0 );CS = 1;return d;/*函数:AdcInit()功能:初始化ADC接口*/void AdcInit()CS = 1;CLK = 0;DAT = 1;ReadAdc();/*函数:adcSysInit()功能:数字电压表系统初始化*/void adcSysInit()TMOD &= 0xF0;TMOD |= 0x01;DispInit();AdcInit();Delay(10);/*函数:temSysInit()功能:数字温度计系统初始化*/void temSysInit()TMOD &= 0xF0;TMOD |= 0x01;/设置T0为16位定时器DispInit();/数码管扫描显示初始化I2C_Init();/初始化I2C总线/*函数:LM75A_GetTemp功能:读出LM75A的温度值返回:LM75A温度寄存器的数值(乘以0.125可得到摄氏度值)*/int LM75A_GetTemp()unsigned char buf2;int t;I2C_Gets(0x90,0x00,2,buf);t = buf0;t = 5;/去掉无关位return t;/*函数:ByteToStr()功能:字节型变量c转换为十进制字符串*/void ByteToStr(unsigned char idata *s, unsigned char c)code unsigned char Tab = 10;unsigned char i;unsigned char t;for ( i=0; i1; i+ )t = c / Tabi;*s+ = 0 + t;c -= t * Tabi;*s+ = 0 + c;*s = 0;/定义显示缓冲区(由定时中断程序自动扫描)unsigned char DispBuf8;/*函数:T1INTSVC()功能:定时器T1的中断服务函数*/void T1INTSVC() interrupt 3code unsigned char com = 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80;static unsigned char n = 0;TR1 = 0;TH1 = 0xFC;TL1 = 0x66;TR1 = 1;P1 = 0xFF;/暂停显示XBYTE0xE800 = DispBufn;/更新扫描数据P1 = comn;/重新显示n+;n &= 0x07;/扫描键盘unsigned char KeyScan()unsigned char k = 0;if ( KEY1 = 0 ) k = 1;if ( KEY2 = 0 ) k = 2;if ( KEY3 = 0 ) k = 3;if ( KEY8 = 0 ) k = 8;return k;/*函数:DispClear()功能:清除数码管的所有显示*/void DispClear()unsigned char i;for ( i=0; i8; i+ )DispBufi = 0x00;/*函数:DispP()功能:在数码管显示字幕P*/void DispP( )DispBuf1 = 0x73;/*函数:DispVol()功能:将ADC值转换成电压值,并显示参数:v:8位ADC结果*/void DispVol(unsigned char v)DispStr(5,VolTabv);DispDotOn(5);/*函数:DispTemp()功能:在数码管上显示出温度值参数:t:补码,除以8以后才是真正温度值*/void DispTemp(int t)code unsigned char Tab104 =0,1,2,3,4,5,6,7,8,9;unsigned char buf4;bit s;/符号位unsigned char i;/整数部分unsigned char d;/小数部分unsigned char x;/临时变量/分离出符号s = 0;if ( t 0 )s = 1;t = -t;/分离出整数和小数部分i = t / 8;d = t % 8;/整数部分转换成字符串ByteToStr(buf,i);x = 4 - strlen(buf);/清除所有显示DispClear();/显示符号if ( s ) DispChar(x,-);x+;/显示整数部分DispStr(x,buf);/显示小数点DispDotOn(2);/显示小数部分DispStr(4,Tabd);/*函数:DispT()功能:在数码管上显示出温度值*/void DispT()int t;unsigned char k;temSysInit();for (;)t = LM75A_GetTemp();DispTemp(t);Delay(1000);k=KeyScan();if (k != 0) break;/*函数:DispV()功能:在数码管显示电压值*/void DispV()unsigned char v;/电压值unsigned char k;adcSysInit();for (;)v = ReadAdc();/读取ADC值DispVol(v);/显示成电压值Delay(30);/延时300msk=KeyScan();if (k != 0) break;/*函数:DispBoth()功能:在数码管交替显示电压值和温度值*/void DispBoth( )unsigned char v;/电压值unsigned char k;int t;for (;)t = LM75A_GetTemp();DispTemp(t);Delay(100);DispClear();v = ReadAdc();/读取ADC值DispVol(v);/显示成电压值Delay(100);/延时300msDispClear();k=KeyScan();if (k != 0) break;void main()unsigned char v;int t;unsigned char k;adcSysInit();temSysInit();DispP( );for (;)Delay(5);/延时50msk = KeyScan();/键盘扫描if ( k != 0 ) break;/如果有键按下,退出循环for(;)switch ( k )case 1: v = ReadAdc(); DispV();break;case 2: t = LM75A_GetTemp(); DispT(); break;case 3:DispBoth( ); break;case 8:DispP( ); break;default: break;子程序:/*I2C.c标准80C51单片机模拟I2C总线的主机程序*/#include I2C.h/定义延时变量,用于宏I2C_Delay()unsigned char data I2C_Delay_t;/*宏定义:I2C_Delay()功能:延时,模拟I2C总线专用*/#define I2C_Delay()I2C_Delay_t = (I2C_DELAY_VALUE);while ( -I2C_Delay_t != 0 );/*函数:I2C_Init()功能:I2C总线初始化,使总线处于空闲状态说明:在main()函数的开始处,通常应当要执行一次本函数*/void I2C_Init()I2C_SCL = 1;I2C_Delay();I2C_SDA = 1;I2C_Delay();/*函数:I2C_Start()功能:产生I2C总线的起始状态说明:SCL处于高电平期间,当SDA出现下降沿时启动I2C总线不论SDA和SCL处于什么电平状态,本函数总能正确产生起始状态本函数也可以用来产生重复起始状态本函数执行后,I2C总线处于忙状态*/void I2C_Start()I2C_SDA = 1;I2C_Delay();I2C_SCL = 1;I2C_Delay();I2C_SDA = 0;I2C_Delay();I2C_SCL = 0;I2C_Delay();/*函数:I2C_Write()功能:向I2C总线写1个字节的数据参数:dat:要写到总线上的数据*/void I2C_Write(unsigned char dat)unsigned char t = 8;doI2C_SDA = (bit)(dat & 0x80);dat = 1;I2C_SCL = 1;I2C_Delay();I2C_SCL = 0;I2C_Delay(); while ( -t != 0 );/*函数:I2C_Read()功能:从从机读取1个字节的数据返回:读取的一个字节数据*/unsigned char I2C_Read()unsigned char dat;unsigned char t = 8;I2C_SDA = 1;/在读取数据之前,要把SDA拉高doI2C_SCL = 1;I2C_Delay();dat = 1;if ( I2C_SDA ) dat |= 0x01;I2C_SCL = 0;I2C_Delay(); while ( -t != 0 );return dat;/*函数:I2C_GetAck()功能:读取从机应答位返回:0:从机应答1:从机非应答说明:从机在收到每个字节的数据后,要产生应答位从机在收到最后1个字节的数据后,一般要产生非应答位*/bit I2C_GetAck()bit ack;I2C_SDA = 1;I2C_Delay();I2C_SCL = 1;I2C_Delay();ack = I2C_SDA;I2C_SCL = 0;I2C_Delay();return ack;/*函数:I2C_PutAck()功能:主机产生应答位或非应答位参数:ack=0:主机产生应答位ack=1:主机产生非应答位说明:主机在接收完每一个字节的数据后,都应当产生应答位主机在接收完最后一个字节的数据后,应当产生非应答位*/void I2C_PutAck(bit ack)I2C_SDA = ack;I2C_Delay();I2C_SCL = 1;I2C_Delay();I2C_SCL = 0;I2C_Delay();/*函数:I2C_Stop()功能:产生I2C总线的停止状态说明:SCL处于高电平期间,当SDA出现上升沿时停止I2C总线不论SDA和SCL处于什么电平状态,本函数总能正确产生停止状态本函数执行后,I2C总线处于空闲状态*/void I2C_Stop()unsigned int t = I2C_STOP_WAIT_VALUE;I2C_SDA = 0;I2C_Delay();I2C_SCL = 1;I2C_Delay();I2C_SDA = 1;I2C_Delay();while ( -t != 0 );/在下一次产生Start之前,要加一定的延时/*函数:I2C_Puts()功能:主机通过I2C总线向从机发送多个字节的数据参数:SlaveAddr:从机地址(高7位是从机地址,最低位是写标志0)SubAddr:从机的子地址Size:数据的字节数*dat:要发送的数据返回:0:发送成功1:在发送过程中出现异常*/bit I2C_Puts(unsigned char SlaveAddr, unsigned char SubAddr, unsigned char Size, char *dat)/检查长度if ( Size = 0 ) return 0;/确保从机地址最低位是0SlaveAddr &= 0xFE;/启动I2C总线I2C_Start();/发送从机地址I2C_Write(SlaveAddr);if ( I2C_GetAck() )I2C_Stop();return 1;/发送子地址I2C_Write(SubAddr);if ( I2C_GetAck() )I2C_Stop();return 1;/发送数据doI2C_Write(*dat+);if ( I2C_GetAck() )I2C_Stop();return 1; while ( -Size != 0 );/发送完毕,停止I2C总线,并返回结果I2C_Stop();return 0;/*函数:I2C_Put()功能:主机通过I2C总线向从机发送1个字节的数据参数:SlaveAddr:从机地址(高7位是从机地址,最低位是写标志0)SubAddr:从机的子地址dat:要发送的数据返回:0:发送成功1:在发送过程中出现异常*/bit I2C_Put(unsigned char SlaveAddr, unsigned char SubAddr, char dat)return I2C_Puts(SlaveAddr,SubAddr,1,&dat);/*函数:I2C_Gets()功能:主机通过I2C总线从从机接收多个字节的数据参数:SlaveAddr:从机地址(高7位是从机地址,最低位是读标志1)SubAddr:从机的子地址Size:数据的字节数*dat:保存接收到的数据返回:0:接收成功1:在接收过程中出现异常*/bit I2C_Gets(unsigned char SlaveAddr, unsigned char SubAddr, unsigned char Size, char *dat)/检查长度if ( Size = 0 ) return 0;/确保从机地址最低位是0SlaveA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论