第8章-IO口的C语言编程.pptx

上传人:可**** 文档编号:75844269 上传时间:2023-03-05 格式:PPTX 页数:83 大小:2.70MB
返回 下载 相关 举报
第8章-IO口的C语言编程.pptx_第1页
第1页 / 共83页
第8章-IO口的C语言编程.pptx_第2页
第2页 / 共83页
点击查看更多>>
资源描述

《第8章-IO口的C语言编程.pptx》由会员分享,可在线阅读,更多相关《第8章-IO口的C语言编程.pptx(83页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、 C 语言提高篇I/O的C语言编程C language programming of I/O port本章主要从I/O口的内部结构和工作原理、作输出功能的原理及应用、作输入功能的原理及应用对I/O口进行讲解2IO口的C语言编程目 录8.2 I/O输出口应用及编程8.1 单片机的I/O口内部结构8.3 I/O输入口应用及编程38 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构MCS-51单片机的输出口有4个,分别为P0、P1、P2、P3,其中,P1,P2和P3口是准双向口,P0口为双向三态口。48 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构 1P0口P0口一个

2、引脚的内部结构如图8-1所示。从图8-1中可以看出,电路中包含一个数据输出锁存器、两个三态数据输入缓冲器和一个数据输出的驱动电路。P0.x可以是P0.0到P0.7中的任何一位,即P0口是由8个与图8-1相同的电路构成。多路开关MUX与相连接时,P0口作为普通的I/O口使用;多路开关MUX和与门相连接时,P0口作为数据/地址总线使用。P0口作为I/O口使用时,由于其内部没有上拉电阻,因而需要外接上拉电阻。5图8-1P0口内部结构8 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构 2P1口 P1口为8位准双向口,这8位均可单独定义为输入或输出口,每一位的内部电路结构如图8-2所示。

3、P1.x输出数据时,把1写入锁存器时,=0,T2截止,内上拉电阻将电位拉至1,此时该口输出为1;把0写入锁存器时,=1,T2导通,输出为0。准双向口P1作为输入口时,应先将锁存器置1,这样=0,T2截止,此时该位既可以由外部电路拉成低电平,也可由内部上拉电阻拉成高电平。6图8-2P1口内部结构8 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构双向口与准双向口的区别是准双向I/O口用于数据输入时需要先对其置1,否则,若前一位输入低电平,后一位输入高电平时将导致数据出错;而双向口则不需要提前置1操作,因为双向口有悬浮态。7需要说明的是,P1作为输入口使用时,输入方式有两种情况:(1

4、)先读锁存器的内容,处理后再写入到锁存器,这种操作即“读修改写”操作,JBC(逻辑判断)、CPL(取反)、INC(递增)、DEC(递减)、ANL(与逻辑)和ORL(逻辑或)指令均属于这类操作。(2)打开三态门G2,将P1口的外部状态读入CPU。8 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构 3P2口 P2口不仅可以用作输入/输出口,也可以和P0口一起用作外部存储器的地址总线。8由于单片机没有专用的地址总线和数据总线,在向外扩展存储器和接口时,P2口和P0口充当地址总线和数据总线,P2口输出地址的高8位(A8A15),P0口输出地址的低8位(A0A7)。P2口结构如图8-3所

5、示。图8-3P2口内部结构8 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构 4P3口9 P3口的第一功能和P1口一样,既可作为输入/输出端口,又能够进行字节操作和位操作。在位操作模式下,每位引脚可以单独定义为输入或输出引脚。在实际应用中,P3口第二功能的作用更为突出。为适应第二功能的需要,每位引脚内部都增加了第二功能控制逻辑,其内部结构如图8-4所示。图8-4P3口内部结构8 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构下面着重讨论P3口的第二功能,P3口用于第二功能的各引脚定义如下:10P3.0:串行输入口(RXD)。P3.1:串行输出口(TXD)。P3.

6、2:外部中断0(INT0)。P3.3:外部中断1(INT1)。P3.4:定时/计数器0的外部输入口(T0)。P3.5:定时/计数器1的外部输入口(T1)。P3.6:外部数据存储器写选通(WR)。P3.7:外部数据存储器读选通(RD)。P3作为输出端口使用时,第二功能信号线保持高电平,与非门开通,从锁存器到输出口的通路畅通无阻,数据能够正常输出。P3口使用第二功能输出时,锁存器置为高电平,与非门对第二功能信号的输出是畅通的,从而实现第二功能信号的输出。8 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构使用第二功能输入时,引脚的第二功能控制逻辑在输入通路上增设了一个缓冲器,输入的第

7、二功能信号可从这个缓冲器的输出端取得。而作为I/O口时,输入信号取自三态缓冲器的输出端。不管是作为第一功能的输入端口使用还是第二功能信号输入,输出电路中的锁存器输出和第二功能输出信号线均应置1。新型的51系列单片机,除了有传统的P0P3口之外,还有P4口,各端口地址及数据位如表8-1所示。11表8-1新型51单片机I/O端口助记符地址名字76543210复位值P080H8位P0P0.7P0.6P0.5P0.4P0.3P0.2P0.1P0.011111111P190H8位P1P1.7P1.6P1.5P1.4P1.3P1.2P1.1P1.011111111P2A0H8位P2P2.7P2.6P2.5

8、P2.4P2.3P2.2P2.1P2.011111111P3B0H8位P3P3.7P3.6P3.5P3.4P3.3P3.2P3.1P3.011111111P4E8H4位P4-P4.3P4.2P4.1P4.0*11118 8.1 .1 单片机的单片机的I/OI/O口内部结构口内部结构P4口可以像普通的P1,P2,P3口一样进行操作,在使用C语言编程时,需要在程序的开头进行声明。sfrP4=0 xe8;/C语言中声明P4口特殊功能寄存器地址在汇编语言编程时,可以进行如下操作。P4DATA0E8H;或P4EQU0E8HMOVA,P4;读取P4口的状态到累加器中MOVP4,#0AH;向P4口输出数据“

9、#0AH”SETBP4.0;P4.0=1CLRP4.0;P4.0=012IO口的C语言编程目 录8.2 I/O输出口应用及编程8.1 单片机的I/O口内部结构8.3 I/O输入口应用及编程138 8.2 .2 I/OI/O输出口应用及编程输出口应用及编程148.2.1驱动发光二极管8.2.2驱动蜂鸣器8.2.3驱动继电器8.2.4驱动7段LED数码管8.2.1 8.2.1 驱动发光二极管驱动发光二极管15【例8-1】如图8-5所示,P2驱动8个LED灯。当每位引脚输出为0时,LED灯被点亮;引脚输出为1时,LED灯不亮。在此结构图基础上设计一个霹雳灯程序,使得任何时候只有一个LED灯亮。图8-

10、5霹雳灯电路连接8.2.1 8.2.1 驱动发光二极管驱动发光二极管16每次只点亮一个LED,即P2端口在输出时只能有一位为0,其他位为1。设计程序时,可以先使P2端口的值左移7次,左移可采用“LED=1;”实现右移1位,移动后在最高位补1;如此循环即可实现其功能。霹雳灯程序流程如图8-6所示。【例8-1】如图8-5所示,P2驱动8个LED灯。当每位引脚输出为0时,LED灯被点亮;引脚输出为1时,LED灯不亮。在此结构图基础上设计一个霹雳灯程序,使得任何时候只有一个LED灯亮。图8-6霹雳灯程序流程图8.2.1 8.2.1 驱动发光二极管驱动发光二极管17【参考代码】/*/此程序实现LED灯先

11、向左移动,后向右移动,即为霹雳灯/*#include/*程序声明*#defineLEDP2/将P2口定义为LEDvoiddelay(int);/*主程序*main()【例8-1】如图8-5所示,P2驱动8个LED灯。当每位引脚输出为0时,LED灯被点亮;引脚输出为1时,LED灯不亮。在此结构图基础上设计一个霹雳灯程序,使得任何时候只有一个LED灯亮。8.2.1 8.2.1 驱动发光二极管驱动发光二极管18unsignedchari;LED=0 xfe;while(1)for(i=0;i7;i+)/向左移动7次delay(100);LED=(LED1)|0 x01;/向左移动,每移动1次在最低位

12、补1for(i=0;i1)|0 x80;/向右移动,每移动1次在最高位补1/*延时x0.5ms子函数*voiddelay(intx)inti,j;for(i=0;ix;i+)for(j=0;j=60;j+);【例8-1】如图8-5所示,P2驱动8个LED灯。当每位引脚输出为0时,LED灯被点亮;引脚输出为1时,LED灯不亮。在此结构图基础上设计一个霹雳灯程序,使得任何时候只有一个LED灯亮。8.2.2 8.2.2 驱动蜂鸣器驱动蜂鸣器蜂鸣器(buzzer)是一种发声装置,可分为无源蜂鸣器与有源蜂鸣器,如图8-7所示。20图8-7有源(左)与无源(右)蜂鸣器蜂鸣器的“源”不是指电源,而是指震荡源

13、。有源蜂鸣器内部带有震荡源,只要通电就可以鸣叫,所以通常用作报警提示,其优点是程序控制方便。无源蜂鸣器内部不带震荡源,所以直流信号无法令其鸣叫,必须使用1K5K的方波才能驱动它。无源蜂鸣器的优点是声音频率可控,并可做出类似“哆来咪发嗦拉西”的效果。在一些特例中,无源蜂鸣器可以和LED复用一个控制口。8.2.2 8.2.2 驱动蜂鸣器驱动蜂鸣器蜂鸣器的驱动电路如图8-8所示,该电路中三极管基极直接与P1,P2,P3相连,P0与三极管的基极相连时可以在基极接上上拉电阻。21蜂鸣器本质上是一个感性元件,其电流不能瞬变,因此必须有一个续流二极管提供续流,否则在蜂鸣器两端会产生几十伏的尖峰电压,可能损坏

14、三极管,并干扰整个电路系统的其他部分。图8-8蜂鸣器驱动电路8.2.2 8.2.2 驱动蜂鸣器驱动蜂鸣器22使无源蜂鸣器鸣叫的关键是设置合适的方波。方波即先设置一定时间的高电平,再设置同样时长的低电平,这里通过pulse_BZ()函数来实现。【参考代码】/*/此实验用的蜂鸣器为可编程控制的无源蜂鸣器,应要考虑蜂鸣器的工作频率/频率不能过低,过低不会蜂鸣,过高即表现为噪音,频率不同声音效果不同/*声明*#includesbitbuzzer=P10;voiddelay(int);voidpulse_BZ(int,int,int);【例8-2】编程实现无源蜂鸣器的鸣叫。8.2.2 8.2.2 驱动蜂

15、鸣器驱动蜂鸣器23/*主程序*main()while(1)pulse_BZ(100,10,10);/蜂鸣器发声100(5+5)ms=0.5Sdelay(10000);/延时100000.5ms=5S【例8-2】编程实现无源蜂鸣器的鸣叫。8.2.2 8.2.2 驱动蜂鸣器驱动蜂鸣器24/*延时子函数*/*延时函数开始,延时x0.05ms*/voiddelay(intx)inti,j;for(i=0;ix;i+)for(j=1;j=6;j+);【例8-2】编程实现无源蜂鸣器的鸣叫。8.2.2 8.2.2 驱动蜂鸣器驱动蜂鸣器25/*蜂鸣器蜂鸣子函数*/*蜂鸣器发声函数,count=计数次数,TH=

16、高电平时间,TL=低电平时间*/voidpulse_BZ(intcount,intTH,intTL)inti;for(i=0;icount;i+)buzzer=1;/输出高电平delay(TH);/延迟TH0.05msbuzzer=0;/输出低电平delay(TL);/延迟TL0.05ms【例8-2】编程实现无源蜂鸣器的鸣叫。8.2.3 8.2.3 驱动继电器驱动继电器26【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关8次后,蜂鸣器发出两声鸣叫“哔哔”,然后再从头开始执行上述操作。电路连线如图8-9所示。图8-9继电器与蜂鸣器实验电路8.2.3 8.2.3

17、驱动继电器驱动继电器27【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关8次后,蜂鸣器发出两声鸣叫“哔哔”,然后再从头开始执行上述操作。程序流程如图8-10所示。声明变量和函数后,先给P1.1引脚高电平0.5秒,使继电器闭合从而形成通路点亮灯泡;然后给P1.1引脚低电平,熄灭灯泡,持续时间也是0.5秒。如此点亮灯泡8次后,使蜂鸣器鸣叫2次。以上操作不断重复执行即可实现指定的功能。图8-10继电器程序执行流程8.2.3 8.2.3 驱动继电器驱动继电器28【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关8次后,蜂鸣器发出两声鸣叫

18、“哔哔”,然后再从头开始执行上述操作。【参考代码】/*/继电器驱动实验/*#includesbitbuzzer=P10;/声明蜂鸣器接到P1.0引脚sbitrelay=P11;/声明继电器接到P1.1引脚voiddelay(int);/声明延时函数voidpulse_BZ(int,int,int);/声明蜂鸣器函数voidpulse_RL(int,int,int);/声明继电器函数8.2.3 8.2.3 驱动继电器驱动继电器29【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关8次后,蜂鸣器发出两声鸣叫“哔哔”,然后再从头开始执行上述操作。main()while

19、(1)pulse_RL(8,1000,1000);/继电器使灯亮灭各8次,每次10000.5ms=0.5spulse_BZ(100,1,1);/蜂鸣器发第1声delay(200);/延时2000.5ms=100mspulse_BZ(100,1,1);/蜂鸣器发第2声delay(200);8.2.3 8.2.3 驱动继电器驱动继电器30【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关8次后,蜂鸣器发出两声鸣叫“哔哔”,然后再从头开始执行上述操作。/*延时0.5ms子函数*voiddelay(intx)inti,j;for(i=0;ix;i+)for(j=1;j=

20、60;j+);8.2.3 8.2.3 驱动继电器驱动继电器31【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关8次后,蜂鸣器发出两声鸣叫“哔哔”,然后再从头开始执行上述操作。/*蜂鸣器发声函数*voidpulse_BZ(intcount,intTH,intTL)inti;for(i=0;icount;i+)buzzer=1;/输出高电平delay(TH);/延时TH时间buzzer=0;/输出低电平delay(TL);/延时TL时间8.2.3 8.2.3 驱动继电器驱动继电器32【例8-3】使用单片机控制继电器,P1.1控制所连接的继电器,每1S开关一次,开关

21、8次后,蜂鸣器发出两声鸣叫“哔哔”,然后再从头开始执行上述操作。/*继电器子函数*voidpulse_RL(intcount,intTH,intTL)inti;for(i=0;i=count;i+)relay=1;/输出高电平,继电器励磁(灯亮)delay(TH);relay=0;/输出低电平,继电器消磁(灯灭)delay(TL);8.2.4 8.2.4 驱动驱动7 7段段LEDLED数码管数码管33【例8-4】编写程序,驱动共阳极7段数码管依次显示数字09。这里使用单片机的P0口驱动数码管,数码管与单片机的连接见图8-11,程序流程如图8-12所示。图8-117段数码管实验图图8-12程序流

22、程图8.2.4 8.2.4 驱动驱动7 7段段LEDLED数码管数码管34【例8-4】编写程序,驱动共阳极7段数码管依次显示数字09。将数码管的驱动信号放置在数组TAB10中,每取出一个数据,就通过P0口进行输出,这样就能在数码管显示出对应的数字了。【参考代码】/*/驱动7段数码管依次显示数字09/*#include#defineSEGP0/*声明7段数码管09驱动信号(共阳)*charTAB10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x83,0 xf8,0 x80,0 x98;voiddelay(int);8.2.4 8.2.4 驱动驱动7 7段段LED

23、LED数码管数码管35【例8-4】编写程序,驱动共阳极7段数码管依次显示数字09。/*主函数*main()unsignedchari;while(1)for(i=0;i10;i+)SEG=TABi;delay(500);8.2.4 8.2.4 驱动驱动7 7段段LEDLED数码管数码管36【例8-4】编写程序,驱动共阳极7段数码管依次显示数字09。/*延时函数*voiddelay(intx)inti,j;for(i=0;ix;i+)for(j=1;j=150;j+);IO口的C语言编程目 录8.2 I/O输出口应用及编程8.1 单片机的I/O口内部结构8.3 I/O输入口应用及编程378.3

24、8.3 I/OI/O输入口应用及编程输入口应用及编程8.3.1输入设备8.3.2输入电路设计8.3.3抖动与防抖动8.3.4输入设备编程应用388.3 8.3 I/OI/O输入口应用及编程输入口应用及编程单片机的I/O口既可以输出数据,也可以输入数据。P0口用于输出时,需要外接10K的上拉电阻,以确保输出数据的可靠性;若用于输入,则使用时需要先向该口赋值1。398.3.1 8.3.1 输入设备输入设备对于数字电子电路而言,最基本的输入设备是开关。开关按其结构可以分为按钮开关和闸刀开关两类。按钮开关通常用于产生边缘触发的场合,每按一次产生一个脉冲;而闸刀开关主要用于电平触发的场合。1按钮开关(B

25、utton)按钮开关的特点是具有自动恢复(回弹)功能。常 见 的 按 钮 开 关 是 轻 触 开 关,如 图 8-13(a)所示。按下按钮时开关接通,放开按钮时开关断开,其内部结构如图8-13(b)所示。40如图8-13所示,按钮开关有4个引脚,引脚1与引脚4连通、引脚2与引脚3连通。按钮按下时,内部开关a接通;松开按钮,a自动弹起,开关断开。电子电路或微型计算机所使用的按钮开关有6mm,8mm,10mm,12mm等尺寸。(a)轻触开关实物(b)轻触开关内部电路结构图8-13轻触开关实物及其内部电路结构8.3.1 8.3.1 输入设备输入设备 2闸刀开关(Knife Switch)这类开关具有

26、保持功能,将开关拨动到ON时,内部的开关接通形成通路,若要断开通路,则需要再次拨动开关。比较典型的闸刀开关是指拨开关(DIPswitch),如图8-14所示。指拨开关内部相当于含有若干个独立的开关。当电路板上不需要经常切换状态时可以利用短路帽进行替代。说 明41(a)指拨开关实物(b)指拨/闸刀开关电路符号图8-14指拨开关实物与电路符号8.3.2 8.3.2 输入电路设计输入电路设计设计数字电路或含有微控制器的输入电路时,输入端不能含有不确定的状态,即输入端不可留空,否则除了会产生不确定的状态外,还可能感染噪声,使电路产生误动作。1按钮开关的输入电路设计将按钮开关接入输入端时,需要连接一个电

27、阻再接到VCC或GND上,如图8-15所示。42图8-15按钮开关作为输入元件P0.7引脚连接的按钮开关初始状态为开路状态,该开关与一个10KW的电阻串联后连接到VCC上,此时输入引脚保持为高电平。按下按钮开关时,输入引脚变为低电平;放开开关时,输入引脚恢复为高电平,这样就产生了一个负脉冲。8.3.2 8.3.2 输入电路设计输入电路设计设计数字电路或含有微控制器的输入电路时,输入端不能含有不确定的状态,即输入端不可留空,否则除了会产生不确定的状态外,还可能感染噪声,使电路产生误动作。1按钮开关的输入电路设计将按钮开关接入输入端时,需要连接一个电阻再接到VCC或GND上,如图8-15所示。43

28、图8-15按钮开关作为输入元件P0.5引脚连接的按钮开关初始状态为开路状态,开关与一个470W的电阻相接后接地,此时输入引脚为低电平。按下按钮开关时,引脚经开关连接上VCC,输入引脚变为高电平;放开开关时,输入引脚将恢复为低电平,这样就产生了一个正脉冲。8.3.2 8.3.2 输入电路设计输入电路设计 2闸刀开关的输入电路设计将闸刀开关接到输入端时,通常也会接一个上拉电阻到VCC或接一个下拉电阻到GND,如图8-16所示。闸刀开关作为输入设备使用时,其工作原理类似于按钮开关。但闸刀开关两种状态的切换需要手动完成,即拨动开关一次能够完成一次切换,再次拨动才能恢复开关原状。44图8-16闸刀开关作

29、为输入元件8.3.3 8.3.3 抖动与防抖动抖动与防抖动不管是按钮开关还是闸刀开关,在操作时,信号的高低电平切换并不如想象中的理想。实际应用中,开关操作在很多情况下会产生不确定状态,这种状态将产生噪声信号,因而需要及时进行去干扰处理。1抖动现象如图8-17所示,图的上半部分为开关按下和松开时的实际状态,下半部分为理想状态。在实际应用中,按键按下和松开都将产生抖动,同时也会产生干扰信号,这种干扰信号对数字电路的影响很大,往往会导致计数的错误。451020ms抖动1020ms抖动理想状态实际状态图8-17开关的实际状态与理想状态8.3.3 8.3.3 抖动与防抖动抖动与防抖动 2硬件防抖动要避免

30、按键抖动,可以用一个切换开关及互锁电路组成一个防抖动电路(debouncer),如图8-18所示。这个电路虽然可以降低抖动所产生的噪声,但它所需要的元件较多,且将占用电路的PCB板空间,这样就增加了成本与电路的复杂程度。46图8-18互锁防抖动电路8.3.3 8.3.3 抖动与防抖动抖动与防抖动除了上述电路外,也可以利用RC元件来设计一个防抖动的滤波电路,如图8-19所示。放开按钮开关时,开关通路被断开,电容开始充电;而开关被按下时,电容被短路,此时电容开始放电。电容在开关抖动期间处于充电或放电状态,这期间电容始终保持为低电平,并不随抖动而发生变化;抖动过后,电容两端的电压才稳定上升,这样就避

31、开了抖动的时间段。这种电路结构简单,是一种常用的防抖动电路。47图8-19RC防抖动电路8.3.3 8.3.3 抖动与防抖动抖动与防抖动 3软件防抖动利用硬件防抖动电路会增加硬件设计的成本与复杂度,故有时也利用软件来防抖动。只要避开按键按下时产生抖动的20ms,即可达到防抖动的目的。因而在按下按钮开关的瞬间,立刻执行debouncer()防抖动函数,这样就避开了产生抖动的时间段。而debouncer()防抖动函数只是一个延时函数(总延时为20ms),其代码如下所示。voiddebouncer(void)inti;/声明变量for(i=0;i2400;i+);/计数2400次来达到延时目的488

32、.3.4 8.3.4 输入设备编程应用输入设备编程应用【例8-5】如图8-20所示,编程实现以下功能:若P0.0所连接的LED不亮,按一下PB1,则LED亮;再按一下PB1,则LED不亮,如此循环。49图8-20按钮切换式控制实验8.3.4 8.3.4 输入设备编程应用输入设备编程应用实现该功能的程序流程如图8-21所示。初始化时先关闭LED,然后判断PB1是否按下,如果按下,则先调用防抖动函数,再切换LED的状态。【例8-5】如图8-20所示,编程实现以下功能:若P0.0所连接的LED不亮,按一下PB1,则LED亮;再按一下PB1,则LED不亮,如此循环。50图8-21按钮切换式控制程序流程

33、8.3.4 8.3.4 输入设备编程应用输入设备编程应用【参考代码】/*/按钮切换式控制实验:若原本P0.0所连接的LED不亮,按一下PB1/则LED灯亮,再按一下PB1,则LED不亮,依次循环工作/*#includesbitPB1=P20;/声明PB1接到P2.0引脚sbitLED=P00;/声明LED接到P0.0引脚voiddebouncer(void);/声明防抖动函数/=主程序=【例8-5】如图8-20所示,编程实现以下功能:若P0.0所连接的LED不亮,按一下PB1,则LED亮;再按一下PB1,则LED不亮,如此循环。518.3.4 8.3.4 输入设备编程应用输入设备编程应用mai

34、n()LED=1;/关闭LEDP2=0 xff;/将P2口设置为输入口while(1)if(PB1=0)/判断按键是否按下debouncer();/进行按键防抖动LED=!LED;/切换LED为反相【例8-5】如图8-20所示,编程实现以下功能:若P0.0所连接的LED不亮,按一下PB1,则LED亮;再按一下PB1,则LED不亮,如此循环。528.3.4 8.3.4 输入设备编程应用输入设备编程应用/=延时20ms防抖动子程序=/*防抖动函数,延时约20ms*/voiddebouncer(void)inti;/声明整数变量ifor(i=0;i2400;i+);【例8-5】如图8-20所示,编程

35、实现以下功能:若P0.0所连接的LED不亮,按一下PB1,则LED亮;再按一下PB1,则LED不亮,如此循环。538.3.4 8.3.4 输入设备编程应用输入设备编程应用Q Q【思考题】在上述过程中,改变debouncer()函数的时间长短会有什么影响?若按住PB1不放会怎么样?如何改善?548.3.4 8.3.4 输入设备编程应用输入设备编程应用如图8-22(下页)所示,P0口通过限流电阻连接至共阳极7段LED数码管,P2.0连接按钮开关PB1,PB2.1连接PB2,其中PB1具有增数功能,PB2具有减数功能。编程实现如下功能:7段LED数码管最初显示为0,按一下PB1后,数码管显示1;再按

36、一下PB1,数码管显示2数码管显示9时,再按下PB1,重新显示数字0。若7段LED数码管显示数字n(n9),按一下PB2,数码管显示n1;再按一次PB2,数码管显示n2依此类推。先将09这10个数字的驱动信号放入字符数组中,然后判断PB1是否为0,若PB1被按下,则显示下一个数字,若显示数字9,按下PB1则重新显示数字0;如果按下PB2,则显示上一个数字,若当前显示的是数字0,按下PB2后重新显示数字9。程序流程如图8-23(下下页)所示。【例8-6】558.3.4 8.3.4 输入设备编程应用输入设备编程应用【例8-6】56图8-22按键控制7段LED数码显示8.3.4 8.3.4 输入设备

37、编程应用输入设备编程应用【例8-6】57图8-23按钮开关控制7段LED数码管8.3.4 8.3.4 输入设备编程应用输入设备编程应用【参考代码】/*/两个按钮开关控制7段LED数码管进行加减数显示/功能:P2.0连接PB1,P2.1连接PB2,PB1具有增数功能,PB2具有减数功能/*#include#defineSEGP0/将P0口连接至7段LED数码管/*声明7段LED数码管驱动信号数组(共阳极)*/charTAB10=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x83,0 xf8,0 x80,0 x98;/0123456789voiddebouncer(

38、void);/声明防抖动函数sbitPB1=P20;/声明按钮1与P2.0相连sbitPB2=P21;/声明按钮2与P2.1相连【例8-6】588.3.4 8.3.4 输入设备编程应用输入设备编程应用/=主程序=main()unsignedchari=0;PB1=PB2=1;/设置为输入口while(1)SEG=TABi;/输出数字到7段LED数码管if(PB1=0)/判断PB1是否按下debouncer();/调用防抖动函数i=(i9)?i+1:0;/若i=9清除为0【例8-6】598.3.4 8.3.4 输入设备编程应用输入设备编程应用if(PB2=0)/判断PB2是否按下debounce

39、r();/调用防抖动函数i=(i0)?i-1:9;/若i0则i=i-1,i=0则从9开始继续显示/=延时防抖动子程序=voiddebouncer(void)inti;for(i=0;i2400;i+);/单片机晶振12MHz,计数2400次,延时20ms【例8-6】608.3.4 8.3.4 输入设备编程应用输入设备编程应用如图8-24所示,P0口经限流电阻连接8个LED灯,P2口的低四位各连接一个开关,每个输入/输出端口上都连接了一个10K的上拉电阻使其保持高电平。【例8-7】61图8-24多重按钮开关实验电路8.3.4 8.3.4 输入设备编程应用输入设备编程应用按一下PB1按钮,前4个L

40、ED(D1D4)和后4个LED(D5D8)交互点亮3次(即前4个LED亮、后4个LED不亮;0.5s后,切换为前4个LED不亮、后4个LED亮;如此循环3次),然后8个LED闪烁3次(每闪烁一次为全亮0.5s、全暗0.5s)。按一下PB2按钮,单灯左移(先点亮最右侧LED,点亮的LED逐步向左移动一位,直至点亮最左侧的LED,这个过程为1圈)3圈,然后8个LED闪烁3次。按一下PB3按钮,单灯右移(先点亮最左侧LED,点亮的LED逐步向右移动一位,直至点亮最右侧的LED,这个过程为1圈)3圈,然后8个LED闪烁3次。按一下PB4按钮,点亮霹雳灯(单灯先左移1圈,再右移1圈)3圈,然后8个LED

41、闪烁3次。【例8-7】编程实现如下功能:628.3.4 8.3.4 输入设备编程应用输入设备编程应用根据功能需求,对不同的功能编写不同的函数,如防抖动函数、交互闪烁函数、单灯左移函数、单灯右移函数、霹雳灯函数、闪烁函数及延迟函数等。利用条件判断语句来判断PB1,PB2,PB3,PB4按钮是否被按下,再根据按钮的不同状态,调用不同的函数,以实现相应的功能。由于函数较多,且大都在前面的操作过程中使用过,在此将所有函数放在头文件myio.h中,这样整个程序的结构比较清楚。本例将分别用if-else结构和switch结构来说明按钮的优先等级问题。【例8-7】638.3.4 8.3.4 输入设备编程应用

42、输入设备编程应用(1)采用if-else结构,程序流程如图8-25所示。依次判断各开关的状态,选择执行不同的操作。【例8-7】64图8-25if-else结构实现多重按钮开关流程8.3.4 8.3.4 输入设备编程应用输入设备编程应用【参考代码】myio.h头文件。/*/此头文件包含:防抖动函数、交互闪烁函数、单灯左移函数、单灯右移函数/霹雳函数、闪烁函数、延时函数/*#defineLEDP0/将LED连接到P0口voiddebouncer(void);/声明防抖动函数voiddelay10ms(int);/声明10ms延迟函数voidalter(int);/声明交互闪烁函数voidleft(

43、int);/声明单灯左移函数voidright(int);/声明单灯右移函数voidpili(int);/声明霹雳灯函数voidflash(int);/声明闪烁函数【例8-7】(1)采用if-else结构658.3.4 8.3.4 输入设备编程应用输入设备编程应用/=防抖动函数,延迟约20ms=voiddebouncer(void)inti;for(i=0;i2400;i+);/计数2400次,延迟约20ms/=延迟10*xms函数=voiddelay10ms(intx)inti,j;for(i=0;ix;i+)for(j=1;j=1200;j+);/计数1200次,延迟约10ms【例8-7】

44、(1)采用if-else结构668.3.4 8.3.4 输入设备编程应用输入设备编程应用/=高低位交互闪烁函数,执行x次=voidalter(intx)inti;LED=0 x0f;/初始化状态(高位亮,低位灭)for(i=0;i2*x-1;i+)/i变量for循环执行2x-1次delay10ms(50);/延迟5010ms=0.5sLED=LED;/LED反相输出delay10ms(50);【例8-7】(1)采用if-else结构678.3.4 8.3.4 输入设备编程应用输入设备编程应用/=全灯闪烁函数,执行x次=voidflash(intx)inti;/声明变量iLED=0 x00;/初

45、始化状态(全亮)for(i=0;i2*x-1;i+)/i变量for循环执行2x-1次delay10ms(50);LED=LED;/P0口反相输出delay10ms(50);【例8-7】(1)采用if-else结构688.3.4 8.3.4 输入设备编程应用输入设备编程应用/=单灯左移函数,执行x圈=voidleft(intx)inti,j;for(i=0;ix;i+)/i循环,执行x圈LED=0 xfe;/初始化状态=11111110for(j=0;j7;j+)/j循环,左移7次delay10ms(25);/延迟2510ms=0.25sLED=(LED1)|0 x01;/左移1位后,LSB设为

46、1delay10ms(25);/延迟0.25s【例8-7】(1)采用if-else结构698.3.4 8.3.4 输入设备编程应用输入设备编程应用/=单灯右移函数,执行x圈=voidright(intx)inti,j;/声明变量i,jfor(i=0;ix;i+)/i循环,执行x圈LED=0 x7f;/初始化状态=01111111for(j=0;j1)|0 x80;/左移1位后,MSB设为1delay10ms(25);/延迟2510ms=0.25ms【例8-7】(1)采用if-else结构708.3.4 8.3.4 输入设备编程应用输入设备编程应用/=霹雳灯函数,执行x圈=voidpili(in

47、tx)/霹雳灯函数开始inti;/声明变量ifor(i=0;ix;i+)/i循环,执行x圈left(1);/单灯左移一圈right(1);/单灯右移一圈【例8-7】(1)采用if-else结构718.3.4 8.3.4 输入设备编程应用输入设备编程应用主程序main.c文件。/=声明=#include#includemyio.hsbitPB1=P20;/声明PB1sbitPB2=P21;/声明PB2sbitPB3=P22;/声明PB3sbitPB4=P23;/声明PB4/=主程序=【例8-7】(1)采用if-else结构728.3.4 8.3.4 输入设备编程应用输入设备编程应用main()L

48、ED=0 xff;/初始化状态(LED全灭)P2=0 xff;/设计P2输入口while(1)if(PB1=0)/如果按下PB1debouncer();/防抖动函数alter(3);/高低位交互闪烁3次flash(3);/全灯闪烁3次【例8-7】(1)采用if-else结构738.3.4 8.3.4 输入设备编程应用输入设备编程应用elseif(PB2=0)/如果按下PB2debouncer();/防抖动函数left(3);/单灯左移3圈flash(3);/全灯闪烁3次elseif(PB3=0)/如果按下PB3debouncer();/防抖动函数right(3);/单灯右移3次flash(3)

49、;/全灯闪烁3次【例8-7】(1)采用if-else结构748.3.4 8.3.4 输入设备编程应用输入设备编程应用elseif(PB4=0)/如果按下PB4debouncer();/防抖动函数pili(3);/霹雳灯3圈flash(3);/全灯闪烁3次【例8-7】(1)采用if-else结构758.3.4 8.3.4 输入设备编程应用输入设备编程应用Q Q【思考题】在本例中,若同时按下多个按钮会如何?在本例中,若按住按钮不放会如何?可否用delay10ms()函数替代debouncer()函数?768.3.4 8.3.4 输入设备编程应用输入设备编程应用(2)采用switch结构,程序流程如

50、图8-26所示。【例8-7】77图8-26switch结构实现多重按钮开关流程8.3.4 8.3.4 输入设备编程应用输入设备编程应用在前面的程序中,各按钮之间是有优先级的,PB1具有最高优先级,其次是PB2,PB3和PB4。若要改成无优先权的选择结构,可使用switch语句来取代if-else语句。【参考代码】其中myio.h源代码见程序8.7。/*/多重按钮开关(switch语句实现)/*/=声明=#include#includemyio.h#definePBP2/定义按钮开关合接至P2口【例8-7】(2)采用switch结构788.3.4 8.3.4 输入设备编程应用输入设备编程应用/=

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > 工作计划

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com