单片机例程及详细分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

近期的几个单片机例程及详细分析
最近,我们在课上讲了几个小例子,在此再把Proteus图及程序的详细解释列出来,供大家参考。

1.应用查询方式,对连接在P1.4管脚上的按键次数进行计数,每5次在P 1.0上连接的红色LED亮或不亮。

本题考虑点:
A、应用查询方式,即读和检测P1.4管脚的状态,是1或0;
B、每5次翻转一次,因此可设一个寄存器作为计数器,看是否到了5次,5次后清零;
C、P1.0上的LED亮或不亮,即状态翻转,CPL P1.0。

Proteus图
应用元器件:单片机80C51(或80C52)、按键Button、电阻Res、LED
图1 找元器件的方法
单片机属于微处理器库里面的,因此,应再点击Microprocessor ICS,后同。

图2. 1题图
程序:
ORG 0H ;程序从程序存储器的0单元开始存放
MAIN: MOV R0,#0 ;设R0为计数器,赋初始值0,注意,在这儿不赋值0,单片机一上电R0也等于0
LOOP: JB P1.4,$ ;若P1.4为高,表明没键按下,等待
JNB P1.4,$ ;若P1.4为低,表明有键按下,等待该键的弹起 INC R0 ;按键弹起后,表明按键一次,计数器加1
CJNE R0,#6,LOOP ;若R0不等于6,表明还没按够5次,继续查询按键信息 MOV R0,#0 ;若R0=6,表明已经被按下5次,计数器清零 CPL P1.0 ;P1.0翻转,即LED 的状态转换 AJMP LOOP ;进入下一个循环 END ;程序结束
图3 调试状态
2. 应用定时器,控制从P1.0和P1.1输出周期为300us 和600us 的方波程序。

本题考虑点:
首先明确为应用定时器,且输出波形为方波,周期300us 和600us ,也就是说,如果用这两个管脚输出波形的话,其翻转的时间分别为150us 和300us 。

然后确定应用定时器的工作方式,对于6MHz 的晶振来说,对于12分频的单片机的机器周期为2us ,即对机器周期的计数分别为75和150,都小于256,因此,可用8位定时器,并且300us 是150us 的整数倍,因此可用一个定时器解决。

在此选用自动装入的8位定时器,即工作方式2,设用T0。

则TMOD 的取值为:
先看TMOD 的各位: GATE C\T M1 M0 GATE C\T M1 M0
因为用T0来计时,且在本题目中T1不用,因此,TMOD 的取值可为:00000010B , 16进制:02H 初始值的计算,应用公式:
6610150102)X 256(--⨯=⨯⨯-
计算得:X=106,16进制为6AH ,即TH0和TL0的赋值都为6AH (因方式2位自动装入模式)
Proteus图:
图4 题2图及调出示波器的位置
程序及解释:
ORG 0H ;程序从程序存储器的0单元开始存放
AJMP MAIN ;跳转至以MAIN为标号的主程序
ORG 0BH ;0B是定时器0的中断子程序入口
AJMP T0INT ;跳转到以T0INT为标号的中断子程序
ORG 30H ;主程序从30H单元开始存放
MAIN: MOV TMOD,#20H ;设置定时器的工作方式,采用工作方式2即自动装入的8位MOV TH0,#8AH ;给TH0赋初值
MOV TL0,#8AH ;给TL0赋初值
SETB EA ;打开总中断
SETB ET0 ;打开T0的中断
SETB TR0 ;让T0开始工作
SJMP $ ;踏步,等待中断
T0INT: CPL P1.0 ;时间到,翻转P1.0
INC R0 ;因为300us正好是150us的整数倍,因而可用一个定时器
CJNE R0,#2,GOON ;用R0作为中断几次的计数器,若中断2次既达到150us的两倍
MOV R0,#0 ;若达到了两倍,翻转,计数器清零
CPL P1.1 ;P1.1翻转
GOON: RETI ;中断子程序返回
END ;程序结束
图5 波形图
3.应用164带3只数码管,显示从000-999的单个跳数;
本题考虑点:
164是移位寄存器,因此最好直接用串口,与164连接;
3位数,可把三位数设为一个计数器,设从30H-32H,其中30H为最低位,31H为中间位,32H为最高位,然后从30H开始加1,当30H加到10后,30H清零,31H再加1,31H为10后,变为零,32H再加1,当32H为10后,清零。

把显示部分编写为一个子程序,30-32H内的数每改变一次,调用一次显示;
由于人的视力跟不上单片机一条指令的运算时间,因此需要延时。

因此,在软件设计上可分为三部分:一是加数部分,一是显示部分,一是延时部分。

Proteus图:
图6 题3图
(注意RXD、TXD的接法,以及后两只164的接法)
程序:
ORG 0H ;程序从程序存储器的0单元开始存放
AJMP MAIN ;跳转到主程序
ORG 30H ;主程序从程序存储器的30H单元开始存放
MAIN: MOV 30H,#0 ;给30H单元赋初始值0
MOV 31H,#0 ;给31H单元赋初始值0
MOV 32H,#0 ;给32H单元赋初始值0
LOOP: INC 30H ;30H单元内的数加1
MOV R1,30H ;将30H单元内的数赋值给R1,以便应用CJNE Rn,#DATA,REL语言判断并跳转
CJNE R1,#10,NEXT ;若30H内的数不是10则跳转到调用显示
MOV 30H,#0 ;若30H内的数是10,则清零
INC 31H ;上位30H的数等于10时,下一位31H加1
MOV R1,31H ;将31H内的数赋值给R1
CJNE R1,#10,NEXT ;间接地判断31H内的数是否等于10,如不是,转显示
MOV 31H,#0 ;若31H等于10,则清零,将32H加1
INC 32H ;32H加1(此为最高位)
MOV R1,32H ;判断32H的数值
CJNE R1,#10,NEXT ;间接判断32H内的数是否等于10,不是转显示
MOV 32H,#0 ;若是32H清零
NEXT: ACALL DISPLAY ;调用显示子程序
ACALL DELAY ;调用延时子程序
SJMP LOOP ;跳转到加1部分,循环
DISPLAY:MOV R0,#30H ;将显示数据的存放首单元赋值给R0,以便调用循环将数值赋值给A MOV DPTR,#TAB ;将显示码的首地址赋值给DPTR
DISLOP:MOV A,@R0 ;将以R0内的数30H内的数值赋值给A
MOVC A,@A+DPTR ;查表语句,将显示码赋值给A
MOV SBUF,A ;将显示码通过串行口送出去
JNB TI,$ ;如果TI不等于1,表明还没送出去,等待
CLR TI ;若TI=1表明数据已经送走,将送走的标志位TI清零,以便进行下次输送INC R0 ;指向下一单元
CJNE R0,#33H,DISLOP ;判断是否将3个单元(30H,31H,32H)的数据都送完
RET ;子程序返回
DELAY: MOV R7,#0 ;延时子程序,给R7赋值0(相当于256)
DEL1: MOV R6,#0 ;给R6赋值0
DJNZ R6,$ ;若R6-1不等于0,在此语句循环
DJNZ R7,DEL1 ;如R0=0则判断R7-1是否为零,不为零则跳转到DEL1,给R6重新赋值RET ;子程序返回
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;显示码表
END ;程序结束
图7 运行状态图
4.应用双机通讯,实现在A机上的数码管数字加到按另一键时的将该数发送到B机的数码管上显示。

本题考虑点:
双机通讯,串行口的通讯方式设置;
设采用串行口方式1,则需要设置波特率,应用T1的工作方式2;
双机都带一只数码管;
主机带3只按键。

Proteus图:
此处由于用P0口带数码管,因此因在P0各管脚上加上拉电阻,此处用排阻respack-8;公共端接高。

图8 题4图
编程考虑:
波特率生成器用T1的工作模式2,波特率选用9600,晶振6MHz,则TH1和TL1的赋值为0F4H,SCON 选用工作模式1,且可接收。

TMOD= #20H
SCON=50H
编程:
主机程序:
ORG 0H ;程序从程序存储器的0单元开始存放
AJMP MAIN ;跳转到以MAIN为标号的程序去
ORG 30H ;以下程序从程序存储器的30H开始存放
MAIN: MOV TMOD,#20H ;选用定时器2工作模式,即自动赋初始值的8位定时器MOV TH1,#0F4H ;给TH1赋值0F4H;
MOV TL1,#0F4H ;给TL1赋值0F4H;
SETB EA ;打开总中断允许位;
SETB ET1 ;打开定时器1的中断允许位;
SETB TR1 ;使定时器1运行
MOV SCON,#50H ;设置串行口的工作模式,采用模式1
MOV DPTR,#TAB ;赋值显示码表的首地址
MOV R0,#0 ;设置R0为显示数字的计数器
MOV R1,#0 ;R1设置为讯显示码的中转寄存器
KEYSCAN:JB P1.0,KEY1 ;若按键1没有被按下,转去查询键2
JNB P1.0,$ ;如键1被按下,则等待键1弹起
INC R0 ;键1弹起后,显示数加1
CJNE R0,#10,NEXT ;如显示数等于10,则从0开始
MOV R0,#0 ;清零
NEXT: MOV A,R0 ;将显示的数给A
MOVC A,@A+DPTR ;查表取显示的码值
MOV R1,A ;将码值给R1暂存
MOV P0,A ;将显示码值给P0显示
key1: JB P1.1,KEYSCAN ;检测第二个按键按下没有
JNB P1.1,$ ;按下了等待弹起
MOV A,R1 ;将显示码给A
MOV SBUF,A ;将显示码送去串行口
JNB TI,$ ;若TI不等于1,表明正在发送中
CLR TI ;TI=1,则表明已经发送完毕,将标志位清零,以便下次发送
SJMP KEYSCAN ;继续检测有按键是否被按下
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;显示码
END ;程序结束
从机程序:
ORG 0H ;程序从程序存储器的0单元开始存放
AJMP MAIN ;跳转到以MAIN为标号的程序去
ORG 30H ;以下程序从程序存储器的30H开始存放
MAIN: MOV TMOD,#20H ;选用定时器2工作模式,即自动赋初始值的8位定时器MOV TH1,#0F4H ;给TH1赋值0F4H;
MOV TL1,#0F4H ;给TL1赋值0F4H;
SETB EA ;打开总中断允许位;
SETB ET1 ;打开定时器1的中断允许位;
SETB TR1 ;使定时器1运行
MOV SCON,#50H ;设置串行口的工作模式,采用模式1
LOOP: JNB RI,$ ;若RI不等于1,表明无数据通过串行口送入
CLR RI ;如RI=1,表明有数据送入,将RI清零,以便下次接收
MOV A,SBUF ;将串行口接收到的数据给A
MOV P0,A ;A将接收到的数据传送给P0,显示
SJMP LOOP ;继续等待接收到数据
END ;程序结束
图9 题4运行状态图
5.应用外部中断,对连接在P3.2管脚上的按键次数进行计数,每5次在P1.
0上连接的绿色LED亮或不亮。

本题考虑点:
要求应用外部中断,则必须应用中断子程序,且在子程序内计数,满5次让P1.0翻转。

Proteus图:
图10 题5图
编程:
ORG 0H ;程序从程序存储器的0单元开始存放
AJMP MAIN ;跳转到以标号为MAIN处
ORG 03H ;外部中断0的9子程序入口
AJMP INT0 ;调用外部中断子程序INT0
ORG 30H ;主程序从程序存储器的30H单元开始存放MAIN: SETB EA ;打开总中断
SETB EX0 ;打开外部中断0的中断
SETB IT0 ;将外部中断0的触发信号设置为下降沿
SJMP $ ;在此等待中断发生
INT0: INC R0 ;用R0作为计数器,每中断一次加1
CJNE R0,#5,NEXT ;若没中断5次返回,等待下一次
MOV R0,#0 ;将计数器清零
CPL P1.0 ;将P1.0翻转
NEXT: RETI ;中断子程序返回
END ;程序结束
图11 题5运行状态图
6.应用计数器,对连接在P3.4管脚上的按键次数进行计数,每5次在P1.0上连接的黄色LED亮或不亮。

本题考虑点:
题意用计数器,且在P3.4管脚上,即应用计数器T0;
未说明用查询还是中断方式,本题选用中断方式。

Proteus图:
图12 题6图
程序:
ORG 0H ;主程序入口
AJMP MAIN ;跳转到以MAIN为标号的程序
ORG 0BH ;计数器中断0的子程序入口
AJMP INT0 ;调用外部中断子程序INT0
ORG 30H ;主程序从程序存储器的30H单元开始存放MAIN: MOV TMOD,#06H ;设置计数器为8位自动装入模式MOV TH0,#251 ;设置TH0初始值为256-5=251
MOV TL0,#251 ;设置TL0同上
SETB EA ;打开总中断
SETB ET0 ;打开计数器0的中断
SETB TR0 ;将计数器0打开
MOV R0,#0 ;给R0赋值0
SJMP $ ;在此等待中断发生
INT0: CPL P1.0 ;将P1.0翻转
NEXT: RETI ;中断子程序返回
END ;程序结束
图6 运行状态图
11。

相关文档
最新文档