1、单片机原理及应用单片机原理及应用北京化工大学北京化工大学信息科学与技术学院信息科学与技术学院主讲教师:郭青主讲教师:郭青E-mail: guoqingmail.buct.edu,cn第五章第五章 80C51单片机的程序设计单片机的程序设计5.15.1 概述概述一、计算机语言一、计算机语言-机器语言、汇编语言与高机器语言、汇编语言与高级语言级语言1.机器语言机器语言2.汇编语言汇编语言3.高级语高级语言言二、二、 汇编语言汇编语言1.1.汇编语言语句的种类和格式汇编语言语句的种类和格式2.2.伪指令语句伪指令语句 5.35.3 汇编语言程序设计汇编语言程序设计一、一、 顺序结构程序顺序结构程序1
2、. 数据传送和交换数据传送和交换例例1:对:对R0R3工作寄存器清工作寄存器清“0”, R4R5置成全置成全“1”,对对P1口清口清“0”,片内,片内RAM中中30H、40H单元清单元清“0”。 ORG 1000HMOV R0,#00H ; (R0) 0MOV R1,#00H ; (R1) 0MOV R2,#00H ; (R2) 0MOV R3,#00H ; (R3) 0MOV P1,#00H ; (P1) 0MOV R4,#0FFH ; (R4) 0FFHMOV R5,#0FFH ; (R5) 0FFHMOV 30H,#00H ; (30H) 0MOV 40H,#00H ; (40H) 0
3、END ; 结束结束例例2:将:将R3与与R5内容互换,内容互换,R4与与35H单元内容互换,程序段单元内容互换,程序段如下如下XCHR:XCH A,R3 XCH A,R5 XCH A,R3 ; R3与与R5内容互换内容互换 XCH A,R4 XCH A,35H XCH A,R4 ; R4与与35H单元内容互换单元内容互换2. 2. 简单运算程序简单运算程序例例1. 双字节加法程序段,设被加数与加数均存放于片内双字节加法程序段,设被加数与加数均存放于片内RAM中。中。 被加数存放于被加数存放于addr1(低位字节)、(低位字节)、addr2(高位字节),(高位字节), 加数存放于加数存放于ad
4、dr3(低位字节)、(低位字节)、 addr4(高位字节),(高位字节), 将运算结果将运算结果和数和数存于存于addr1和和addr2中。中。程序段如下程序段如下: START:PUSH ACC ;将将A中内容进栈保护中内容进栈保护 MOV R0,addr1 ; 将将addr1地址值送地址值送R0 MOV R1,addr3 ; 将将addr3地址值送地址值送R1 MOV A,R0 ;被加数低字节内容送;被加数低字节内容送A ADD ADD A,R1 ;低字节数相加;低字节数相加 MOV R0,A ;低字节数和存;低字节数和存addr1中中 INC R0 ;指向被加数高位字节;指向被加数高位字
5、节 INC R1 ;指向加数高位字节;指向加数高位字节 MOV A,R0 ;被加数高位字节送;被加数高位字节送A ADDC A,R1 ;高字节数相加;高字节数相加 MOV R0,A ;高字节数和存;高字节数和存addr2中中 POP ACC ;恢复;恢复A原内容原内容例例2. 双字节乘法双字节乘法内部内部RAM中中被乘数:被乘数:addr1(低位字节),(低位字节),addr2(高位字节)(高位字节)乘数:乘数: addr3(低位字节),(低位字节),addr4(高位字节)(高位字节)乘积:由低到高乘积:由低到高 addr1,addr2,addr3,addr4分析分析设被乘数设被乘数 AH A
6、L 乘数乘数 BH BL HLL LLL HHL LHL HLH LLH + HHH LHH RES3 RES2 RES1 RES0 addr4 addr3 addr2 addr1 双字节乘法程序段双字节乘法程序段START: PUSH PSW ;PSW、A、B入栈入栈 PUSH ACC PUSH B MOV PSW, #18H ;选用工作寄存器组选用工作寄存器组3 MOV R0, #addr1 ;被乘数低字节地址送被乘数低字节地址送R0 MOV R1, #addr3 ; 乘数低字节地址送乘数低字节地址送R1 MOV A, R0 ;被乘数低字节内容送被乘数低字节内容送 MOV , R1 ;乘数
7、低字节内容送乘数低字节内容送 MUL AB ;低字节内容低字节内容AL*BL MOV R7,A ;积的最低字节积的最低字节RES0存入存入R7中中 MOV R2,B ;高字节高字节HLL送送R2INC R0;指向被乘数高字节指向被乘数高字节addr2MOV A,R0 ;被乘数高字节送被乘数高字节送MOV B,R1 ;乘数低字节送乘数低字节送MUL AB ;AH*BLADD A,R2 ;LHL+HLLMOV R2,A ; LHL+HLL之和之和RES1送送R2MOV A,B ;HHL送送AADDC A,#00H ;HHL+CYMOV R3, A ;HHL送送R3DEC R0 ;指向指向addr1
8、,被乘数低字节,被乘数低字节ALINC R1 ;指向指向addr4 ,乘数高字节,乘数高字节BHMOV A,R0 ;AL送累加器送累加器AMOV B, R1 ;BH送送BMUL AB ;AL*BHADD A,R2 ;LLH+(R2)(R2)=HLL+LHLMOV R2,A ;LLH+LHL+HLL之和送之和送R2MOV A,B ;HLH送送AADDC A,R3 ;HLH+HHL+CYMOV R3,A ; HLH+HHL+CY之和送之和送R3MOV R4 ,#0 ;清清R4JNC LOOP ;判判CY,CY=0转转LOOPINC R4 ;CY=1,则,则R4 (R4) +1LOOP:INC R0
9、 ;指向指向addr2, i.e. AHMOV A,R0 ;AH送送AMOV B,R1 ;BH送送BMUL AB ;AH*BHADD A,R3;LHH+HLH+HHL=RES2MOV R3,A;RES2送送R3MOV A,B ;HHH送送AADDC A,R4 ;(R4)+HHH=RES3MOV R1,A;最高字节最高字节RES3存入存入addr4中中MOV A,R2MOV R0,A;RES1存入存入addr2中中DEC R1 ;指向指向addr3MOV A,R3MOV R1, A;RES2存入存入addr3中中DEC R0;指向;指向addr1MOV A, R7MOV R0, A;RES0存入
10、存入addr1中中POP B ;B、A、PSW出栈出栈POP ACCPOP PSW3.查表程序查表程序例例1.设表中有设表中有1024个元素,每个元素为两个字节,则表格总长为个元素,每个元素为两个字节,则表格总长为2048个字节。现按个字节。现按R4和和R5的内容从表格中查出对应的数据元的内容从表格中查出对应的数据元素值,送存素值,送存R4和和R5中。中。程序如下:程序如下:TBDP1:MOV DPTR,#addr16 ;表格首地;表格首地 址值送址值送DPTRMOV A,R5;查表参数低位字节送;查表参数低位字节送ACLR C ;清;清CYRLC A ;带进位左移一位;带进位左移一位XCH
11、A,R4 ;将查表参数;将查表参数R4内容送内容送ARLC A ;带进位左移一位;带进位左移一位XCH A,R4 ;A与与R4内容互换内容互换ADD A,DPL;DPL+查表参数低位字节查表参数低位字节MOV DPL,A;调整;调整DPL、DPHMOV A,DPH;DPH送送AADDC A,R4 ;DPH+查表参数高位字节查表参数高位字节MOV DPH,A ;相加和存相加和存DPHCLR A ;清清AMOVC A,A+DPTR ;查表,读第一字节查表,读第一字节MOV R4,A ;第一字节存入第一字节存入R4CLR A ;清清AINC DPTR ;(DPTR)+1MOVC A,A+DPTR ;
12、查表,读第二字节查表,读第二字节MOV R5,A ;第二字节存入第二字节存入R5RET ;返返回回TBDP2:DW ;数据表数据表 DW二二、 选择结构程序选择结构程序1.1.单分支选择结构单分支选择结构例例1.求双字节补码程序求双字节补码程序分析:按位取反分析:按位取反+1得补码。低位字节,直接求补。得补码。低位字节,直接求补。 高位字节:低字节为高位字节:低字节为0,求补;不为,求补;不为0,则取反。,则取反。START:MOV R0,#addr1 ;原码低字节地址码送原码低字节地址码送R0 MOV R1,#addr2 ;补码低字节地址码送补码低字节地址码送R1 MOV A,R0 ;原码低
13、字节内容送原码低字节内容送A CPL A ;A内容取反内容取反+1;即取补;即取补 INC A MOV R1,A ;低字节补码存低字节补码存addr2单元单元INC R0 ;指向原码高字节;指向原码高字节INC R1 ;指向补码高字节;指向补码高字节JZ LOOP1 ;判;判(A)=0?当?当(A)=0转转LOOP1MOV A,R0;原码高字节送;原码高字节送ACPL A ;高字节内容取反;高字节内容取反MOV R1 ,A ;高字节反码存;高字节反码存addr2+1单元单元SJMP LOOP2 ;转;转LOOP2,结束,结束LOOP1:MOV A,R0 ;低字节补码为;低字节补码为0 CPL
14、A ;对高字节数取补;对高字节数取补 INC A MOV R1,A ;高字节补码存;高字节补码存addr2+1单元单元LOOP2: END ;结束;结束2.多分支选择结构多分支选择结构(1)结构类型结构类型 判别部分有两个以上的出口流向判别部分有两个以上的出口流向(2) 程序结构程序结构例如,由例如,由40H单元中动态运行结果值来选择分支程序,其对单元中动态运行结果值来选择分支程序,其对应关系如:应关系如:(40H)=0,转处理程序,转处理程序0(40H)=1,转处理程序,转处理程序1(40H)=n,转处理程序,转处理程序n其程序段如下:其程序段如下:START:MOV DPTR,#ADDR1
15、6;多分支转移程序首址多分支转移程序首址 送送DPTR MOV A,40H ;40H单元内容送单元内容送A CLR C ;清清CY RLC A ;A内容左移一位内容左移一位 JNC TABEL ;若若CY=0,转,转TABEL INC DPH ;若若CY=1,DPH内容内容+1TABEL:JMP A+DPTR ;多分支转移多分支转移ADDR16:AJMP LOOP0;转移表转移表 AJMP LOOP1 AJMP LOOPn如果转移表由如果转移表由3字节字节LJMP指令构成,程序段修改为:指令构成,程序段修改为:START:MOV DPTR,#ADDR16 ;分支程序段首址送;分支程序段首址送D
16、PTR MOV A,40H ;选择参量送;选择参量送A MOV B,#03H ;乘数;乘数3送入送入B MUL AB ;选择参量;选择参量*3 MOV R3,A ;乘积低;乘积低8位暂存位暂存R3中中 MOV A, B ;乘积高;乘积高8位送位送A ADD A,DPH ;乘积高;乘积高8位加到位加到DPH中中 MOV DPH,A MOV A,R3 JMP A+DPTR ;多分支选择;多分支选择ADDR16:LJMP LOOP0 ;分支转移表;分支转移表 LJMP LOOP1 LJMP LOOPn 当分支数超过当分支数超过256个时,则需用两个字节单元来存放选择参量,个时,则需用两个字节单元来存
17、放选择参量,并需对选择参量的高位字节进行处理,即把它加到并需对选择参量的高位字节进行处理,即把它加到DPH中去。中去。设设41H(高位字节高位字节)、40(低位字节低位字节)存放选择参数。其程序段如存放选择参数。其程序段如下:下:START:MOV DPTR,#ADDR16;分支程序首址送分支程序首址送DPTR MOV A,40H ;选择参量低字节送选择参量低字节送A MOV B,#03H ;乘数乘数3送入送入B MUL AB MOV R3,A ;乘积低字节内容送乘积低字节内容送R3 MOV A,B ;乘积高字节内容送乘积高字节内容送AADD A,DPH ;DPH+高字节内容高字节内容MOV
18、DPH,AMOV A,41H ;选择参量高字节内容送选择参量高字节内容送AMOV B,#03H ;乘数乘数3送入送入B MUL AB ;选择参量高字节内容乘选择参量高字节内容乘3ADD A,DPH;DPH+乘积低字节内容乘积低字节内容MOV DPH,A;和送和送DPHMOV A,R3 ;选择参量低字节内容送选择参量低字节内容送AJMP A+DPTR;选转移分支选转移分支ADDR16:LJMP LOOP0;3字节转移指令表字节转移指令表 LJMP LOOP1 LJMP LOOPn例例2. 存放于存放于addr1和和addr2中的两个无符号二进制数,求其中中的两个无符号二进制数,求其中的大数并存于
19、的大数并存于addr3中,其程序段如下:中,其程序段如下:TART :MOV A,addr1 ;将;将addr1中的内容送中的内容送A CJNE A,addr2,LOOP1 ;两数比较,不相等则;两数比较,不相等则转转LOOP1LOOP3:RET ;结束;结束LOOP1:JC LOOP2 ;当;当CY=1,转,转LOOP2 MOV addr3,A ;CY=0, (A) (addr2) SJMP LOOP3 ;转结束;转结束LOOP2:MOV addr3, addr2 ;CY=1,(addr2)(A) SJMP LOOP3三、三、 循环结构程序循环结构程序1.计数控制循环结构计数控制循环结构例例
20、1.采用循环程序进行软件延时,延时子程序如下:采用循环程序进行软件延时,延时子程序如下: DELAY: MOV R2,#data ;预置循环控制常数预置循环控制常数 LOOP:DJNZ R2,LOOP ;当当(R2) 0,转向本身,转向本身 RET例例2.工作单元清零程序段。工作单元清零程序段。 设设R1中存放欲清零字节单元首地址,中存放欲清零字节单元首地址, R3中存放欲清零的字节数。中存放欲清零的字节数。START:MOV R3,#data;清清0的字节数送的字节数送R3 MOV R1,#addr;被清被清0字节的首地址字节的首地址 CLR A ;清清0累加器累加器LOOP: MOV R1
21、,A ;指定单元清指定单元清0 INC R1 DJNZ R3,LOOP;(R3) 1 0,继续清,继续清0 END例例3.多字节无符号数加法程序多字节无符号数加法程序设被加数低字节地址存设被加数低字节地址存R0中,加数低字节地址存中,加数低字节地址存R1中,字节数中,字节数存存R3中。相加的结果依次存于原被加数单元。加法程序段如下中。相加的结果依次存于原被加数单元。加法程序段如下START:MOV A,R0 ;保存被加数首地址到;保存被加数首地址到R5 MOV R5,A MOV A,R3 ;传送字节数给;传送字节数给R7 MOV R7,A CLR CADDT:MOV A,R0 ADDC A,
22、R1 ;做加法;做加法 MOV R0,A ;部分和存入对应的被加数单元;部分和存入对应的被加数单元 INC R0 ;指向下一个字节单元;指向下一个字节单元 INC R1 DJNZ R7,ADDT ;若;若(R7) 1 0,继续做加法,继续做加法JNC ADDB ;若最高位相加无进位,则转;若最高位相加无进位,则转ADDBINC R3 ;有进位;有进位(CY),字节数加,字节数加1MOV R0,#01H;最高进位位存入被加数下一单元;最高进位位存入被加数下一单元ADDB:MOV A,R5;和数低字节地址送;和数低字节地址送AMOV R0,A ;A送送R0,为读取和数做准备,为读取和数做准备END
23、 ;结束;结束2.条件控制循环结构条件控制循环结构例例1.设某系统的设某系统的ADC0809的转换结束信号的转换结束信号EOC与与80C51的的P1.7相连。当相连。当EOC(P1.7)的状态由低变高,则结束循环)的状态由低变高,则结束循环等待,读取转换结果值,其程序段如下:等待,读取转换结果值,其程序段如下:START:MOV DPTR,#addr ;0809端口地址送端口地址送DPTR MOV A,#00H ;启动;启动0809的的0号通道号通道 MOVC DPTR,A LOOP: JNB P1.7,LOOP ;检测检测 P1.7状态状态 MOVX A,DPTR ;读取转换结果值送读取转换
24、结果值送A3.多重循环结构多重循环结构例例1. 实现较长时间的延时。实现较长时间的延时。延时程序段如下:延时程序段如下:START:MOV R3,#data1;外层循环计数初值;外层循环计数初值LOOP1:MOV R2,#data2;内层循环计数初值;内层循环计数初值LOOP2:NOP NOP DJNZ R2,LOOP2;(R2) 10,转,转LOOP2 DJNZ R3,LOOP1;(R3) 10,转,转LOOP1 END四、四、 子程序子程序1.子程序及其调用子程序及其调用1)调用前保护,返回后恢复)调用前保护,返回后恢复 这种方式是在主程序的调用指令之前进行现场保护;在调用这种方式是在主程
25、序的调用指令之前进行现场保护;在调用指令之后,即返回断点后进行现场恢复。其主程序结构如下指令之后,即返回断点后进行现场恢复。其主程序结构如下程序段所示程序段所示:PUSH PSW ;将将PSW、ACC、B等压栈保护等压栈保护PUSH ACCPUSH BMOV PSW,#10H ;选用工作寄存器;选用工作寄存器2,将组,将组0保护保护ACALL addr11 ;调用子程序;调用子程序addrPOP B ;恢复;恢复PSW、ACC、B内容内容POP ACCPOP PSW2)调用后保护,返回前恢复)调用后保护,返回前恢复这种方式是在主程序调用后,在子程序的开始部分,进行必要的这种方式是在主程序调用后
26、,在子程序的开始部分,进行必要的现场保护;而子程序结束,返回指令前进行现场恢复。这是常现场保护;而子程序结束,返回指令前进行现场恢复。这是常用方式,设子程序首地址为用方式,设子程序首地址为addr,其子程序段如下所示。,其子程序段如下所示。addr:PUSH PSW ;现场保护;现场保护 PUSH ACC PUSH B MOV PSW,#14H ;选用工作寄存器组;选用工作寄存器组3,组,组0保护保护 : POP B POP ACC ;现场恢复;现场恢复 POP PSW2. 常用子程序举例常用子程序举例例例1.单字节无符号二进制整数转换成三位压缩型单字节无符号二进制整数转换成三位压缩型BCD码
27、码入口参数:待转换无符号二进制整数存于入口参数:待转换无符号二进制整数存于R4中。中。出口参数:三位出口参数:三位BCD码存于码存于R5,R4中。中。子程序如下:子程序如下:BINBCD:PUSH PSW PUSH ACC ;现场保护现场保护 PUSH B MOV A,R4 ;二进制整数送二进制整数送A MOV B,#100 ;十进制数十进制数100送送B DIV AB ;(A)/100,以确定百位数,以确定百位数 MOV R5,A ;商商(百位数百位数)存于存于R5中中 MOV A,#10 ;将将10送送A XCH A,B ;将将10和和B中余数互换中余数互换 DIV AB ; (A)/10
28、得十、个位数得十、个位数 SWAP A ;将将A中商中商(十位数十位数)移入高移入高4位位 ADD A,B ;将将B中余数中余数(个位数个位数)加到加到A中中 MOV R4,A ;将十、个位将十、个位BCD码存入码存入R4POP B POP ACC ;恢复现场恢复现场POP PSWRET ;返回返回例例2:单字节码整数转换成单字节十六进制整数:单字节码整数转换成单字节十六进制整数入口参数:待转换的单字节入口参数:待转换的单字节C码整数在累加器码整数在累加器A中。中。出口参数:转换后的单字节十六进制整数仍在累加器出口参数:转换后的单字节十六进制整数仍在累加器A中。中。影响资源:影响资源:PSW、
29、A、B、R4 堆栈需求:堆栈需求: 字节字节BCDH: MOV B, #10H ;分离十位和个位分离十位和个位 DIV AB MOV R4, B ;暂存个位暂存个位 MOV B, #10 ;将十位转换成十六进制将十位转换成十六进制 MUL AB ADD A, R4 ;按十六进制加上个位按十六进制加上个位 RET例例3:双字节码整数转换成双字节十六进制整数:双字节码整数转换成双字节十六进制整数入口参数:待转换的双字节码整数在入口参数:待转换的双字节码整数在R2、R3中。中。出口参数:转换后的双字节十六进制整数仍在出口参数:转换后的双字节十六进制整数仍在R2、R3中。中。 BH2: MOV A,
30、R3 ;将低字节转换成十六进制将低字节转换成十六进制 LCALL BCDH MOV R3, A MOV A, R2 ;将高字节转换成十六进制将高字节转换成十六进制 LCALL BCDH MOV B, #100 ;扩大一百倍扩大一百倍 MUL AB ADD A, R3 ;和低字节按十六进制相加和低字节按十六进制相加 MOV R3, A CLR A ADDC A, B MOV R2, A RET五、中断服务程序五、中断服务程序关中断,保护现场;然后开中断,执行中断服务程序。关中断,保护现场;然后开中断,执行中断服务程序。功能程序执行完,关中断,恢复现场;开中断,返回。功能程序执行完,关中断,恢复现
31、场;开中断,返回。例例1.试编写串行接口以工作方式试编写串行接口以工作方式2发送数据的中断服务程序。发送数据的中断服务程序。START:CLR 0AFH ;关中断关中断 PUSH PSW ;保护现场保护现场 PUSH ACC SETB 0AFH ;开中断开中断 SETB PSW.4 ;切换寄存器工作组切换寄存器工作组 CLR T1 ;清除发送中断请求标志清除发送中断请求标志MOV A,R0 ;取数据,且置奇偶标志位取数据,且置奇偶标志位MOV C,P ;送偶位送偶位MOV TB8,C MOV SBUF,A;数据写入发送缓冲器,启动发送数据写入发送缓冲器,启动发送INC R0 ;数据地址指针数据地址指针R0加加1CLR 0AFH ;恢复现场恢复现场POP ACCPOP PSWSETB 0AFHCLR PSW.4 ;切换寄存器工作组切换寄存器工作组RETI ;中断返回中断返回