几个单片机汇编语言教学例程及详细分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最近,我们在课上讲了几个小例子,在此再把Proteus图及程序的详细解释列出来,供大家参考。
1.应用查询方式,对连接在P1.4管脚上的按键次数进行计数,
每5次在P1.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 调试状态
1.应用定时器,控制从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
初始值的计算,应用公式:
计算得: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 波形图
1.应用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 ;调用显示子程序