c51 在6联c51数码管电路上左移或右移循环显示学号+图纸

单片机作业单只数码管循环显示0~9_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
单片机作业单只数码管循环显示0~9
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
还剩7页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢用C语言编程使51单片机的数码管左移循环显示
我的图书馆
用C语言编程使51单片机的数码管左移循环显示
用C语言编程使51单片机的数码管左移循环显示
高手支招:请问用C语言编程使51单片机的数码管左移循环显示0-7的程序怎么编呀由于我不懂得用中断和定时,请程序里不要用那两个函数,谢谢(*^__^*) 嘻嘻…… 悬赏分:0 - 解决时间: 18:09 问题补充:这个是我自己编的,可是运行起来就是不移动,麻烦你们帮修改一下,我没有编左移循环部分的程序。//==========================================================最佳答案:在楼主的程序基础上,增加显示数码移位的功能,程序如下://---------------------------------------------------#include &REG51.H& #define uint unsigned int #define uchar unsigned charuchar code DIS_SEG7[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};uchar code DIS_BIT[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//---------------------------------------------------void delay1ms(uint i) { while(i--) for(j = 0; j & 125; j++);} //---------------------------------------------------void main(void) { uchar cnt,uchar DISP[] = {0, 1, 2, 3, 4, 5, 6, 7};while(1) { for(ttt = 0; ttt & 100; ttt++) for(cnt = 0; cnt & 8; cnt++) { //点亮数码管0-7 P2 = 0;P0 = DIS_SEG7[DISP[cnt]];P2 = ~DIS_BIT[cnt];delay1ms(1);}//-------------------以上显示800ms,下面更新显示内容ttt = DISP[0];DISP[0] = DISP[1];DISP[1] = DISP[2];DISP[2] = DISP[3];DISP[3] = DISP[4];DISP[4] = DISP[5];DISP[5] = DISP[6];DISP[6] = DISP[7];DISP[7] =} } //---------------------------------------------------程序运行截图如下:
图片链接://==========================================================提问者对于答案的评价:非常感谢您,运行得了····thankyou(*^__^*) 原题网址://---------------------------------------------------
馆藏&130665
TA的推荐TA的最新馆藏[转]&[转]&[转]&[转]&
喜欢该文的人也喜欢595级联通过uln2803点亮数码管
[问题点数:40分,结帖人u]
595级联通过uln2803点亮数码管
[问题点数:40分,结帖人u]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2013年1月 硬件/嵌入开发大版内专家分月排行榜第一2012年10月 硬件/嵌入开发大版内专家分月排行榜第一2012年9月 硬件/嵌入开发大版内专家分月排行榜第一2012年8月 硬件/嵌入开发大版内专家分月排行榜第一2012年7月 硬件/嵌入开发大版内专家分月排行榜第一2012年6月 硬件/嵌入开发大版内专家分月排行榜第一2012年5月 硬件/嵌入开发大版内专家分月排行榜第一2012年4月 硬件/嵌入开发大版内专家分月排行榜第一2012年3月 硬件/嵌入开发大版内专家分月排行榜第一2012年2月 硬件/嵌入开发大版内专家分月排行榜第一2012年1月 硬件/嵌入开发大版内专家分月排行榜第一2011年11月 硬件/嵌入开发大版内专家分月排行榜第一2011年10月 硬件/嵌入开发大版内专家分月排行榜第一2011年9月 硬件/嵌入开发大版内专家分月排行榜第一
2014年10月 硬件/嵌入开发大版内专家分月排行榜第二2014年2月 硬件/嵌入开发大版内专家分月排行榜第二2013年10月 硬件/嵌入开发大版内专家分月排行榜第二2013年8月 硬件/嵌入开发大版内专家分月排行榜第二2013年3月 硬件/嵌入开发大版内专家分月排行榜第二2012年12月 硬件/嵌入开发大版内专家分月排行榜第二2012年11月 硬件/嵌入开发大版内专家分月排行榜第二2011年12月 硬件/嵌入开发大版内专家分月排行榜第二
2013年1月 硬件/嵌入开发大版内专家分月排行榜第一2012年10月 硬件/嵌入开发大版内专家分月排行榜第一2012年9月 硬件/嵌入开发大版内专家分月排行榜第一2012年8月 硬件/嵌入开发大版内专家分月排行榜第一2012年7月 硬件/嵌入开发大版内专家分月排行榜第一2012年6月 硬件/嵌入开发大版内专家分月排行榜第一2012年5月 硬件/嵌入开发大版内专家分月排行榜第一2012年4月 硬件/嵌入开发大版内专家分月排行榜第一2012年3月 硬件/嵌入开发大版内专家分月排行榜第一2012年2月 硬件/嵌入开发大版内专家分月排行榜第一2012年1月 硬件/嵌入开发大版内专家分月排行榜第一2011年11月 硬件/嵌入开发大版内专家分月排行榜第一2011年10月 硬件/嵌入开发大版内专家分月排行榜第一2011年9月 硬件/嵌入开发大版内专家分月排行榜第一
2014年10月 硬件/嵌入开发大版内专家分月排行榜第二2014年2月 硬件/嵌入开发大版内专家分月排行榜第二2013年10月 硬件/嵌入开发大版内专家分月排行榜第二2013年8月 硬件/嵌入开发大版内专家分月排行榜第二2013年3月 硬件/嵌入开发大版内专家分月排行榜第二2012年12月 硬件/嵌入开发大版内专家分月排行榜第二2012年11月 硬件/嵌入开发大版内专家分月排行榜第二2011年12月 硬件/嵌入开发大版内专家分月排行榜第二
匿名用户不能发表回复!|赞助商链接
当前位置: >>
51单片机最小系统板实验指导书
单片机实验板工 程 训 练 指 导 书物理与电子工程系 2005 年 10 月1 目实验一 实验二 实验三 实验四 实验五 实验六 实验七 实验八 实验九 实验十 实验十一 实验十二 实 验十三 实验十四 实验十五 实验十六 实验十七 实验十八 实验十九 实验二十录LED 闪烁灯设计-------------------------------------------------4 模拟开关控制指示灯设计---------------------------------------------7 多路开关状态指示设计---------------------------------------――――10 广告灯左、右移设计--------------------------------------- 14 查询法设计广告灯---------------------------------18 报警产生器设计---------------------------------------------21 I/O 并行口直接驱动 LED 显示设计-----------------------------――25 单键识别设计--------------------------------------- ―――29 一键多功能按键识别设计--------------------------------- 33 00-99 计数器设计-------------------------------- ――――38 六十秒计时器设计------------------------――――――――――42 可预置可逆 4 位计数器设计-----------------------------------46 动 态数码显 示设计 - -- -- -- - - - --- - -- - -- -- -- - -- -- - --- - -- - -- - 5 1 4 × 4 矩 阵式 键 盘 识 别 设 计 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 5 定 时 计 数 器 T 0 作 定 时 应 用 设 计( 一 ) - - - - - - - - - - - - - - - - - - - - - - 6 4 定时计数器 T0 作定时应用设计(二)――----------------------71 9.9 秒跑马表设计------------------------------------------ 76 “嘀、嘀、??”报警声设计--------------------------------- 82 “叮咚”门铃设计-------------------------------------------87 智能电子钟设计---------------------------------------------92实验二十一 “新年好”音乐设计-----------------------------------------------102 实验二十二 电子琴设计-------------------------------------------------108 实验二十三 模 拟 计 算 器 数 字 输 入 及 显 示 设 计 - - - - - - - - - - - - - - - - - - - - - - - - - 1 1 9 实验二十四 数字电压表设计--------------------――-------------------------126 实验二十五 DS18B20 数字温度计设计---------------------------------131 附录 A 实验板中模拟/数字转换器 ADC0804 的参数及使用说明------------------------139 附录 B 实验板中 DS18B20 智能温度控制器的参数及使用----------------------------1412 单片机实验板详细说明该单片机实验板设计巧妙,经过了严格的检查,可放心使用。 由于考虑到众多的实验要在此单片机实验板上完成,然而每个实验用到的单片机的 I/O 口不尽相同,所以设计时采用拨动拨码开关和替换跳线帽的位置来完成每个实验内容。 在完成各个实验内容时, 首先要看清楚实验电路原理图, 然后按照实验内容给出的单片 机实验板上的硬件连线、 拨动拨码开关或替换跳线帽的位置来完成系统设计。 检查无误后下 载程序。由于每个程序都经过了单片机实验板的验证,证明程序没有问题。所以要是调不出 来,肯定是硬件没有连好,再次检查直到完成实验。每做完一个实验后,把拨动拨码开关和 跳线帽恢复到初始状态。 一、拨码开关和跳线帽的初始化状态介绍如下: 单片机实验板上有 8 联拨动拨码开关 4 个(JP1、JP2、JP3、JP4),2 联拨动拨码开关 1 个(JP5),跳线帽 13 个。 在初始化状态下,拨动拨码开关都处于紧靠数字的位置,此 位置下的拨动拨码开关为不用状态。8 排针接插件 J3 上的 8 个跳线帽要全部连接在标号为 P0 位置上。单排针接插件 J4 上的跳线帽要连接在 OE 和 GND 的位置上。单排针接插件 J5 上 的跳线帽连接在 OE 和 GND 的位置上。单排针接插件 J6 上的跳线帽要连接在 OE 和 VCC 的位 置。单排针接插件 J7 上的跳线帽要连接在 CS 和 GND 的位置。双排针接插件 J8 上的跳线帽 应该和 J8 上排插针相连。4 个 8 联拨动拨码开关(JP1、JP2、JP3、JP4)应该全部所至下 方。 二、实验中具体使用介绍如下: (1)当用到发光二极管时,要把 8 联拨动拨码开关 JP4 拨到 ON 状态。 (2)当用到喇叭输出时,把 2 联拨动拨码开关 JP5 的 1 号拨动开关拨上去; 当用 DS18B20 做测温时,把 2 联拨动拨码开关 JP5 的 2 号拨动开关拨上去。 (3)当用到矩阵键盘输入时,把 8 联拨动拨码开关 JP3 的拨动开关全部拨上去。 (4) 当用到拨动开关 SW1―SW4 时, 8 联拨动拨码开关 JP2 对应的拨动开关拨上去。 把 (5) 当用到按键开关 S18―S21 时, 8 联拨动拨码开关 JP2 对应的拨动开关拨上去。 把 (6) 当用 8 个动态数码管显示时, 首先应该把单排针接插件 J4 的 OE 与 VCC 用跳线帽 相连。 同时 8 联拨动拨码开关 JP1 对应的拨动开关拨上去。 联拨动拨码开关 JP1 的 S1―S8 8 分别对应三极管 Q2―Q9。 (7)当用 8 个动态数码管输入 a―h 数码时,如果用到 P0 口,不用移动跳线帽;如果 用到 P1 口,把 8 个跳线帽移到下面的标有 P1 的位置。 (8) 当用 P0 口做数码管静态显示时, 把单排针接插件 J5 的 OE 与 VCC 用跳线帽相连。 (9) 当用 P2 口做数码管静态显示时, 把单排针接插件 J6 的 OE 与 GND 用跳线帽相连。 总之,在用单片机编写简单程序时,汇编语言编写起来比较简单,但复杂的程序还是用 C51 编写起来比较简单。所以 C51 编程是必学的。这里基本上所有的实验程序都采用汇编和 C51 两种编程方法。有的实验还给出了两套设计方案,便于比较学习。3 实验一一、实验目的LED 闪烁灯设计1、初步了解单片机 I/O 口的简单控制。 2、掌握单片机外围常用电路的固定接法。 二、设计原理 利用单片机控制一个发光二极管,使此发光二极管间隔 0.2 秒亮、灭一次。 三、参考电路图 1.1 LED 闪烁灯外部电路原理图 四、电路硬件说明 如图 1.1 所示:在单片机的 P1.0 端口上通过 8 联拨动拨码开关 JP4 的相应拨码开关连 接一个发光二极管 D1。 五、程序设计内容 (1) 延时程序的设计方法 : 单片机指令的执行时间是很短的,它的数量级为微秒级。在本程序设计中,要求 LED 闪烁灯的闪烁时间间隔为 0.2 秒。相对于微秒来说,相差太大,所以在执行某一指令时,需 要插入延时程序, 来达到的要求。 然而这样的延时程序是如何设计呢?下面具体介绍其原理: 如图 1.1 所示,单片机所用的石英晶体为 12MHz。因此,1 个机器周期为 1 微秒。 延时 10ms 子程序 机器周期 微秒 MOV R6,#20 1个 1 D1: MOV R7,#248 1个 1+1×20 DJNZ R7,$ 2个 2×248+2×20×2484 DJNZ R6,D1 2个 2×20 因此,上面的延时程序时间为 10.478ms。 由以上可知,当 R6=10、R7=248 时,延时时间为 5ms;R6=20、R7=248 时,延时时 间为 10ms。通常所用延时时间以此为基本的计时单位。比如本实验要求为 0.2 秒=200ms, 所以用 10ms×R5=200ms,得到 R5=20。延时子程序如下: DELAY: MOV R5,#20 1 D1: MOV R6,#20 1+20 D2: MOV R7,#248 1+20+20(1+20) DJNZ R7,$ 2×248+20×2×248+20(2×248+20×2×248) DJNZ R6,D2 2×20+2×20×20 DJNZ R5,D1 2×20 RET 2 上面的延时程序为 0.220081s。 (2)单片机的 P1.0 端口的输出控制方法: 如图 1.1 所示,根据发光二极管的单向导电性,当单片机的 P1.0 端口输出高电平,即 P1.0=1 时,发光二极管 D1 熄灭;当单片机的 P1.0 端口输出低电平,即 P1.0=0 时,发光 二极管 D1 亮。 可以使用 SETB P1.0 指令使单片机的 P1.0 端口输出高电平, 使用 CLR P1.0 指令使单片机的 P1.0 端口输出低电平。 六、程序流程图(如图 1.2 所示)图 1.2 LED 闪烁灯设计流程图 七、汇编源程序 ORG LJMP ORG RETI ORG RETI 0000H START BH ;系统复位 ;转入主程序 ;外部中断 0 ;中断返回 ;定时器 0 溢出中断5 START:DELAY200MS: D1: D2:ORG RETI ORG RETI ORG RETI ORG CLR LCALL SETB LCALL LJMP MOV MOV MOV DJNZ DJNZ DJNZ RET ENDBH H P1.0 DELAY200MS P1.0 DELAY200MS START R5,#20 R6,#20 R7,#248 R7,$ R6,D2 R5,D1;外部中断 1 ;定时器 1 溢出中断 ;外部中断 2;和 P1.0 口接的二极管亮 ;延时 0.2 秒 ;和 P1.0 口接的二极管灭 ;延时 0.2 秒 ;循环 ;延时子程序八、C 语言源程序 #include &AT89X51.H& sbit L1=P1^0; void delay02s(void) //延时子程序// { unsigned char i,j,k; for(i=20;i&0;i--) for(j=20;j&0;j--) for(k=248;k&0;k--); } void main(void) //主程序// { while(1) //进入循环// { L1=0; //指示灯亮// delay02s(); //延时 0.2 秒// L1=1; //指示灯灭// delay02s(); //延时 0.2 秒// } } 九、注意事项 (1)用 Keil 软件时,注意中文说明及注释。 (2) 用汇编语言编写程序时不区分大小写,但用 C 语言编写程序时注意区分大小写。 (3)汇编语言和 C 语言定义口的方式不同,如汇编语言为 P1.0,P2.0,P3.0,而 C 语 言为 P1_0 ,P2_0 ,P3_0。6 实验二 模拟开关控制指示灯设计一、实验目的 1、掌握单片机外围常用电路的固定接法。 2、掌握单片机利用模拟开关控制指示灯的简单设计。 二、设计原理 如图 2.1 所示,用发光二极管监视模拟开关的状态。如果模拟开关合上,发光二极管点 亮;如果模拟开关打开,发光二极管熄灭。 三、参考电路图 2.1 模拟开关控制指示灯原理图 四、电路硬件说明 如图 2.1 所示,模拟开关 SW1 通过 8 联拨动拨码开关连接在单片机的 P3.0 端口上,用 发光二极管 D1(通过 8 联拨动拨码开关接在单片机的 P1.0 端口上)显示模拟开关 SW1 的状 态。当模拟开关 SW1 断开时,单片机的 P3.0 端口为高电平;当模拟开关闭合时,单片机的 P3.0 端口为低电平。 五、程序设计内容 (1)开关状态的检测过程 对于单片机来说,开关状态的检测是从单片机的 P3.0 端口输入信号,然而输入的信号 只有高、低电平两种。当拨动开关 SW1 拨上去(输入高电平)时,拨动开关 SW1 断开;当拨 动开关 SW1 拨下来(输入低电平)时,拨动开关 SW1 闭合。单片机可以采用 JB BIT 或者 JNB BIT 指令来完成对拨动开关状态的检测。 (2)输出控制7 如图 2.1 所示,当单片机的 P1.0 端口输出为高电平,即 P1.0=1 时,根据发光二极管 的单向导电性可知, 这时发光二极管 D1 熄灭; 当单片机的 P1.0 端口输出为低电平, P1.0 即 =0 时,发光二极管 D1 亮。可以使用 SETB P1.0 指令使单片机的 P1.0 端口输出高电平, 使用 CLR P1.0 指令使单片机 P1.0 端口输出低电平。 六、程序流程图(如图 2.2 所示)图 2.2 模拟开关控制指示灯程序流程图 七、汇编源程序 ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI ORG RETI ORG RETI ORG JB CLR SJMP SETB SJMP END 0000H START BH BH BH 0100H P3.0,NEX P1.0 START P1.0 START ;程序复位入口地址 ;跳到主程序 ;外部中断 0 入口地址 ;中断返回 ;定时器中断 0 入口地址 ;中断返回 ;外部中断 1 入口地址 ;中断返回 ;定时器中断 1 入口地址 ;中断返回 ;串行口中断入口地址 ;中断返回 ;定时器中断 2 入口地址 ;中断返回 ;P3.0 为 1,则跳 NEX ;P1.0 亮 ;P1.0 灭START:NEX:八、C 语言源程序8 #include &AT89X51.H& main() { if(P3_0==1) { P1_0=0; //P1_0 亮// } else { P1_0=1; //P1_0 灭// } } 九、注意事项 如果程序下载到实验板上后,要把 8 联拨动拨码开关 JP2 和 JP4 的相应开关合上去。9 实验三 多路开关状态指示设计一、实验目的 利用多路模拟开关进行指示灯控制。 二、设计原理 如图 3.1 所示,单片机的 P1.0-P1.3 端口通过 8 联拨动拨码开关连接四个发光二极管 D1-D4。单片机的 P3.0-P3.3 端口通过 8 联拨动拨码开关连接四个拨动开关 SW1-SW4。编 程时将拨动开关的状态反映到发光二极管上(开关闭合,对应的灯亮,开关断开,对应的灯 灭)。 三、参考电路图 3.1 多路开关状态指示电路原理图 四、电路硬件说明 如图 3.1 所示,拨动开关 SW1、SW2、SW3、SW4 通过 8 联拨动拨码开关 JP2 接连单片机 的 P3.0、P3.1、P3.2、P3.3 端口。单片机的 P1.0、P1.1、P1.2、P1.3 口通过 8 联拨动拨码 开关 JP4 分别连接四个指示灯 D1、D2、D3、D4。 五、程序设计内容10 (1)开关状态检测 拨动开关状态的检测,对于单片机来说,是一种输入关系,轮流检测每个开关的状态, 根据每个开关的状态让相应的发光二极管指示显示。在编写程序时,可以使用 JB P3.X 或 JNB P3.X 指令来完成指示控制。 (2)单片机的输出控制 根据拨动开关 SW1、SW2、SW3、SW4 的状态,经由发光二极管 D1-D4 来指示显示。在编 写程序时,可以用 SETB P1.X 和 CLR P1.X 指令来完成。 六、程序流程图(如图 3.2 所示)图 3.2 多路开关状态指示流程图 七、汇编源程序 ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI ORG RETI ORG LCALL LJMP JB CLR SJMP 0000H START BH BH H KAIGUAN START P3.0,N1 P1.0 M1 ;程序复位入口地址 ;跳到主程序 ;外部中断 0 入口地址 ;中断返回 ;定时器中断 0 入口地址 ;中断返回 ;外部中断 1 入口地址 ;中断返回 ;定时器中断 1 入口地址 ;中断返回 ;串行口中断入口地址 ;中断返回 ;调用检测开关状态子程序 ;跳回继续检测 ;判断 p3.0 是否按下 ;p3.0 按下则亮 p1.0 ;跳到 m111START: KAIGUAN: N1: M1:N2: M2:N3: M3:N4: M4:SETB JB CLR SJMP SETB JB CLR SJMP SETB JB CLR SJMP SETB LJMP RET ENDP1.0 P3.1,N2 P1.1 M2 P1.1 P3.2,N3 P1.2 M3 P1.2 P3.3,N4 P1.3 M4 P1.3 KAIGUAN;p3.0 没有按下则灭 p1.0 ;判断 p3.1 是否按下 ;p3.1 按下则亮 p1.1 ;跳到 m2 ;p3.1 没有按下则灭 p1.1 ;判断 p3.2 是否按下 ;p3.2 按下则亮 p1.2 ;跳到 m3 ;p3.2 没有按下则灭 p1.2 ;判断 p3.3 是否按下 ;p3.3 按下则亮 p1.3 ;跳到 m4 ;p3.3 没有按下则灭 p1.3 ;跳回检测开关状态子程序进行循环 ;子程序返回 ;结束八、C 语言源程序 #include &AT89X51.H& main() { if(P3_0==0) { P1_0=0; } else { P1_0=1; } if(P3_1==0) { P1_1=0; } else { P1_1=1; } if(P3_2==0) { P1_2=0; } else { P1_2=1; } if(P3_3==0) { P1_3=0; } else {P1_3=1; }12 } 九、注意事项 (1)程序下载到实验板上后,要把 8 联拨动拨码开关 JP2 和 JP4 的相应按键合上去。 (2)与 8 联拨动拨码开关 JP4 相连的指示灯是高电平亮,低电平灭。13 实验四 广告灯左、右移设计一、实验目的 1.初步了解广告灯的移动设计。 2.掌握循环移动的原理。 二、设计原理 如图 4.1 所示,八个发光二极管 D1-D8 通过 8 联拨动拨码开关 JP4 分别连接在单片机 的 P1.0-P1.7 端口上,做单一灯的左移右移。如果单片机的 P1 端口输出为“0”时,发光 二极管亮,依次为 P1.0→P1.1→P1.2→P1.3→┅→P1.7→P1.6→┅→P1.0 亮,重复循环。 三、参考电路图 4.1 广告灯左、右移设计电路原理图 四、电路硬件说明 把“单片机系统”区域中的单片机的 P1.0-P1.7 端口通过 8 联拨动拨码开关 JP4 连接 到“八路发光二极管指示模块”区域中的 D1-D8 端口上,要求:P1.0 对应着 D1,P1.1 对 应着 D2,??,P1.7 对应着 D8。 五、程序设计内容 运用输出端口指令 MOV P1,A 或 MOV P1,#DATA,给累加器值或常数值,然后执行 上述的指令,即可达到输出控制的动作。 每次送出的数据是不同的,具体的数据如下表 4.2 所示 表 4.2 8 个 LED 循环显示真值表 P1.7 D8 1 1 1 1 1 P1.6 D7 1 1 1 1 1 P1.5 D6 1 1 1 1 1 P1.4 D5 1 1 1 1 0 P1.3 D4 1 1 1 0 1 P1.2 D3 1 1 0 1 1 P1.1 D2 1 0 1 1 1 P1.0 D1 0 1 1 1 1 D1 亮 D2 亮 D3 亮 D4 亮 D5 亮14说明 1 1 01 0 10 1 11 1 11 1 11 1 11 1 11 1 1D6 亮 D7 亮 D8 亮六、程序流程图(如图 4.3 所示)图 4.3 广告灯左右移程序流程图 七、汇编源程序 ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI ORG RETI ORG MOV MOV SETB MOV LCALL RLC DJNZ 0000H START BH BH H R2,#7 A,#0FEH C P1,A DELAY A R2,LOOP ;系统复位 ;转入主程序 ;外部中断 0 ;中断返回 ;定时器 0 溢出中断 ;外部中断 1 ;定时器 1 溢出中断 ;外部中断 2START:;给 CY 置 1LOOP:;带进位左移 ;R2 减 1 不为 0 转到 LOOP15 LOOP1:DELAY: D1: D2:MOV MOV LCALL RRC DJNZ LJMP MOV MOV MOV DJNZ DJNZ DJNZ RET ENDR2,#8 P1,A DELAY A R2,LOOP1 START R5,#20 R6,#20 R7,#248 R7,$ R6,D2 R5,D1;带进位右移 ;R2 减 1 不为 0 转到 LOOP1 ;延时 0.2 秒子程序八、C 语言源程序 #include &AT89X51.H& unsigned char a,b; void delay(void) { unsigned char m,n,s; for(m=20;m&0;m--) for(n=20;n&0;n--) for(s=248;s&0;s--); } void main(void) { while(1) { temp=0 P1= delay(); for(i=1;i&8;i++) { a=temp&&i; b=temp&&(8-i); P1=a|b; delay(); } for(i=1;i&8;i++) { a=temp&&i; b=temp&&(8-i); P1=a|b; delay(); } }//延时子程序////向左移 i 位// //向右移 8-i 位// //a 或 b//16 } 九、注意事项 (1)程序下载到实验板上后,要把 8 联拨动拨码开关 JP4 的相应按键合上去。 (2)用 C 语言编写程序,利用左移和右移指令时,移入单元的数为 0。 (3)在硬件电路中,发光二极管和电源之间必须加上合适的电阻。17 实验五 查询法设计广告灯一、实验目的 1.熟悉广告灯的移动设计。 2.掌握查询法在单片机编程中的使用。 二、设计原理 利用取表的方法,使单片机的 P1 端口做单一灯的变化:左移 2 次,右移 2 次,闪烁 2 次(间隔的时间为 0.2 秒)。 三、参考电路图 5.1 查询设计广告灯电路原理图 四、电路硬件说明 在“单片机系统”区域中,把单片机 的 P1.0-P1.7 端口通过 8 联拨动拨码开关 JP4 连接到“八路发光二极管指示模块” 区域中的 D1-D8 端口上。要求:P1.0 对 应 D1, P1.1 对应 D2, ??, P1.7 对应 D8。 五、程序设计内容 在利用表格进行程序设计时,要用以 下的指令来完成: (1) 利用 MOV DPTR,#DATA16 指 令使数据指针寄存器指到数据表格的首地 址。 (2)利用 MOVC A, @A+DPTR 指令, 根据累加器 A 的值再加上 DPTR 的值, 就可 以使程序计数器 PC 指针指到表格内所需 要取出的数据。因此,只要把控制码组建 图 5.2 查询法设计广告灯流程图18 成一个表格,利用 MOVC A,@A+DPTR 做取控制码的操作,就可方便地处理一些复杂的控 制动作。 六、程序流程图(如图 5.2 所示) 七、汇编源程序 ORG 0000H ;系统复位 LJMP START ;转入主程序 ORG 0003H ;外部中断 0 RETI ;中断返回 ORG 000BH ;定时器 0 溢出中断 RETI ORG 0013H ;外部中断 1 RETI ORG 001BH ;定时器 1 溢出中断 RETI ORG 0023H ;外部中断 2 RETI ORG 0100H MOV DPTR, #TABLE ;把表格首地址给 DPTR CLR A ;A 赋 0 MOVC A,@A+DPTR ;查表得值送给 A 中 CJNE A,#01H,LOOP1 ;比较 A 等于#01,程序结束;否则跳转 SJMP START MOV P1,A ;把 A 送入 P1 口 LCALL DELAY1 ;调用延时 INC DPTR ;DPTR 加 1 SJMP LOOP MOV R3,#20 ;延时 0.2S 子程序 MOV R4,#20 MOV R5,#248 DJNZ R5,$ DJNZ R4,D1 DJNZ R3,DELAY RET 0FEH,0FDH,0FBH,0F7H ;数据表格 0EFH,0DFH,0BFH,07FH 0FEH,0FDH,0FBH,0F7H 0EFH,0DFH,0BFH,07FH 07FH,0BFH,0DFH,0EFH 0F7H,0FBH,0FDH,0FEH 07FH,0BFH,0DFH,0EFH 0F7H,0FBH,0FDH,0FEH 00H, 0FFH,00H, 0FFH 01H19START: LOOP:LOOP1:DELAY1: DELAY: D1:TABLE:DB DB DB DB DB DB DB DB DB DB END 八、C 语言源程序 #include &AT89X51.H& unsigned char code table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f, 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe, 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe, 0x00,0xff,0x00,0xff, 0x01};//数据数组// //定义全局变量// void delay(void) //延时子程序// { unsigned char m,n,s; for(m=20;m&0;m--) for(n=20;n&0;n--) for(s=248;s&0;s--); } void main(void) { while(1) //循环// { if(table[i]!=0x01) //判断是否查完表格// { P1=table[i]; i++; delay(); } else { i=0; } } } 九、注意事项 (1)利用 C 语言编写程序时,一定要注意合局变量和局部变量的定义。 (2)利用汇编语言编写程序时,注意 16 位数据指针 DPTR 的用法。20 实验六 报警产生器设计一、实验目的 掌握利用单片机产生音频信号的方法。 二、设计原理 利用单片机产生 1KHz 的信号,并且让此信号响 100ms;再利用单片机产生 500Hz 的信 号, 并且让此信号响 200ms。 同时让这两个信号交替产生。 通过单片机的 P1.0 端口输出 1KHz 和 500Hz 的音频信号驱动扬声器,作为报警信号。单片机的 P3.0 端口通过 8 联拨动拨码开 关连接一拨动开关(如 SW1)进行控制。拨动开关闭合时报警器报警,断开时报警器停止报 警。 三、参考电路 图 6.1 报警产生器原理图四、电路硬件说明 把单片机的 P1.0 端口连接到“音频放大模块”区域中的 SPK IN 端口上;P3.0 端口连 接到“八路拨动开关”区域中的 K1 端口上,并在“音频放大模块”区域中的 SPK OUT 端口 上接上一个 8 欧的或者是 16 欧的喇叭。 五、程序设计内容 500Hz 信号周期为 2ms,信号电平为每 1ms 取反 1 次,1KHz 的信号周期为 1ms,信号电 平每 500us 取反 1 次,以此来产生报警信号。 六、程序流程图(如图 6.2 所示)21 图 6.2 报警产生器流程图 七、汇编源程序 FLAG ORG LJMP ORG RETI ORG BIT 00H 0000H START BHRETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序;;;;;;;;;; ORG 0100H START: LCALL BAOJING1 LCALL BAOJING2 LJMP START ;;;;;;;;;;500hz 报警信号程序;;;;;;;;;; BAOJING1: MOV R2,#20022 DV:CPL P1.0 LCALL DELAY500 LCALL DELAY500 DJNZ R2,DV RET ;;;;;;;;;;1khz 报警信号程序;;;;;;;;;; BAOJING2: MOV R2,#200 DV1: CPL P1.0 LCALL DELAY500 DJNZ R2,DV1 RET ;;;;;;;;;;500us 延时程序;;;;;;;;;; DELAY500: MOV R7,#249 LOOP: DJNZ R7,LOOP RET ;;;;;;;;;;结束标志;;;;;;;;;; END 八、C 语言源程序 #include &AT89X51.H& #include &INTRINS.H& void dely500(void) //延时子程序// { for(i=250;i&0;i--) { _nop_(); } } void main(void) { while(1) //程序循环// { if(P3_0==0) //判断 P3.0 是否按下// { for(count=200;count&0;count--) { P1_0=~P1_0; dely500(); } for(count=200;count&0;count--) { P1_0=~P1_0; dely500(); dely500(); } } } }23 九、注意事项 (1)程序下载后,一定要把 8 联拨动拨码开关 JP5 的第一个开关拨上去。 (2)程序下载后,要把 8 联拨动拨码开关 JP3 拨下,8 联拨动拨码开关 JP2 拨上去。24 实验七 I/O 并行口直接驱动 LED 显示设计一、实验目的 1.了解静态数码管的显示方法。 2.掌握共阴极数码管和共阳极数码管的接法以及区别。 二、设计原理 如图 7.1 所示,利用单片机 P0 端口的 P0.0-P0.7 连接到一个共阴数码管 DS1 的 a-h 的笔段上,数码管的公共端接地。在数码管上循环显示 0-9 数字,显示时间间隔为 0.2 秒。 三、参考电路图 7.1 I/O 并行口直接驱动 LED 显示电路原理图 四、电路硬件说明 在“单片机系统”区域中,把单片机的 P0.0-P0.7 端口连接到静态数码管 DS1 上的 a- h 端口上;要求:P0.0 与 a 相连,P0.1 与 b 相连,P0.2 与 c 相连,??,P0.7 与 h 相连。 五、程序设计内容 (1)LED 数码显示原理: LED 数码管内部由七个条形发光二极管和一个小圆点发光二极管组成,根据发光二极管 的连接形式,可分为共阴极型和共阳极型。 LED 数码管的 a-g 七个发光二极管加正向电压导通发亮,加反向电压截止熄灭。不同亮 暗的二极管组合形成不同的字形, 这种组合称之为字形码。 见表 7.2 为共阴极数码管的字形 码表。25 (2) 由于数码管显示数字 0-9 的字形码没有规律, 只能采用查表的方式来完成所需要 的要求。这样按着数字 0-9 的顺序,把每个数字的笔段代码按顺序排好并建立的表格如下 所示:TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH 表 7.2 共阴极的字形码表“0” “1” “2” “3” “4” “5” “6” “7”3FH 06H 5BH 4FH 66H 6DH 7DH 07H“8” “9” “A” “b” “C” “d” “E” “F”7FH 6FH 77H 7CH 39H 5EH 79H 71H六、程序流程图(如图 7.3 所示)图 7.3 I/O 并行口直接驱动 LED 显示流程图 七、汇编源程序 ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI 0000H START BH BH26 ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序;;;;;;;;;; ORG 0100H START: LCALL XIANSHI LJMP START ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV R1,#00H NEXT: MOV A,R1 MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A LCALL DELAY INC R1 CJNE R1,#10,NEXT RET ;;;;;;;;;;200ms 延时程序;;;;;;;;;; DELAY: MOV R5,#20 D1: MOV R6,#20 D2: MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET ;;;;;;;;;;数码译码表;;;;;;;;;; TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;;;;;;;;;;结束标志;;;;;;;;;; END 八、C 语言源程序 #include&AT89X51.H& unsigned char codevoid delay200ms(void) { unsigned char for(i=20;i&0;i--) { for(j=20;j&0;j--) { for(k=248;k&0;k--); } } } void main(void)table[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; //延时 0.2 秒的程序// i,j,k;27 { while(1) { for(a=0;a&10;a++) { P0=table[a]; delay200ms(); } }//取表中的数给 P0 口// //每 0.2 秒显示一个数码//} 九、注意事项 1.当数码管显示数码时,一定要分清共阴极和共阳极。 2.下载程序后一定要把单排针接插件 J5 的跳线帽加到 OE/VCC 端。28 实验八 单键识别设计一、实验目的 1.了解按键识别方法。 2.掌握按键的消抖方法。 3.了解加法计数的原理。 二、设计原理 每按下一次按键开关 S18,计数值加 1,然后通过和单片机的 P1 端口相连的“八路发光 二极管指示模块”区域中的 D1-D8 显示出相应的二进制计数值。 三、参考电路图 8.1 单键识别电路原理图 四、电路硬件说明 (1)在“单片机系统”区域中,把单片机的 P3.7 端口通过 8 联拨动拨码开关 JP2 连接 到“独立式键盘”区域中的 S18 端口上。29 (2)在“单片机系统”区域中,把单片机的 P1.0-P1.7 端口通过 8 联拨动拨码开关 JP4 连接到“八路发光二极管指示模块”区域中的“D1-D7”端口上;要求,P1.0 连接发光 二极管 D1,P1.1 连接发光二极管 D2,P1.2 连接发光二极管 D3,P1.3 连接发光二极管 D4, P1.4 连接发光二极管 D5,P1.5 连接发光二极管 D6,P1.6 连接发光二极管 D7,P1.7 连接发 光二极管 D8。 五、程序设计内容 (1)作为一个按键,完整的过程是从没有按下到按下再到释放。也就是说,当按下一 个按键时,某个命令只执行一次,然而在按键按下的过程中,不允许有干扰进来。因为,在 按下的过程中,一旦有干扰过来,可能造成误触发过程,这不是所想要的。因此在按键按下 的时候,就要把手动造成的干扰信号以及按键的机械接触等干扰信号滤除掉。一般情况下, 可以采用电容来滤除掉这些干扰信号,但实际上,这会增加硬件成本及硬件电路的体积,因 此采用软件滤波的方法去除这些干扰信号。一般情况下,一个按键按下的时候,总是在按下 的时刻存在着一定的干扰信号, 按下之后就基本上进入了稳定的状态。 具体的一个按键从按 下到释放的全过程的信号图如下图 8.2 所示:图 8.2 干扰信号示意图 从图中可以看出,在程序设计时,从按键被识别按下之后,延时 5ms 以上,从而避开了 干扰信号区域。再来检测一次,看按键是否真得已经按下,若真得已经按下,这时肯定输出 为低电平。如果这时检测到的是高电平,证明刚才是由干扰信号引起的误触发,CPU 就认为 是误触发信号而舍弃这次的按键识别过程。从而提高了系统的可靠性。 由于要求每按下一次,命令被执行一次,直到下一次再按下的时候,再执行一次命令, 因此从按键被识别出来之后,就可以执行这次的命令。所以要有一个等待按键释放的过程, 显然释放的过程,就是使其恢复成高电平状态。图 8.3(a) 按键识别流程图30 (2)对于识别按键的指令,依然选择如下指令 JB BIT,REL 指令是用来检测 BIT 是否为高电平,若 BIT=1,则程序转向 REL 处执行程序,否则就继续向下执行程序。 或者是 JNB BIT,REL 指令是用来检测 BIT 是否为低电平,若 BIT=0,则程序转向 REL 处执行程序,否则就继续向下执行程序。 六、程序设计流程图(如图 8.3 所示) (1)程序设计过程中按键识别过程的框图如图 8.3(a)所示。 (2)按键控制程序流程图如图 8.3(b)所示。图 8.3(b) 按键控制程序流程图 七、汇编源程序 ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI ORG RETI ORG MOV MOV CPL MOV 0000H START BH BH H R1,#00H A,R1 A P1,A ;系统复位 ;转入主程序 ;外部中断 0 ;中断返回 ;定时器 0 溢出中断 ;外部中断 1 ;定时器 1 溢出中断 ;外部中断 2START:;初始化 R7 为 0, 0 开始计数 从 ;取反指令 ;送出 P1 口由发光二极管显示31 REL:DELAY10MS: L1:JB LCALL JB INC MOV CPL MOV JNB SJMP MOV MOV DJNZ DJNZ RET ENDP3.7,REL DELAY10MS P3.7,REL R1 A,R1 A P1,A P3.7,$ REL R6,#20 R7,#248 R7,$ R6,L1;判断 SP1 是否按下 ;若按下,则延时 10ms 左右 ;再判断 SP1 是否真得按下 ;若真得按下,则进行按键处理 ;计数内容加 1,并送出 P1 口由 ;发光二极管显示 ;等待 SP1 释放 ;继续对 K1 按键扫描 ;延时 10ms 子程序八、C 语言源程序 #include&AT89X51.H& void delay10ms(void) //延时 10 毫秒// { unsigned char i,j; for(i=20;i&0;i--) { for(j=248;j&0;j--); } } void main(void) { while(1) { if(P3_7==0) //看是否 P3.7 按下// { delay10ms(); //延时 10 毫秒// if(P3_7==0) //再看一遍是否真的按下// { k++; //如果按下,k 记下按下的次数// if(k==256) //记到 256 次,k 重 0 开始记// { k=0; } P1=~k; //由于是低电平亮,所以取反后再送 P1 口显示// while(P3_7==0); //判断 P3.7 是否弹起// } } } } 九、注意事项 (1)按键的识别一定要消除抖动干扰。 (2)键盘消抖所用的时间不少于 5 毫秒。 (3)下载结束后,拔掉下载线以防止 P1 端口对二极管的显示干扰。32 实验九 一键多功能按键识别设计一、实验目的 (1)了解按键识别方法。 (2)掌握一键多功能的设计原理。 二、设计原理 如图 9.1 所示,按键开关 S18 通过 8 联拨动拨码开关 JP3 接在单片机的 P3.7 管脚上, 在单片机的 P1 端口接有四个发光二极管。上电的时候,接在 P1.0 管脚上的发光二极管 D1 在闪烁。当按下一次按键开关 S18 的时候,接在 P1.1 管脚上的发光二极管 D2 在闪烁。再按 下按键开关 S18 的时候,接在 P1.2 管脚上的发光二极管 D3 在闪烁。第三次按下按键开关 S18 的时候,接在 P1.3 管脚上的发光二极管 D4 在闪烁。第四次按下按键开关 S18 的时候, 回到 D1 闪烁,如此循环下去。 三、参考电路图 9.1 一键多功能识别技术电路原理图 四、电路硬件说明 (1)在“单片机系统”区域中,把单片机的 P3.7 端口连接到“独立式键盘”区域中的 按键开关 S18 端口上。33 (2)在“单片机系统”区域中,把单片机的 P1.0-P1.4 端口通过 8 联拨动拨码开关连 接到“八路发光二极管指示模块”区域中的发光二极管“DL1-DL8”端口上;要求,P1.0 连接 D1,P1.1 连接 D2,P1.2 连接 D3,P1.3 连接 D4。 五、程序设计内容 (1)设计思想由来 在生活中,有张三、李四、王五、等等。由于每个人有不同的名子,就能很快认出。同 样,对于要通过某个按键来识别其相应的功能,再给不同的功能模块赋予了不同的 ID 号标 识。这样,每按下一次按键,ID 就显不同的值,因此单片机就很容易识别不同功能的身份 了。 (2)设计方法 从设计的原理可以看出, 发光二极管 D1 到 D4 在每个时刻闪烁的时间是受按键开关 S18 来控制的。给发光二极管 D1 到 D4 闪烁的时段定义出不同的 ID 号,当 D1 在闪烁时,ID=0; 当 D2 在闪烁时,ID=1;当 D3 在闪烁时,ID=2;当 D4 在闪烁时,ID=3;很显然,只要每 次按下开关 S18 时,分别给出不同的 ID 号就能够实现所设计的要求了。 六、程序设计流程图(如图 9.2 所示)、图 9.2 一键多功能识别技术程序流程图 七、汇编源程序 ID SP1 L1 EQU BIT BIT 30H P3.7 P1.0 ;定义相应的位34 L2 L3 L4START:REL:IS0:IS1:BIT BIT BIT ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI ORG RETI ORG MOV JB LCALL JB INC MOV CJNE MOV JNB MOV CJNE SETB SETB SETB CPL LCALL SJMP CJNE SETB CPL LCALL SJMP CJNE SETB SETB CPL LCALL SJMPP1.1 P1.2 P1.3 0000H START BH BH 0023H;系统复位 ;转入主程序 ;外部中断 0 ;中断返回 ;定时器 0 溢出中断 ;外部中断 1 ;定时器 1 溢出中断 ;外部中断 20100H ;程序入口地址 ID,#00H SP1,REL ;判断按键是否按下 DELAY10MS ;延时消抖 SP1,REL ;再次判断 ID ;如果按下,用 ID 记下按键按下的次数 A,ID A,#04,REL ;看按键是否按下 4 次 ID,#00H ;如果是清 0,重新记数 SP1,$ ;等待按键弹起 A,ID A,#00H,IS0 ;是否第一次按下按键 L4 ;如果是,第一指示灯显示 L3 L2 L1 DELAY ;延时 START A,#01H,IS1 ;是否第二次按下按键 L1 ;如果是第二个指示灯显示 L2 DELAY START A,#02H,IS2 ;是否第三次按下按键 L1 ;如果是第三个指示灯显示 L2 L3 DELAY START35 IS2:IS3: DELAY10MS: LOOP1:DELAY: LOOP2:CJNE SETB SETB SETB CPL LCALL SJMP LJMP MOV MOV DJNZ DJNZ RET MOV LCALL DJNZ RET ENDA,#03H,IS3 L1 L2 L3 L4 DELAY START START R6,#20 R7,#248 R7,$ R6,LOOP1 R5,#20 DELAY10MS R5,LOOP2;是否第四次按下按键 ;如果是第四个指示灯显示;延时子程序八、C 语言源程序 #include&AT89X51.H& void delay10ms(void) //延时 10 毫秒子程序// { unsigned char i,j; for(i=20;i&0;i--) { for(j=248;j&0;j--); } } void delay200ms(void) //延时 0.2 秒程序// { for(k=20;k&0;k--) { delay10ms(); } } void main(void) { while(1) { if(P3_7==0) //看是否 P3.7 的按键按下// { delay10ms(); //延时 10 毫秒看是否干扰// if(P3_7==0) //重新看是否真的按下// { h++; //如果按下 h 加 1,即 h 记下按键按下的次数// if(h==4) //如果 h 记到 8 次,则 h 清 0 重新记录次数// { h=0; } while(P3_7==0); //等待按键弹起// } } switch(h)36 {case 0: P1_3=1; P1_0=~P1_0; delay200ms(); case 1: P1_0=1; P1_1=~P1_1; delay200ms(); case 2: P1_1=1; P1_2=~P1_2; delay200ms(); case 3: P1_2=1; P1_3=~P1_3; delay200ms(); }//如果按键按下次数为 1 次时,进入此部分// //给 P1.0 取反,以达到闪烁的效果// //每隔 0.2 秒闪烁一次// //按键按下的次数为 2 次时,进入此部分// //给 P1.1 取反,以达到每隔 0.2 秒闪烁一次////按键按下的次数为 3 次时,进入此部分// //给 P1.2 取反,以达到每隔 0.2 秒闪烁一次////按键按下为 4 次时,进入此部分// //给 P1.3 取反,以达到每隔 0.2 秒闪烁一次//} } 九、注意事项 汇编语言和 C 语言定义口的书写形式不同。如汇编语言为 P1.0,P2.0,P3.0,而 C 语 言为 P1_0 ,P2_0 ,P3_0。37 实验十 00-99 计数器设计一、实验目的 1.掌握计数器的设计方法。 2.了解计数器的手动计数功能。 3.了解静态数码显示技术。 二、设计原理 如图 10.1 所示, 利用单片机来制作一个手动计数器, 在单片机的 P3.7 管脚口接一个轻 触开关,作为手动计数的按钮,用单片机管脚的 P2.0-P2.7 口连接一个共阴数码管,作为 00-99 计数的个位数显示,用单片机管脚的 P0.0-P0.7 口连接一个共阴数码管,作为 00- 99 计数的十位数显示。 三、参考电路图 10.1 00-99 计数器设计电路原理图 四、电路硬件说明38 (1)在“单片机系统”区域中,把单片机的 P0.0-P0.7 端口连接到“静态数码显示模 块”区域中的 a-h 端口上;要求:P0.0 对应着 a,P0.1 对应着 b,??,P0.7 对应着 h。 (2)在“单片机系统”区域中,把单片机的 P2.0-P2.7 端口连接到“静态数码显示模 块”区域中的 a-h 端口上;要求:P0.0 对应着 a,P0.1 对应着 b,??,P0.7 对应着 h。 (3)在“单片机系统”区域中,把单片机的 P3.7 端口通过拨动开关 JP2 连接到“独立 式键盘”区域中的按键开关 S18 上。 五、程序设计内容 (1)单片机对按键的识别过程的处理。 (2)单片机对正确识别的按键进行计数,计数满时,从零开始计数。 (3)单片机对计的数值要进行数码显示,计得的数是十进制数,含有十位和个位。要 把十位和个位的数值分别到各自对应的数码管上并显示。 分别送数时, 可以把所计得的数值 对 10 求余,即可得到个位数字;对 10 整除,即可得到十位数字。 (4)通过查表方式,分别显示出个位和十位的数字。 六、程序流程图(如图 10.2 所示)图 10.2 00-99 计数器设计流程图 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; COUNT EQU 30H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH RETI ORG 0013H RETI39 ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序;;;;;;;;;; ORG 0100H START: LCALL CHUSHIHUA NEXT: LCALL XIANSHI LCALL WT LCALL WAIT CJNE A,#100,NEXT LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV COUNT,#00H RET ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A,COUNT MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOVC A,@A+DPTR MOV P2,A RET ;;;;;;;;;;开关抬起检测程序;;;;;;;;;; WT: JNB P3.7,$ RET ;;;;;;;;;;开关按下次数记数程序;;;;;;;;;; WAIT: JB P3.7,WAIT LCALL DELAY10MS JB P3.7,WAIT INC COUNT MOV A,COUNT RET ;;;;;;;;;;10ms 延时程序;;;;;;;;;; DELAY10MS: MOV R6,#20 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET40 TABLE:;;;;;;;;;;共阴数码表;;;;;;;;;; DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;;;;;;;;;;结束标志;;;;;;;;;; END八、C 语言源程序 #include&AT89X51.H& unsigned char codetable[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; void delay10ms(void) //延时 10 毫秒子程序// { unsigned char i,j; for(i=20;i&0;i--) { for(j=248;j&0;j--); } } void main(void) { k=0; //先让十位和个位显示 00// P0=table[k/10]; P2=table[k%10]; while(1) { if(P3_7==0) //看按键是否按下// { delay10ms(); //延时 10 毫秒// if(P3_7==0) //再判断按键是否真的按下// { k++; //记下按键按下的次数// if(k==100) //如果计数到 100,返回 0// { k=0; } while(P3_7==0); //等待按键弹起// P0=table[k/10]; //显示十位数// P2=table[k%10]; //显示个位数// } } } } 九、注意事项 (1)程序中数码管的显示为共阴极显示。 (2)用静态数码管 DS1、DS2 时,要把 J5 上的跳线帽加到 OE 和 VCC 上;把 J6 上的跳线 帽加到 OE 和 GND 上。41 实验十一 六十秒计时器设计一、实验目的 1.了解计时器的功能。 2.掌握计时器的设计方法。 3.掌握静态数码显示技术。 二、设计原理 如图 11.1 所示,在单片机的 P0 和 P2 端口分别接两个共阴极数码管。P0 口驱动计时器 显示的十位,P2 口驱动计时器显示的个位。 三、参考电路图 11.1 六十秒计时器电路原理图 四、电路硬件说明 (1)在“单片机系统”区域中,把单片机的 P0.0-P0.7 端口连接到“静态数码显示模 块”区域中的 a-h 端口上;要求:P0.0 对应着 a,P0.1 对应着 b,??,P0.7 对应着 h。42 (2)在“单片机系统”区域中,把单片机的 P2.0-P2.7 端口连接到“静态数码显示模 块”区域中的 a-h 端口上;要求:P2.0 对应着 a,P2.1 对应着 b,??,P2.7 对应着 h。 五、程序设计内容 (1)在设计过程中要用一个存储单元作为秒计数单元。当一秒钟到来时,就让秒计数 单元加 1;当秒计数达到 60 时,就自动返回到 0,从新计数。 (2)对于秒计数单元中的数据来说,要把它的十位数和个数分开,方法仍采用对 10 整 除和对 10 求余。 (3)当在数码管上显示数时,仍通过查表的方式完成。 (4)一秒时间的产生在这里采用软件精确延时的方法来完成,经过精确计算得到 1 秒 时间为 1.002 秒。 DELY1S: MOV R5,#100 D2: MOV R6,#20 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 DJNZ R5,D2 RET 六、程序流程图(如图 11.2 所示)图 11.2 60 秒计时器设计流程图 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; COUNT EQU 30H ;;;;;;;;;;入口地址;;;;;;;;;;43 START:CHUSHIHUA:NEXT:XIANSHI:DELAY1S: D1: D2:ORG 0000H LJMP START ORG 0003H RETI ORG 000BH RETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序;;;;;;;;;; ORG 0100H LCALL CHUSHIHUA LCALL NEXT LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; MOV COUNT,#00H RET ;;;;;;;;;;计数显示程序;;;;;;;;;; LCALL XIANSHI LCALL DELAY1S INC COUNT MOV A,COUNT CJNE A,#60,NEXT RET ;;;;;;;;;;显示程序;;;;;;;;;; MOV A,COUNT MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOVC A,@A+DPTR MOV P2,A RET ;;;;;;;;;;1s 延时程序;;;;;;;;;; MOV R5,#100 MOV R6,#20 MOV ` R7,#24844 TABLE:DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET ;;;;;;;;;;共阴数码表;;;;;;;;;; DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;;;;;;;;;;结束标志;;;;;;;;;; END八、C 语言源程序 #include&AT89X51.H& unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66, //数据表格// 0x6d,0x7d,0x07,0x7f,0x6f}; void delay1s(void) //1 秒子程序// { unsigned char i,j,k; for(i=100;i&0;i--) { for(j=20;j&0;j--) { for(k=248;k&0;k--);} } } void main(void) { m=0; //显示 0 秒// P0=table[m/10]; P2=table[m%10]; while(1) { delay1s(); //延时 1 秒// m++; //每到 1 秒加 1// if(m==60) //如果到了 60 秒,重新开始计时// { m=0; } P0=table[m/10]; //显示// P2=table[m%10]; } } 九、注意事项 用静态数码管 DS1、 时, DS2 要将 J5 上的 OE 和 VCC 通过跳线帽连接 、 上的 OE 和 GND J6 通过跳线帽连接。45 实验十二 可预置可逆 4 位计数器设计一、实验目的 1.可预置可逆 4 位计数器设计 2.掌握计数器的预置、加法和减法。 二、设计原理 如图 12.1 所示,用单片机的 P1.0-P1.3 端口接四个发光二极管 D1-D4,用来指示当 前计数的数据。用单片机的 P3.0-P3.3 端口作为预置数据的输入端,通过 8 联拨动拨码开 关 JP2 连接四个拨动开关 SW1-SW4,用单片机的 P3.6 和 P3.7 端口连接两个按键开关,用做 加计数和减计数开关。 三、参考电路图 12.1 可预置可逆 4 位计数器电路原理图 四、电路硬件说明46 (1)在“单片机系统”区域中,把单片机的 P1.0-P1.3 管脚通过 8 联拨动拨码开关 JP4 连接到“八路发光二极管指示模块”区域中的 D1-D4 上;要求:P1.0 对应着 D1,P1.1 对应着 D2,P1.2 对应着 D3,P1.3 对应着 D4。 (2)在“单片机系统”区域中,把单片机的 P3.0,P3.1,P3.2,P3.3 管脚通过 8 联拨 动拨码开关 JP2 连接到“四路拨动开关”区域中的拨码开关 SW1-SW4 上。 (3)在“单片机系统”区域中,把单片机的 P3.6,P3.7 管脚通过 8 联拨动拨码开关 JP2 连接到“独立式键盘”区域中的按键开关 S18 和 S19 上。 五、程序设计内容 (1)两个独立式按键识别的处理过程。 (2)预置初值的读取问题。 (3)LED 输出指示。 六、程序流程图(如图 12.2 所示)图 12.2 可预置可逆计数器设计流程图 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; COUNT EQU 30H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START47 ORG 0003H RETI ORG 000BH RETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H START: LCALL CHUSHIHUA MAIN: LCALL JIA LCALL JIAN LJMP MAIN ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV A,P3 ANL A,#0FH MOV COUNT,A MOV P1,A RET ;;;;;;;;;;加 1 程序;;;;;;;;;; JIA: JB P3.6,JIAN LCALL DELAY10MS JB P3.6,JIAN INC COUNT MOV A,COUNT CJNE A,#16,NEXT MOV A,P3 ANL A,#0FH MOV COUNT,A NEXT: MOV P1,A WAIT: JNB P3.6,$ RET ;;;;;;;;;;减 1 程序;;;;;;;;;; JIAN: JB P3.7,JIA LCALL DELAY10MS JB P3.7,JIA DEC COUNT MOV A,COUNT CJNE A,#0FFH,NEX48 MOV A,P3 ANL A,#0FH MOV COUNT,A NEX: MOV P1,A WAIT1: JNB P3.7,$ RET ;;;;;;;;;;10MS 延时程序;;;;;;;;;; DELAY10MS: MOV R6,#20 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET ;;;;;;;;;;结束标志;;;;;;;;;; END 八、C 语言源程序 #include&AT89X51.H& void delay10ms(void) { unsigned char i,j; for(i=20;i&0;i--) { for(j=248;j&0;j--); } } void main(void) { k=P3&0x0f; P1=k; while(1) { if(P3_6==0) { delay10ms(); if(P3_6==0) { if(k&=15) { k=15; } else { k++; } P1=k; while(P3_6==0); } } if(P3_6==0) { delay10ms(); if(P3_6==0) { if(k&=0) { k=0; } else//10 毫秒延时子程序////如果高电平时,指示灯亮,相反// //判断 P3.6 是否按下// //延时 10 毫秒// //再次判断是否真的按下// //如果指示的数大于等于 15,都以 15 计// //否则一直能加到 15// //送入 P1 口显示// //等待按键弹起////判断是否 P3.7 按下// //延时 10 毫秒// //再次判断是否真的按下// //如果 K 小于等于零,一切以 0 计//49 { k--; } P1=k; while(P3_7==0); } } } } 九、注意事项//如果不小于零,一直减到 0// //送入 P1 口显示// //等待 P3.7 弹起//(1)单片机中的指令在 C 语言中运用一定要大写。 (2)程序中要屏蔽 P1 口的高四位。50 实验十三 动态数码显示设计一、实验目的 1.掌握动态数码显示技术的设计方法。 2.掌握扫描在程序设计中的应用。 二、设计原理 如图 13.1 所示,在单片机的 P1 端口接动态数码管的字形码笔段,在单片机的 P2 端口 接动态数码管的数位选择端。在单片机 P3.0 管脚处接一个开关,当开关连接高电平时,态 数码管上显示“12345”字样;当开关连接低电平时,态数码管上显示“HELLO”字样。 三、参考电路图 13.1 动态数码显示电路原理图 四、电路硬件说明 (1)在“单片机系统”区域中,把单片机的 P1.0-P1.7 端口连接到“动态数码显示” 区域中的 a-h 端口上。51 (2) “单片机系统” 在 区域中,把单片机的 P2.0-P2.7 端口通过 8 联拨动拨码开关 JP1 连接到“动态数码显示”区域中的 S1-S8 端口上。 (3)在“单片机系统”区域中,把单片机的 P3.0 端口通过 8 联拨动拨码开关 JP2 连接 到拨动开关区域中的 SW1 端口上。 五、程序设计内容 (1)动态扫描方法: 动态接口采用各数码管循环轮流显示的方法, 当循环显示频率较高时, 利用人眼的暂留 特性,看不出显示的闪烁现象,这种显示需要一个接口完成字形码的输出(字形选择),另 一接口完成各数码管的轮流点亮(数位选择)。 (2)在进行数码显示的时候,要对显示单元开辟 8 个显示缓冲区,在每个显示缓冲区 装有显示的不同数据即可。 (3)对于显示不同字形码的数据采用查表方法来完成。 六、程序流程图 (如图 13.2 所示)图 13.2 动态数码显示程序流程图 七、汇编源程序 ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH52 START:PANDUAN:SW: Q1: XIANSHI: NEXT:DELAY10MS: D1:RETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H LCALL PANDUAN LCALL XIANSHI LJMP START ;;;;;;;;;;判断开关的状态;;;;;;;;;; JB P3.0,SW LCALL DELAY10MS JB P3.0,SW MOV DPTR,#TABLE2 SJMP Q1 JNB P3.0,PANDUAN MOV DPTR,#TABLE1 RET ;;;;;;;;;;显示程序;;;;;;;;;; MOV R0,#00H MOV R1,#7FH MOV A,R0 MOVC A,@A+DPTR MOV P0,A MOV A,R1 MOV P2,A LCALL DELAY INC R0 RR A MOV R1,A CJNE R1,#0FBH,NEXT RET ;;;;;;;;;;10ms 延时程序;;;;;;;;;; MOV R6,#20 MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET ;;;;;;;;;;200ms 延时程序;;;;;;;;;;53 DELAY: LOOP:TABLE1: TABLE2:MOV R5,#20 LCALL DELAY10MS DJNZ R5,LOOP RET ;;;;;;;;;;共阴字母码表;;;;;;;;;; DB 76H,79H,38H,38H,3FH ;;;;;;;;;;共阴数码表;;;;;;;;;;; DB 06H,5BH,4FH,66H,6DH ;;;;;;;;;;结束标志;;;;;;;;;;;;; END八、C 语言源程序 #include&AT89X51.H& unsigned char code table1[]={0x06,0x5b,0x4f,0x66,0x6d}; unsigned char code table2[]={0x76,0x79,0x38,0x38,0x3f}; void main(void) { unsigned char i,j,k,m; while(1) { j=0x7f; for(i=0;i&5;i++) //运行 5 次取出表中的 5 个数// { if(P3_0==0) //如果开关为 0,则显示 12345// { P0=table1[i]; } //送 P1 口显示// else //如果开关为 1,显示 HELLO// { P0=table2[i]; } //送 P1 口显示// P2=j; //显示码送入 P2 口// j=0x7f; //重赋初值// k=j&&(i+1); //右移 i+1 位// m=j&&(7-i); //左移 7-i 位// j=k|m; for(k=4;k&0;k--) //每隔一段时间显示一次// for(m=248;m&0;m--); } } } 九、注意事项 (1)程序中要注意共阴极数码管显示和共阳极数码管显示的区别,本程序在共阴极数 码管显示时,要把单排针接插件 J4 中的跳线帽加到 OE 和 VCC 上。 (2)程序下载后要把 8 联拨动拨码开关 JP2 中相应的拨码开关拨上去。54 实验十四 4×4 矩阵式键盘识别设计一、实验目的 1.掌握 4×4 矩阵式键盘程序识别原理。 2.掌握 4×4 矩阵式键盘按键的设计方法。 二、设计原理 (1)如图 14.2 所示,用单片机的并行口 P3 连接 4×4 矩阵键盘,并以单片机的 P3.0 -P3.3 各管脚作输入线,以单片机的 P3.4-P3.7 各管脚作输出线,在数码管上显示每个按 键 “0-F”的序号。 (2)键盘中对应按键的序号排列如图 14.1 所示。 三、参考电路图 14.2 4×4 矩阵式键盘识别电路原理图55 图 14.1 4×4 键盘 0-F 显示图 14.3 4×4 矩阵式键盘识别程序流程图四、电路硬件说明 (1)在“单片机系统”区域中,把单片机的 P3.0-P3.7 端口通过 8 联拨动拨码开关 JP3 连接到“4×4 行列式键盘”区域中的 M1-M4,N1-N4 端口上。 (2)在“单片机系统”区域中,把单片机的 P0.0-P0.7 端口连接到“静态数码显示模 块”区域中的任何一个 a-h 端口上;要求:P0.0 对应着 a,P0.1 对应着 b,??,P0.7 对 应着 h。 五、程序设计内容56 (1)4×4 矩阵键盘识别处理 。 (2)每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩 阵的行线和列线分别通过两并行接口和 CPU 通信。键盘的一端(列线)通过电阻接 VCC,而 接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪 一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。两个并行口中,一个 输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共 同形成键编码而识别按键,通过软件查表,查出该键的功能。 六、程序流程图(如图 14.3 所示) 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; COUNT EQU 30H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH RETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H START: LCALL CHUSHIHUA LCALL PANDUAN LCALL XIANSHI LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV COUNT,#00H RET ;;;;;;;;;;判断哪个按键按下程序;;;;;;;;;; PANDUAN: MOV P3,#0FFH CLR P3.4 MOV A,P3 ANL A,#0FH XRL A,#0FH JZ SW1 LCALL DELAY10MS57 K1:K2:K3: K4: SW1:K5:K6:K7: K8: SW2:JZ MOV ANL CJNE MOV LJMP CJNE MOV LJMP CJNE MOV LJMP CJNE MOV NOP LJMP MOV CLR MOV ANL XRL JZ LCALL JZ MOV ANL CJNE MOV LJMP CJNE MOV LJMP CJNE MOV LJMP CJNE MOV NOP LJMP MOV CLR MOV ANL XRLSW1 A,P3 A,#0FH A,#0EH,K1 COUNT,#0 DK A,#0DH,K2 COUNT,#4 DK A,#0BH,K3 COUNT,#8 DK A,#07H,K4 COUNT,#12 DK P3,#0FFH P3.5 A,P3 A,#0FH A,#0FH SW2 DELAY10MS SW2 A,P3 A,#0FH A,#0EH,K5 COUNT,#1 DK A,#0DH,K6 COUNT,#5 DK A,#0BH,K7 COUNT,#9 DK A,#07H,K8 COUNT,#13 DK P3,#0FFH P3.6 A,P3 A,#0FH A,#0FH58 K9:KA:KB: KC: SW3:KD:KE:KF: KG: SW4: DK:JZ LCALL JZ MOV ANL CJNE MOV LJMP CJNE MOV LJMP CJNE MOV LJMP CJNE MOV NOP LJMP MOV CLR MOV ANL XRL JZ LCALL JZ MOV ANL CJNE MOV LJMP CJNE MOV LJMP CJNE MOV LJMP CJNE MOV NOP LJMP LJMP RETSW3 DELAY10MS SW3 A,P3 A,#0FH A,#0EH,K9 COUNT,#2 DK A,#0DH,KA COUNT,#6 DK A,#0BH,KB COUNT,#10 DK A,#07H,KC COUNT,#14 DK P3,#0FFH P3.7 A,P3 A,#0FH A,#0FH SW4 DELAY10MS SW4 A,P3 A,#0FH A,#0EH,KD COUNT,#3 DK A,#0DH,KE COUNT,#7 DK A,#0BH,KF COUNT,#11 DK A,#07H,KG COUNT,#15 DK PANDUAN59 ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A,COUNT MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A LCALL DELAY SK: MOV A,P3 ANL A,#0FH XRL A,#0FH JNZ SK RET ;;;;;;;;;;10ms 延时程序;;;;;;;;;; DELAY10MS: MOV R6,#20 D1: MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET ;;;;;;;;;;200ms 延时程序;;;;;;;;;; DELAY: MOV R5,#20 LOOP: LCALL DELAY10MS DJNZ R5,LOOP RET ;;;;;;;;;;共阴码表;;;;;;;;;; TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ;;;;;;;;;;结束标志;;;;;;;;;; END 八、C 语言源程序 #include&AT89X51.H& unsigned char codetable[]={0x3f,0x66,0x7f,0x39, 0x06,0x6d,0x6f,0x5e, 0x5b,0x7d,0x77,0x79, 0x4f,0x07,0x7c,0x71};void main(void) { unsigned char i,j,k, while(1) { P3=0 P3_4=0; i=P3; i=i&0x0f; if(i!=0x0f) { for(j=50;j&0;j--) for(k=200;k&0;k--);//给 P3 口置 1// //给 P3.4 这条线送入 0// //屏蔽低四位// //看是否有按键按下// //延时//60 if(i!=0x0f) { switch(i) { case 0x0e: key=0; case 0x0d: key=1; case 0x0b: key=2; case 0x07: key=3; } P0=table[key]; } } P3=0 P3_5=0; i=P3; i=i&0x0f; if(i!=0x0f) { for(j=50;j&0;j--) for(k=200;k&0;k--); i=P3; i=i&0x0f; if(i!=0x0f) { switch(i) { case 0x0e: key=4; case 0x0d: key=5; case 0x0b: key=6; case 0x07: key=7; } P0=table[key]; }//再次判断按键是否按下// //看是和 P3.4 相连的四个按键中的哪个////送数到 P0 口显示////读 P3.5 这条线// //屏蔽 P3 口的低四位// //读 P3.5 这条线上看是否有按键按下// //延时// //再看是否有按键真的按下////如果有,显示相应的按键////送入 P0 口显示//61 } P3=0 P3_6=0; i=P3; i=i&0x0f; if(i!=0x0f) { for(j=50;j&0;j--) for(k=200;k&0;k--); i=P3; i=i&0x0f; if(i!=0x0f) { switch(i) { case 0x0e: key=8; case 0x0d: key=9; case 0x0b: key=10; case 0x07: key=11; } P0=table[key]; } } P3=0 P3_7=0; i=P3; i=i&0x0f; if(i!=0x0f) { for(j=50;j&0;j--) for(k=200;k&0;k--); i=P3; i=i&0x0f; if(i!=0x0f) { switch(i) { case 0x0e: key=12; case 0x0d: key=13;//读 P3.6 这条线上是否有按键按下////读 P3.7 这条线上是否有按键按下//62
case 0x0b: key=14; case 0x07: key=15; } P0=table[key]; } } } } 九、注意事项 在硬件电路中,要把 8 联拨动拨码开关 JP2 拨下,把 8 联拨动拨码开关 JP3 拨上去。63 实验十五 定时计数器 T0 作定时应用设计(一)一、实验目的 1.掌握定时计数器 T0 的用法。 2.掌握定时计数器 T0 的功能。 二、设计原理 用单片机的定时/计数器 T0 产生一秒的定时时间,作为秒计数时间。当一秒产生时,秒 计数加 1,秒计数到 60 时,自动从 0 重新计数。 三、参考电路图 15.1 定时计数器 T0 作定时应用(一)电路原理图 四、电路硬件说明 (1)在“单片机系统”区域中,把单片机的 P0.0-P0.7 端口连接到“静态数码显示模 块”区域中的任何一个 a-h 端口上;要求:P0.0 对应着 a,P0.1 对应着 b,??,P0.7 对 应着 h。64 (2)在“单片机系统”区域中,把单片机的 P2.0-P2.7 端口连接到“静态数码显示模 块”区域中的任一个 a-h 端口上;要求:P2.0 对应着 a,P2.1 对应着 b,??,P2.7 对应 着 h。 五、程序设计内容 AT89S51 单片机的内部 16 位定时/计数器是一个可编程定时/计数器,它既可以工作在 13 位定时方式,也可以工作在 16 位定时方式和 8 位定时方式。只要通过设置特殊功能寄存 器 TMOD,即可完成。定时/计数器何时工作也是通过软件 TCON 特殊功能寄存器来设定完成 的。 现在选择 16 位定时工作方式,对于 T0 来说,最大定时也只有 65536us,即 65.536ms, 无法达到所需要的 1 秒的定时,因此,必须通过软件来处理这个问题。假设取 T0 的最大定 时为 50ms,即要定时 1 秒就需要经过 20 次的 50ms 的定时。对于这 20 次就可以采用软件的 方法来计算了。 因此,设定 TMOD=B,即 TMOD=01H。 下面要给 T0 定时/计数器的 TH0,TL0 装入预置初值,通过下面的公式可以计算出 TH0=(6) / 256 TL0=(6) % 256 当 T0 在工作的时候,如何得知 50ms 的定时时间已到,通过检测 TCON 特殊功能寄存器 中的 TF0 标志位,如果 TF0=1 表示定时时间已到。 六、程序流程图(如图 15.2 所示)图 15.2 定时计数器 T0 应用(一)程序流程图65 七、汇编源程序(查询法) ;;;;;;;;;;定义单元;;;;;;;;;; COUNT EQU 30H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH RETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H START: LCALL CHUSHIHUA LCALL XIANSHI LCALL MAIN LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV COUNT,#00H RET ;;;;;;;;;;装初值程序;;;;;;;;;; CHUZHI: MOV TMOD,#01H MOV TH0,#3CH MOV TL0,#0B0H SETB TR0 RET ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A,COUNT MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOVC A,@A+DPTR MOV P2,A RET66 MAIN: SK:TABLE:;;;;;;;;;;60s 计时显示程序;;;;;;;;; MOV R5,#20 LCALL CHUZHI JNB TF0,$ CLR TF0 LCALL CHUZHI DJNZ R5,SK INC COUNT LCALL XIANSHI MOV A,COUNT CJNE A,#60,MAIN RET ;;;;;;;;;;共阴数码表;;;;;;;;; DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;;;;;;;;;;结束标志;;;;;;;;;; END八、C 语言源程序(查询法) #include&AT89X51.H& unsigned char codetable[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f};void main(void) { unsigned char i,j; TMOD=0x01; TH0=()/256; TL0=()%256; TR0=1; i=0; j=0; P0=table[j/10]; P2=table[j%10]; while(1) { if(TF0==1) { i++; if(i==20) { i=0; j++; if(j==60) { j=0; } P0=table[j/10]; P2=table[j%10]; } TF0=0; TH0=()/256;//设置定时器 0 方式 1// //赋 50 毫秒的初值// //开启定时器 0////十位数放入 P0 口显示,// //个位数放入 P2 口显示// //如果定时器溢出,则为 50 毫秒// //每到一个 50 毫秒,i 加 1// //如果到了 20 个 50 毫秒,则 1 秒的到来// //i 清 0,重新计数// //每到一个 1 秒,j 加 1// //如果计到 60 秒,则重新计数// //显示秒数的十位数// //显示秒数的个位数// //关闭定时器 0// //重新赋初值//67 TL0=()%256; } } } 九、汇编源程序(中断法) ORG LJMP ORG RETI ORG LJMP ORG RETI ORG RETI ORG RETI ORG RETI ORG MOV MOV MOV DIV MOV MOVC MOV MOV MOVC MOV MOV MOV MOV SETB SETB SETB SJMP MOV MOV INC MOV CJNE MOV 0000H ;系统复位 ZHONGDUANDINGSHI;进入 ZHONGDUANDINGSHI 程序 BH ZHONGDUAN BH BH 0100H R0,#00H A,R0 B,#10 AB DPTR,#TABLE A,@A+DPTR P0,A A,B A,@A+DPTR P2,A TMOD,#01H TH0,#3CH TL0,#0B0H TR0 ET0 EA $ TH0,#3CH TL0,#0B0H R1 A,R1 A,#20,NEXT R1,#00H ;转入中断子程序 ;开始的显示 00 的程序 ;定时器中断ZHONGDUANDINGSHI:ZHONGDUAN:;定义为定时器 0 的工作方式 1 ;给定时器的高位赋值 ;给定时器的低位赋值 ;开定时器 0 ;开启分开关 ;开启总开关 ;自身循环,等待中断 ;进入中断子程序,并重新赋值 ;记下中断次数 ;是否有 20 次中断 ;如果有,则清零,重新记68 NEX:NEXT: TABLE:INC R0 ;同时 R0 加 1 MOV A,R0 CJNE A,#60,NEX ;看是否加到 60 MOV R0,#00H ;如果加到 60 次,重新记 MOV A,R0 ;把 R0 中所记的数显示出来 MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A ;用 P0 显示十位 MOV A,B MOVC A,@A+DPTR MOV P2,A ;用 P2 显示个位 RETI ;中断返回 DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END十、C 语言源程序(中断法) #include&AT89X51.H& unsigned char codetable[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f};unsigned char i,j; void main(void) { TMOD=0x01; TH0=()/256; TL0=()%256; TR0=1; ET0=1; EA=1; i=0; j=0; P0=table[j/10]; P2=table[j%10]; while(1); } void t0(void) interrupt { i++; if(i==20) { i=0; j++; if(j==60) { j=0; } P0=table[j/10]; P2=table[j%10];//定义为定时器 0 方式 1// //赋初值// //开启定时器 0// //开启定时器 0 溢出中断// //开启总的中断开关////显示秒数的十位// //显示秒数的个位// //等待中断// 1 using 0 //定时器 0 溢出中断// //每到一个中断为 50 毫秒,i 加 1// //到来 20 次中断后,i 重新计数// //每来 20 次中断即为 1 秒,j 加 1// //每到 60 秒,则重新计时// //显示秒计时的十位// //显示秒计时的个位//69 } TH0=()/256; TL0=()%256; } 十一、注意事项//重新赋定时器 0 的初值//程序初始化时,针对不同的定时器要赋予不同的初值。70 实验十六 定时计数器 T0 作定时应用设计(二)一、实验目的 1.了解定时计数器 T0 在程序设计中的应用。 2.掌握定时器 T0 的功能以及用法。 二、设计原理 如图 16.1 所示, 用单片机的定时/计数器 T0 产生 2 秒钟的定时, 每当 2 秒定时到来时, 更换指示灯闪烁。每个指示灯闪烁的频率为 0.2 秒,也就是说,开始 D1 指示灯以 0.2 秒的 速率闪烁,当 2 秒定时到来之后,D2 开始以 0.2 秒的频率闪烁,如此循环下去。0.2 秒的闪 烁的频率也由定时/计数器 T0 来完成。 三、参考电路图 16.1 定时计数器 T0 应用(二)电路原理图 四、电路硬件说明 在“单片机系统”区域中,把单片机的 P1.0-P1.3 端口通过 8 联拨动拨码开关 JP4 连 接到“八路发光二极管指示模块”区域中的闪烁灯 D1-D4 上。71 五、程序设计内容 (1)本程序采用中断方式来完成,因此,对于中断源必须有它的中断入口地址。对于 定时/计数器 T0 来说,中断入口地址为 000BH。所以在中断入口地方加入长跳转指令来执行 中断服务程序。书写汇编源程序格式如下所示: ORG 00H LJMP START ORG 0BH ;定时/计数器 T0 中断入口地址 LJMP INT_T0 START: NOP ;主程序开始 . INT_T0: PUSH ACC ;定时/计数器 T0 中断服务程序 PUSH PSW . POP PSW POP ACC RETI ;中断服务程序返回 END (2)定时 2 秒,采用 16 位定时 50ms,共定时 40 次才可达到 2 秒,每 50ms 产生一中 断。定时的 40 次计数在中断服务程序中完成。同样,0.2 秒的定时,需要 4 次才可达到。 对于中断程序,在主程序中要开中断。 (3)由于定时每 2 秒一次,D1-D4 要交替闪烁。采用 ID 标号来识别。当 ID=0 时, D1 在闪烁;当 ID=1 时,D2 在闪烁;当 ID=2 时,D3 在闪烁;当 ID=3 时,D4 在闪烁。 六、程序流程图 (如图 16.2 所示)图 16.2 定时计数器 T0 应用(二)程序流程图72 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; TCOUNT2S EQU 30H TCNT02S EQU 31H ID EQU 32H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH LJMP INT_T0 ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H START: LCALL CHUSHIHUA LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV TCOUNT2S,#00H MOV TCNT02S,#00H MOV ID,#00H MOV TMOD,#01H MOV TH0,#60 MOV TL0,#176 SETB TR0 SETB ET0 SETB EA SJMP $ RET ;;;;;;;;;;中断子程序;;;;;;;;;; INT_T0: MOV TH0,#60 MOV TL0,#176 INC TCOUNT2S MOV A,TCOUNT2S CJNE A,#40,NEXT MOV TCOUNT2S,#00H INC ID73 NEXT:SID1:SID2:SID3:SID4: DONE:MOV A,ID CJNE A,#04H,NEXT MOV ID,#00H INC TCNT02S MOV A,TCNT02S CJNE A,#4,DONE MOV TCNT02S,#00H MOV A,ID CJNE A,#00H,SID1 SETB P1.1 SETB P1.2 SETB P1.3 CPL P1.0 SJMP DONE CJNE A,#01H,SID2 SETB P1.0 CPL P1.1 SJMP DONE CJNE A,#02H,SID3 SETB P1.0 SETB P1.1 CPL P1.2 SJMP DONE CJNE A,#03H,SID4 SETB P1.0 SETB P1.1 SETB P1.2 CPL P1.3 SJMP DONE RETI ;;;;;;;;;;结束标志;;;;;;;;;; END八、C 语言源程序 #include&AT89X51.H& unsigned char i,j,k; void main(void) { TMOD=0x01; TH0=()/256; TL0=()%256; TR0=1; ET0=1; EA=1; while(1);//此处应定义为全局变量// //设置为定时器 0 方式 1// //给定时器 0 赋初值// //开启定时器 0// //开启定时器 0 溢出中断// //开启中断总开关// //等待中断//74 } void t0(void) interrupt { i++; if(i==40) { i=0; j++; if(j==4) { j=0; } } k++; if(k==4) { k=0; switch(j) { case 0: P1_3=1; P1_0=~P1_0; case 1: P1_0=1; P1_1=~P1_1; case 2: P1_1=1; P1_2=~P1_2; case 3: P1_2=1; P1_3=~P1_3; } } } 九、注意事项1using 0 //每来一个 50 毫秒 i 加 1// //看是否 2 秒到来// //如果到了 2 秒,i 重新计 50 毫秒来的次数// //j 用于记下第几个指示灯闪烁// //如果闪到第四个闪烁灯,j 为 0////每到一个 50 毫秒 k 加 1// //看是否到了 0.2 秒// //如果到了 0.2 秒,则 k 清 0// //看应该是哪个指示灯闪烁//程序下载后,要把 8 联拨动拨码开关 JP4 的相应开关拨上去。75 实验十七 9.9 秒跑马表设计一、实验目的 1.了解 9.9 秒跑马表的设计原理。 2.掌握定时器的多重用途。 二、设计原理 (1)开始时,显示“00”,第 1 次按下按键开关 S20 后就开始计时。 (2)第 2 次按下按键开关 S20 后,计时停止。 (3)第 3 次按下按键开关 S20 后,计时归零。 (4)程序循环。 三、参考电路图 17.1 9.9 秒跑马表电路原理图 四、电路硬件说明76 (1)在“单片机系统”区域中,把单片机的 P0.0-P0.7 端口连接到“静态数码显示模 块”区域中的任一个 a-h 端口上;要求:P0.0 对应着 a,P0.1 对应着 b,??,P0.7 对应 着 h。 (2)在“单片机系统”区域中,把单片机的 P2.0-P2.7 端口连接到“静态数码显示模 块”区域中的任一个 a-h 端口上;要求:P2.0 对应着 a,P2.1 对应着 b,??,P2.7 对应 着 h。 (3)在“单片机系统”区域中,把单片机的 P3.5 管脚通过 8 联拨动拨码开关 JP2 连接 到“独立式键盘”区域中的按键开关 S20 端口上。 五、程序设计内容 用按键控制跑马表,开始时,数码管显示“00”;如果第一次按下按键时;跑马表开始 计时;第二次按下按键后,计时开始;第三次按下按键后,计时归零。如此循环。 六、程序流程图(如图 17.2 所示)图 17.2 跑马表设计流程图 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; EQU 30H EQU 31H EQU 32H EQU 33H ;;;;;;;;;;入口地址;;;;;;;;;;TCNTA TCNTB SEC KEYCNT77 ORG 0000H LJMP START ORG 0003H RETI ORG 000BH LJMP INT_T0 ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H START: LCALL CHUSHIHUA LCALL XIANSHI LCALL MAIN LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV SEC,#00H MOV KEYCNT,#00H RET ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A,SEC MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P2,A RET ;;;;;;;;;;9.9s 计数,停止,清零显示程序;;;;;;;;;; MAIN: MOV TMOD,#02H SETB ET0 SETB EA MAIN_1: JB P3.5,MAIN_1 LCALL DELY10MS JB P3.5,MAIN_1 INC KEYCNT78 MOV A,KEYCNT CJNE A,#01H,MAIN_2 SETB TR0 MOV TH0,#06H MOV TL0,#06H MOV TCNTA,#00H MOV TCNTB,#00H LJMP MAIN_0 MAIN_2: CJNE A,#02H,MAIN_3 CLR TR0 LJMP MAIN_0 MAIN_3: CJNE A,#03H,MAIN_0 MOV SEC,#00H LCALL XIANSHI MOV KEYCNT,#00H MAIN_0: JNB P3.5,$ LJMP MAIN_1 ;;;;;;;;;;10ms 延时程序;;;;;;;;;; DELY10MS: MOV R6,#20 DELY10MS_1: MOV R7,#248 DJNZ R7,$ DJNZ R6,DELY10MS_1 RET ;;;;;;;;;;中断子程序;;;;;;;;;; INT_T0: INC TCNTA MOV A,TCNTA CJNE A,#100,INT_T0_1 MOV TCNTA,#00H INC TCNTB MOV A,TCNTB CJNE A,#4,INT_T0_1 MOV TCNTB,#00H INC SEC MOV A,SEC CJNE A,#100,INT_T0_2 MOV SEC,#00H INT_T0_2: LCALL XIANSHI INT_T0_1: RETI ;;;;;;;;;;共阴数码表;;;;;;;;;; TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;;;;;;;;;;结束标志;;;;;;;;;; END 八、C 语言源程序79 #include&AT89X51.H& unsigned char codetable[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f};unsigned char m,n,a; void main(void) { unsigned char i,j,k; TMOD=0x02; //设置定时器 0 方式 2// ET0=1; //开启定时器 0 中断// EA=1; //开启中断总开关// m=0; //开始显示 0// P0=table[m/10]; P2=table[m%10]; while(1) { if(P3_5==0) //看 P3.5 是否按下// { for(i=20;i&0;i--) //延时判断// for(j=248;j&0;j--); if(P3_5==0) //再次判断// { while(P3_5==0); //如果有按下,等待按键弹起// k++; //k 记下按键按下的次数// switch(k) //看按键按下的次数// { case 1: //如果按下的是第一次,开启定时器开始计时// TH0=0x06; TL0=0x06; TR0=1; case 2: //如果按下的是第二次,停止计时// TR0=0; case 3: //如果按下的是第三次,显示 00// k=0; m=0; P0=table[m/10]; P2=table[m%10]; } } } } } void t0(void) { n++; if(n==40) { n=0; interrupt 1 using 0 //每到一个 250 微秒,n 加 1// //每到一个 10 毫秒,n 清 0,a 加 1//80 a++; if(a==10) { a=0; m++; if(m==100) { m=0; } P0=table[m/10]; P2=table[m%10]; } } } 九、注意事项//每到一个 0.1 秒,a 清 0,m 加 1// //每到 10 秒,重新开始计时// //显示//利用静态数码管 DS1、 DS2 时, 要把单排针接插件 J5 上的跳线帽加到 OE 和 VCC 上;把单 排针接插件 J6 上的跳帽加到 OE 和 GND 上。81 实验十八 “嘀、嘀、??”报警声设计一、实验目的 1.了解“嘀、嘀、??”报警声的设计原理。 2.掌握频率的产生方法。 3.了解报警信号的产生与报警器的控制。 二、设计原理 如图 18.1 所示,用 AT89S51 单片机产生“嘀、嘀、?”报警声并从 P1.0 端口输出,产 生 1KHz 的频率。根据图 18.1 可知:1KHZ 方波从 P1.0 输出 0.2 秒,接着的 0.2 秒从 P1.0 输出电平信号,如此循环下去,就形成所需的报警声了。 三、参考电路图 18.1 “嘀、嘀、??”报警声电路原理图 四、电路硬件说明82 (1)在“单片机系统”区域中,把 P1.0 端口连接到“音频放大模块”区域中的 SPK IN 端口上。 (2)在“音频放大模块”区域中,在 SPK OUT 端口上连接一个 8 欧或 16 欧的喇叭。 五、程序设计内容 (1)生活中常常会遇到各种各样的报警声,例如“嘀、嘀、?”就是常见的一种声音 报警声。但对于这种报警声,应该是“嘀”0.2 秒钟,然后断 0.2 秒钟,如此循环下去。假 设“嘀”的频率为 1KHz,则报警声时序如图 18.2 所示:图 18.2 报警声时序图(2)上述波形信号如何用单片机来产生呢? 由于要产生上面的信号,把上面的信号分成两部分:一部分为 1KHZ 方波,占用时间为 0.2 秒;另一部分为低电平,也是占用 0.2 秒。因此,利用单片机的定时/计数器 T0 作为定 时,可以定时 0.2 秒。同时,也用单片机产生 1KHZ 的方波,对于 1KHZ 的方波信号周期为 1ms,高电平占用 0.5ms,低电平占用 0.5ms。所以也采用定时器 T0 来完成 0.5ms 的定时。 最后, 可以选定定时/计数器 T0 的定时时间为 0.5ms。 而要定时的 0.2 秒是 0.5ms 的 400 倍, 也就是说以 0.5ms 定时 400 次就达到 0.2 秒的定时时间了。 六、程序流程图(如图 18.3 所示)图 18.3(a) “嘀、嘀、??”报警声主程序框图83 图 18.3(b) “嘀、嘀、??”报警声中断服务程序框图 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; EQU 30H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH RETI ORG 0013H RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;;; ORG 0100H LCALL BAOJING LCALL DIANPING LJMP START84COUNTSTART: BAOJING: BAOJING_2: BAOJING_1:DIANPING: DIANPING_3: DIANPING_4:DELAY05: DELAY05_1:;;;;;;;;;;报警信号程序;;;;;;;;;; MOV R7,#4 MOV R6,#100 CPL P1.0 LCALL DELAY05 DJNZ R6,BAOJING_1 DJNZ R7,BAOJING_2 RET ;;;;;;;;;;电平信号程序;;;;;;;;;; MOV R7,#4 MOV R6,#100 CLR P1.0 LCALL DELAY05 DJNZ R6,DIANPING_4 DJNZ R7,DIANPING_3 RET ;;;;;;;;;;5ms 延时程序;;;;;;;;;; MOV R5,#20 MOV TMOD,#02H MOV TH0,#00H MOV TL0,#06H SETB TR0 JNB TF0,$ DJNZ R5,DELAY05_1 RET ;;;;;;;;;;结束标志;;;;;;;;;; END八、C 语言源程序 #include&AT89X51.H& bit FLAG; void main(void) { TMOD=0x01; TH0=()/256; TL0=()%256; ET0=1; EA=1; TR0=1; while(1); } void t0(void) interrupt { TH0=()/256; TL0=()%256;//设置为定时器 0 方式 1// //给定时器 0 赋初值// //开启定时器 0 溢出中断// //开启中断总开关// //开启定时器 0// //等待中断// 1 using 0 //重新赋值//85 i++; if(i==200) { i=0; FLAG=~FLAG; } if(FLAG==1) { P1_0=~P1_0; } 九、注意事项//每到一个 1 毫秒,i 加 1// //计时到 0.2 秒时,i 清 0,重新计// //每 0.2 秒 FLAG 变换一次// //如果 FLAG 为 1 时,P1.0 输出 1KHZ 的信号// }在硬件电路中,要把 2 联拨动拨码开关 JP5 的第一个开关拨上去。86 实验十九 “叮咚”门铃设计一、实验目的 1. 了解“叮咚”门铃的设计原理。 2. 掌握不同频率信号的设计方法。 二、设计原理 当按下开关 S18,AT89S51 单片机产生的“叮咚”声从 P1.0 端口输出到 LM386,经过放 大之后送入喇叭。 三、参考电路图 19.1 “叮咚”门铃设计电路原理图 四、电路硬件说明 在“单片机系统”区域中,把单片机的 P3.7 端口通过 8 联拨动拨码开关 JP2 连接到“独 立式键盘”区域中的 S18 端口上。把 P1.0 端口连接到“音频放大模块”区域中的 SPK IN 端口上,并 在“音频放大模块”区域中的 SPK OUT 端口上连接一个 8 欧或 16 欧的喇叭。 把 P3.7 端口通过拨动开关 JP2 连接到“独立式键盘”区域中的 S18 端口上。 五、程序设计内容87 (1)用单片机定时/计数器 T0 来设计产生 700HZ 和 500HZ 的频率。用定时/计数器 T0, 取定时 250us。因此,700HZ 的频率要经过 3 次 250us 的定时,而 500HZ 的频率要经过 4 次 250us 的定时。 (2)在设计中,只有当按下 SP1 之后,才启动 T0 开始工作。当 T0 工作完毕,回到最 初状态。 (3)“叮”和“咚”声音各占用 0.5 秒,因此定时/计数器 T0 要完成 0.5 秒的定时,对 于以 250us 为基准定时 2000 次才可以。 六、程序流程图(如图 19.2 所示)图 19.2 “叮咚”门铃 七、汇编源程序 ;;;;;;;;;;定义单元;;;;;;;;;; EQU 30H EQU 31H EQU 32H EQU 33H EQU 00H EQU 01H ;;;;;;;;;;入口地址;;;;;;;;;; ORG 0000H LJMP START ORG 0003H RETI ORG 000BH LJMP INT_T0 ORG 0013HT500HZ T700HZ T05SA T05SB FLAG STOP88 START:CHUSHIHUA:LINGSHENG:DELAY10MS: D1:INT_T0:RETI ORG 001BH RETI ORG 0023H RETI ORG 002BH RETI ;;;;;;;;;;主程序入口;;;;;;;;;; ORG 0100H LCALL CHUSHIHUA LCALL LINGSHENG LJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; MOV TMOD,#02H MOV TH0,#06H MOV TL0,#06H SETB ET0 SETB EA RET ;;;;;;;;;;铃声程序;;;;;;;;;; JB P3.7,LINGSHENG LCALL DELAY10MS JB P3.7,LINGSHENG SETB TR0 CLR FLAG CLR STOP MOV T500HZ,#00H MOV T700HZ,#00H MOV T05SA,#00H MOV T05SB,#00H JNB STOP,$ LJMP LINGSHENG ;;;;;;;;;;10ms 延时程序;;;;;;;;;; MOV R6,#20 MOV R7,#248 DJNZ R7,$ DJNZ R6,D1 RET ;;;;;;;;;;中断程序;;;;;;;;;; INC T05SA MOV A,T05SA CJNE A,#100,INT_T0_2 MOV T05SA,#00H INC T05SB89 INT_T0_1:INT_T0_2:INT_T0_3:INT_T0_0:MOV A,T05SB CJNE A,#20,INT_T0_2 MOV T05SB,#00

我要回帖

更多关于 c51驱动数码管 的文章

 

随机推荐