单片机第四章示例程序
- 格式:pdf
- 大小:243.58 KB
- 文档页数:10
第4章MCS-51程序设计例题解析【例4-1】已知16位二进制负数存放在R1、R0中,试求其补码,并将结果存放在R3、R2中。
解:二进制负数的求补方法可归结为“求反加1”,符号位不变。
利用CPL指令实现求反;加1时,则应低8位先加1,高8位再加上低位的进位。
注意这里不能用INC指令,因为INC 指令不影响标志位。
程序如下:CONT: MOV A, R0 ;读低8位CPL A ;取反ADD A, #1 ;加1MOV R2, A ;存低8位MOV A, R1 ;读高8位CPL A ;取反ADDC A, #80H ;加进位及符号位MOV R3, A ;存高8位RET ;返回【例4-2】将两个半字节数合并成一个1字节数。
解:设内部RAM的40H、41H单元中分别存放着8位二进制数。
要求取出两个单元中的低半字节,合并成一个字节后,存放在42H单元中。
程序如下:ORG 0000HSTART:MOV R1, #40HMOV A, @R1ANL A, #0FH ;取第一个半字节SWAP AINC R1XCH A, @R1 ;取第二字节ANL A, #0FH ;取第二个半字节ORL A, @R1 ;拼字INC R1MOV @R1, A ;存放结果SJMP $END【例4-3】拆字程序。
ORG 0000HSTART:MOV R1, #40HMOV A, @R1MOV B, A ;暂存B中ANL A, #0FH ;取第一个半字节INC R1MOV @R1, A ;存放第一个半字节MOV A, BSWAP AANL A, #0FH ;取第二个半字节INC R1MOV @R1, A ;存放第二个半字节SJMP $END【例4-4】求单字节有符号二进制数的补码。
解:正数的补码是其本身,负数的补码是其反码加1。
因此,程序首先判断被转换数的符号,负数进行转换,正数即为补码。
设二进制数放在累加器A中,其补码放回到A中。
程序如下:ORG 0000HCMPT:JNB ACC.7, NCH ;(A)>0,不需转换CPL AADD A, #1SETB ACC.7 ;保存符号NCH:SJMP $END【例4-5】两个无符号数比较大小。
解:设两个连续外部RAM单元ST1和ST2中存放不带符号的二进制数,找出其中的大数存入ST3单元中。
程序如下:ORG 8000HST1 EQU 8040HSTART1:C LR C ;进位位清零MOV DPTR, #ST1 ;设数据指针MOVX A, @DPTR ;取第一个数MOV R2, A ;暂存R2INC DPTRMOVX A, @DTPR ;取第二个数SUBB A, R2 ;两数比较JNC BIG1XCH A, R2 ;第一个数大BIG0:I NC DPTRMOVX @DPTR, A ;存大数SJMP $BIG1:M OVX A, @DPTR ;第二个数大SJMP BIG0END【例4-6】多个单字节数据求和。
已知有10个单字节数据,依次存放在以内部RAM的50H单元开始的连续单元中。
要求把计算结果存入R2、R3中(高位存R2,低位存R3)。
解:程序如下:ORG 8000HSAD:MOV R0, #50H ;设数据指针MOV R5, #0AH ;计数值0AH→R5SAD1:MOV R2, #0 ;和的高8位清零MOV R3, #0 ;和的低8位清零LOOP:MOV A, R3 ;取加数ADD A, @R0MOV R3, A ;存和的低8位JNC LOP1INC R2 ;有进位,和的高8位+1LOP1:INC R0 ;指向下一个数据地址DJNZ R5, LOOPSJMP $END【例4-7】内部RAM单元清零。
要求:将60H为起点的9个单元清“0”。
解:程序如下:ORG 0000HCLEAR:CLR A ;A清0MOV R0, #60H ;确定清0单元起始地址MOV R6, #09 ;确定要清除的单元个数LOOP:MOV @R0, A ;清单元INC R0 ;指向下一个单元DJNZ R6, LOOP ;控制循环SJMP $END【例4-8】外部RAM单元清零。
要求:设有40个外部RAM单元要清“0”,即为循环次数存放在R2寄存器中,其首地址存放在DPTR中,设为3000H。
解:程序如下:ORG 0000HMOV DPTR, #3000HCLEAR:CLR AMOV R2, #28H ;置计数值LOOP:MOVX @DPTR, AINC DPTR ;修改地址指针DJNZ R2, LOOP ;控制循环END多重循环程序【例4-9】10秒延时程序。
延时程序与MCS-51执行指令的时间有关,如果使用6MHz晶振,一个机器周期为2μs,计算出执行一条指令以至一个循环所需要的时间,给出相应的循环次数,便能达到延时的目的。
程序如下:DEL:MOV R5, #100 ;1DEL0:MOV R6, #100 ;1DEL1:MOV R7, #249 ;1DEL2:DJNZ R7, DEL2 ;248*2DJNZ R6, DEL1 ;(248*2+1+2)*100DJNZ R5, DEL0 ;[(248*2+1+2)*100+1+2]*100RET【例4-10】请编出能把20H单元内两个BCD数变换成相应ASCII码放在21H(高位BCD数的ASCII码)和22H(低位BCD数的ASCII码)单元的程序。
解:根据ASCII字符表,0~9的BCD数和它们的ASCII码之间仅相差30H。
因此,仅需把20H 单元中两个BCD数拆开,分别和30H相加即可,可以编出程序如下:ORG 0000HASC1:MOV R0, #22HMOV @R0, #00HMOV A, 20HXCHD A, @R0ORL 22H, #30HSWAP AORL A, #30HMOV 21H, ASJMP $END【例4-11】一位十六进制数转换为ASCII码子程序。
解:程序如下:HASC:MOV R0, SPDEC R0DEC R0 ;R0为参数指针XCH A, @R0 ;保护ACC,取出参数ANL A, #0FHADD A, #2 ;加偏移量MOVC A, @A+PCXCH A, @R0 ;将查表结果放回堆栈中RETDB '0123456789' ;十六进制数的ASCII字符表DB 'ABCDEF'END【例4-12】把内部RAM中50H、51H的双字节十六进制数转换为4位ASCII码,存放于(R1)指向的4个内部RAM单元。
解:编写程序时可以将例4-10当作子程序调用,子程序名为HASC。
HA24:MOV A, 50HSWAP APUSH ACCACALL HASCPOP ACCMOV @R1, AINC R1PUSH 50HACALL HASCPOP ACCMOV @R1, AINC R1MOV A, 51HSWAP APUSH ACCACALL HASCPOP ACCMOV @R1, AINC R1PUSH 51HACALL HASCPOP ACCMOV @R1, AEND【例4-13】一个字节的两位十六进制数转换为两个ASCII码子程序。
解:参考程序如下:ORG 0000HHTA2:MOV R0, SPDEC R0DEC R0PUSH ACC ;保护累加器内容MOV A, @R0 ;取出参数ANL A, #0FHADD A, #12 ;加偏移量MOVC A, @A+PCXCH A, @R0 ;低位HEX的ASCII码放入堆栈中SWAP AANL A, #0FHADD A, #5 ;加偏移量MOVC A, @A+PCINC R0XCH A, @R0 ;高位HEX的ASCII码放入堆栈中INC R0XCH A, @R0 ;高位返回地址放入堆栈,并恢复累加器内容RETDB '0123456789'DB 'ABCDEF'END【例4-14】将内部RAM中50H、51H单元的内容以4位十六进制数的ASCII形式串行发送出去,可调用HTA2子程序。
解:参考程序如下:ORG 0000HSCOT4:PUSH 50HACALL HTA2POP ACCACALL COUTPOP ACCACALL COUTPUSH 51HACALL HTA2POP ACCACALL COUTPOP ACCACALL COUTCOUT:JNB TI, COUT ;字符发送子程序CLR TIMOV SBUF, ARETEND【例4-15】字符串发送子程序。
解:ORG 0000HSOUT:POP DPH ;栈中指针POP DPLSOT1:CLR AMOVC A, @A+DPTRINC DPTRJZ SENDJNB TI, $ ;$为本条指令地址CLR TIMOV SBUF, ASJMP SOT1SEND:JMP @A+DPTREND用MOVC A,@A+PC查表指令编程【例4-16】用查表方法编写彩灯控制程序,编程使彩灯先顺次点亮,再逆次点亮,然后连闪3下,反复循环。
解:程序如下:START: MOV R0, #00HLOOP: CLR AMOV A, R0ADD A, #0CHMOVC A, @A+PCCJNE A, #03H, LOOP1JMP STARTLOOP1: MOV P1, AACALL DELINC R0JMP LOOPTAB: DB 01H, 02H, 04H, 08H, 10H, 20H, 40H, 80HDB 80H, 40H, 20H, 10H, 08H, 04H, 02H, 01HDB 00H, 0FFH, 00H, 0FFH, 00H, 0FFH, 03HDEL: MOV R7, #0FFHDEL1: MOV R6, #0FFHDEL2: DJNZ R6, DEL2DJNZ R7, DEL1RETEND用MOVC A,@A+DPTR查表指令编程【例4-17】用查表方法编写彩灯控制程序,编程使彩灯先顺次点亮,再逆次点亮,然后连闪3下,反复循环。
解:程序如下:START: MOV DPTR, #TABLELOOP: CLR AMOVC A, @A+DPTRCJNE A, #03H, LOOP1JMP STARTLOOP1: MOV P1, AACALL DELINC DPTRJMP LOOPTABLE: DB 01H, 02H, 04H, 08H, 10H, 20H, 40H, 80HDB 80H, 40H, 20H, 10H, 08H, 04H, 02H, 01HDB 00H, 0FFH, 00H, 0FFH, 00H, 0FFH, 03HDEL: MOV R7, #0FFHDEL1: MOV R6, #0FFHDEL2: DJNZ R6, DEL2DJNZ R7, DEL1RETEND用转移指令表实现散转在许多场合中,要根据某一单元的值0, 1, 2, …, n分别转向处理程序0,处理程序1, …,处理程序n。