单片机原理与应用程序.docx
- 文档编号:26132380
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:79
- 大小:34.76KB
单片机原理与应用程序.docx
《单片机原理与应用程序.docx》由会员分享,可在线阅读,更多相关《单片机原理与应用程序.docx(79页珍藏版)》请在冰豆网上搜索。
单片机原理与应用程序
《单片机原理与应用》参考程序
第3章
【例3-49】
MOVDPTR,#2000H;源数据区首址
PUSHDPL;源数据区首址压栈保护
PUSHDPH
MOVDPTR,#3000H;目的数据区首址
MOVR6,DPL;目的数据区首址存入寄存器
MOVR7,DPH
LP:
POPDPH;取源数据区地址指针
POPDPL
MOVXA,@DPTR;取源数据
INCDPTR
PUSHDPL
PUSHDPH;更新源数据地址,并将该新地址压栈保护
MOVDPL,R6;取目的数据区首地址指针
MOVDPH,R7
MOVX@DPTR,A;将取得的源数据存入目的数据区
INCDPTR
MOVR6,DPL
MOVR7,DPH;更新目标数据地址,并将该新地址存入到R6和R7中
DJNZ30H,LP;若数据块未移完(即地址30H中的值不为0),则继续
POPDPH
POPDPL
SJMP$
【例3-65】
MOVA,P1;将8位输入信号传到A中
JBA.0,MM;当A的第0位A.0为1时,转去执行MM
SETBC;当A.0为0时,将C置1并转去执行OUT
SJMPOUT;X0=1,转出口
MM:
MOVC,A.1;C=X1
ANLC,/A.2;X1X2
JCOUT;X1X2=1,转出口
MOVC,A.2;C=X2
ANLC,/A.1;X1X2
JCOUT;X1X2=1,转出口
MOVC,A.7;C=X7
ANLC,/A.4;X4X7
ANLC,/A.5;X4X5X7
ANLC,/A.6;X4X5X6X7
OUT:
MOVP3.0,C
…
3.3实例解析
CLRA;结果单元20H~29H清零
MOVR0,#10
MOVR1,#20H
LP:
MOV@R1,A
INCR1
DJNZR0,LP
MOVR0,#100;100个数的计数器
READ:
MOVA,P1;读入P1
CHK0:
CJNEA,#0,CHK1;比较,不为“0”,继续比较
INC20H;是“0”,则“0”计数单元加1
SJMPEND0;是否全部统计完?
CHK1:
CJNEA,#1,CHK2
INC21H;是“1”,则“1”计数单元加1
SJMPEND0
CHK2:
CJNEA,#2,CHK3
INC22H;是“2”,则“2”计数单元加1
SJMPEND0
CHK3:
CJNEA,#3,CHK4
INC23H;是“3”,则“3”计数单元加1
SJMPEND0
CHK4:
CJNEA,#4,CHK5
INC24H;是“4”,则“4”计数单元加1
SJMPEND0
CHK5:
CJNEA,#5,CHK6
INC25H;是“5”,则“5”计数单元加1
SJMPEND0
CHK6:
CJNEA,#6,CHK7
INC26H;是“6”,则“6”计数单元加1
SJMPEND0
CHK7:
CJNEA,#7,CHK8
INC27H;是“7”,则“7”计数单元加1
SJMPEND0
CHK8:
CJNEA,#8,CHK9
INC28H;是“8”,则“8”计数单元加1
SJMPEND0
CHK9:
CJNEA,#9,ERR
INC29H;是“9”,则“9”计数单元加1
END0:
DJNZR0,READ;判是否全部统计完
HERE:
SJMPHERE
ERR:
…;非0~9,出错
第4章
【例4-13】
START:
PUSHACC;将A中内容进栈保护
MOVR0,20H;将20H地址中的内容送R0
MOVR1,22H;将22H地址的内容送R1
MOVA,@R0;被加数低字节内容送A
ADDA,@R1;低字节数相加
MOV@R0,A;低字节数和存20H中
INCR0;指向被加数高位字节
INCR1;指向加数高位字节
MOVA,@R0;被加数高位字节送A
ADDCA,@R1;高字节数带进位相加
MOV@R0,A;高字节数和存21H中
CLRA
ADDCA,#00H
MOV10H,A;进位暂存于10H中
POPACC;恢复A原内容
【例4-14】
ORG0000H
AJMPSTART
ORG30H
START:
MOVP1,#0FFH;关闭所灯
MOVTMOD,#00000001B;定时/计数器0工作于方式1
MOVTH0,#15H
MOVTL0,#0A0H;即数5536
SETBTR0;定时/计数器0开始运行
LOOP:
JBCTF0,NEXT;如果TF0等于1,则清TF0并转NEXT处
AJMPLOOP;否则跳转到LOOP处运行
NEXT:
CPLP1.0
MOVTH0,#15H
MOVTL0,#9FH;重置定时/计数器的初值
AJMPLOOP
ENDAJMPLOOP
【例4-15】
ORG000BH;定时器0的中断向量地址
AJMPTIME0;跳转到真正的定时器程序处
ORG30H
START:
MOVP1,#0FFH;关闭所灯
MOVTMOD,#00000001B;定时/计数器0工作于方式1
MOVTH0,#15H
MOVTL0,#0A0H;即数5536
SETBEA;开总中断允许
SETBET0;开定时/计数器0允许
SETBTR0;定时/计数器0开始运行
LOOP:
AJMPLOOP;真正工作时,这里可写任意程序
TIME0:
PUSHACC;定时器0的中断处理程序
PUSHPSW;将PSW和ACC推入堆栈保护
CPLP1.0
MOVTH0,#15H
MOVTL0,#0A0H;重置定时常数
POPPSW
POPACC
RETI
END
【例4-17】
ORG0000H
START:
MOVA,#a
MOVB,A
MULAB;AB=a2
MOVR0,A;R1R0=a2
MOVR1,B
MOVA,#b
CJNEA,#0AH,MMN;b≠10则转移
MM:
ADDA,R0;b≥10,a2+b=Y
MOVR0,A
MOVA,#00H
ADDCA,R1
MOVR1,A
JMPMMNN
MMN:
JNCMM;无借位(即b>10)转MM
MOVR3,A;R3←b
MOVA,R0
CLRC
SUBBA,R3;R1R0←a2-b
MOVR0,A
MOVA,R1
SUBBA,#00H
MOVR1,A
MMNN:
MOVY0,R0;Y1Y0←结果
MOVY1,R1
HERE:
AJMPHERE
【例4-18】
CLRC
START:
MOVA,R1
SUBBA,#64H;超过100kg则报警
JNCBJ
MOVA,R1
CJNEA,#32H,LOOP1;是否为50kg
MOVB,#2H
MULAB;50kg总收费
SJMPLOOP3
LOOP1:
JCLOOP2
MOVB,#3H
SUBBA,#32H;超过50kg部分的收费
MULAB
MOVR0,A
MOVA,#32H
MOVB,#2H
MULAB
ADDA,R0;50kg以上总收费
SJMPLOOP3
LOOP2:
MOVB,#2H;50kg以下总收费
MULAB
LOOP3:
MOV80H,A
SJMPEOF
BJ:
…;超重报警程序
【例4-21】
MOVR0,#DATA;数据区首地址
MOVDPTR,#BUFFER;数据区长度指针
LOOP:
MOVA,@R0
CJNEA,#24H,LOOP2;判是否为“$”符(24H)
SJMPLOOP1;是“$”符,则结束
LOOP2:
MOVA,@R0;不是“$”符,则传送
MOVX@DPTR,A
INCR0
INCDPTR
DJNZ20H,LOOP;数据串未查完,继续
LOOP1:
RET
DATA:
…;数据串
【例4-22】
BCDB:
PUSHPSW;现场保护
PUSHA
PUSHB
MOVR3,#00H
MOVA,@R0
MOVR4,A;BCD码千位送R4
LOOP:
MOVA,R4
MOVB,#10
MULAB
MOVR4,A
MOVR5,B
MOVB,#10;(R3)、(R4)×10
XCHA,R3
MULA,B
ADDA,R5
MOVR3,A
XCHA,R4
INCR0
ADDA,@R0
XCHA,R3;(R3R4)+((R0))送R3R4
ADDCA,#0
MOVR4,A
DJNZR2,LOOP1;循环n-1次
POPB;恢复现场
POPA
POPPSW
RET;返回
【例4-23】
FILLE:
PUSHPSW;PSW及A保护入栈
PUSHA
MOVA,20H;取第一个数据
CLRC
SUBBA,21H;与第二个数据比较
JNCLOB1;第一个数据比第二个数据大,转LOB1
MOVA,20H;第一个数据比第二个数据小,交换二个数的位置
XCHA,21H
MOV20H,A
LOB1:
MOVA,22H
CLRC
SUBBA,20H;第三个数据与前二个数据中的较大数比较
JNCLOB3;第三个数据大于前二个数据中的较大数,转LOB3
MOVA,22H
CLRC
SUBBA,21H;第三个数据与前二个数据中的较小数比较
JNCLOB4
MOVA,21H
MOVR0,A
AJMPLOB2
LOB3:
MOVR0,20H
AJMPLOB2
LOB4:
MOVR0,22H
LOB2:
POPA;恢复A和PSW
POPPSW
RET
4.7实例解析
主程序:
ORG0400H
ASCB:
MOVR0,#61H;R0指向原始数据的高位
MOVR1,#70H;存放结果数据
ACALLCVERT;调用转换程序,结果放在A中
SWAPA;结果的高位和低位互换
MOV@R1,A;保存高位
DECR0;R0指向原始数据的低位
ACALLCVERT;再次调用转换程序
XCHDA,@R1;低半字节与高半字节交换
LOOP:
SJMPLOOP
子程序:
ORG0500H
CVERT:
MOVA,@R0
CLRC
SUBBA,#30H
CJNEA,#0AH,NEQ
AJMPBIG
NEQ:
JCCEND
BIG:
SUBBA,#07H;大于0AH时再减去07H
CEND:
RET
END
第5章
【例5-1】
MAIN:
MOVSP,#60H
LOOP:
MOVA,P0
ORLA,#10H;P0.4=1
MOVP0,A;准备读P0口的P0.4
ANLA,#10H
JCLOOP;没有按下返回
CALLDELAY;调用延时程序,去键盘抖动,再判断键是否按下
MOVA,P0
ORLA,#10H;P0.4=1
MOVP0,A;准备读P0口的P0.4
MOVA,P0
ANLA,#10H
JCLOOP;没有按下返回
MOVA,P0
MOVR0,A
MOVA,#0FH
SUBBA,R0;对P0.0-P0.3求反
ANLA,#0FH
MOVP0,A;通过P0口输出使D1~D4LED亮或者灭
CALLDELAY
JMPLOOP
DELAY:
MOVR7,#00FH
N1:
MOVR6,#0F0H
N2:
NOP
DJNZR6,N2
DJNZR7,N1
RET
【例5-2】
主机软件设计:
①初始化程序
INIT:
MOVTMOD,#20H
MOVTH1,#0F9H;设置波特率为2400
MOVTL1,#0F9H
MOVSCON,#0F0H;串行口为方式3,SM2=1,允许接收
SETBTR1;启动定时器
RET
②通信子程序
COM:
SETBTB8;地址标志
MOVSBUF,#ADDR1;发送要通信的从机地址
LOOP:
JNBTI,LOOP;等待地址发完
CLRTI
CLRTB8;数据标志
MOVA,@R0;取要发送的数据
MOVSBUF,A;发数据
LOOP1:
JNBTI,LOOP1;等待数据发完
CLRTI
RET
从机软件设计:
①初始化程序
INIT:
MOVTMOD,#20H
MOVTH1,#0F9H;设置波特率为2400
MOVTL1,#0F9H
MOVSCON,#0F0H;设置串行口为方式3,SM2=1,允许接收
ANLPCON,#7FH
SETBTR1
SETBES;允许串行口中断
SETBEA
WAIT:
SJMPWAIT;听号
②串口中断服务通信程序
当接收到地址帧“呼号”且地址帧与本机地址相符时,要置SM2为0以便准备接收数据帧,同时需要将本机地址发回作为应答,建立与主机的联络。
编程如下:
SIO:
CLRRI
PUSHPSW;现场保护
PUSHACC
MOVA,SBUF;接收串行数据
XRLA,#ADDR;判断是否与本机地址相符
JNZBACK;不相符则返回
CLRSM2;相符则SM2为0且发回本机地址
CLRES;关串口中断,避免中断嵌套
MOVA,SBUF;接收数据
WAIT:
JNBRI,WAIT
CLRRI
MOV@R0,A;保存数据
SETBSM2;恢复多机通信,
SETBES;开串口中断
BACK:
POPACC;恢复现场
POPPSW
RETI
【例5-3】
MAIN:
MOVSP,#60H;设置堆栈为60H
MOVTH1,#0FDH;设置波特率为9600
MOVTL1,#0FDH
MOVTMOD,#21H;T1工作在方式2
MOVPCON,#00H;SMOD=0
MOVSCON,#0D0H;串行方式3
SETB TR1
WSIO1:
JNBRI,WSIO1
CLRRI
MOVA,SBUF
MOVC,P
ANLC,/RB8
MOVF0,C
MOVC,RB8
ANLC,/P
ORLC,F0;完成P与RB8相异或
JCERROR;转到出错处理
MOVC,P
MOVTB8,C
MOVSBUF,A
ERROR:
JMPWSIO1
第6章
6.5.2定时器中断应用实例
(1)主程序代码:
ORG1000H
MAIN:
MOVSP,#60H;设置推栈区
MOVTMOD,#01H;空时125ms
MOVTL0,#0DCH
MOVTH0,#0BH
SETBEA;开总中断
SETBET0;允许TO中断
MOVR2,#08H;计数8次
SETBTR0;开始计时
LOOP1:
JBC20H,DY;20H清零
SJMPLOOP1
DY:
LCALLDISPLAY
SJMPLOOP1
(2)中断子程序:
ORG2000H
T0SERVE:
MOVTL0,#0DCH;重置计数初值
MOVTH0,#0BH
DJNZR2,LOOP;8次计数没剩则继续计时
MOVR2,#08H;R2重置为8
SETB20H;1s到,置位20H
LOOP:
RETI
(3)一个实现“间隔一秒调一次显示”功能的完整程序如下:
ORG0000H
AJMPMAIN
ORG000BH
AJMPINTT0
ORG0050H
MAIN:
MOVSP,#60H
MOVR0,#79H
MOVR7,#06H
MLO:
MOV@R0,#08H
INCR0
DJNZR7,MLO
MOVTMOD,#01H
MOVTL0,#0DH
MOVTH0,#0BH
MOVR2,#08H
SETBEA
SETBET0
SETBTR0
LOOP:
JB20H,LOOP1
SJMPLOOP
LOOP1:
LCALLDISPLAY
SJMPLOOP
INTT0:
MOVTL0,#0DCH
MOVTH0,#0BH
DJNZR2,RETURN
MOVR2,#08H
CPL20H
RETURN:
RETI
第7章
【例7-2】
ORG0000H
AJMPMAIN;转到主程序
ORG000BH;T0中断矢量地址
AJMPINQP;转到中断服务程序
ORG0050H
MAIN:
MOVTMOD,#00H;设置T0为方式0定时
MOVTH0,#1EH;装入T0的定时常数
MOVTL0,#0CH
SETBTR0;启动T0
SETBET0;允许T0中断
SETBEA;CPU开中断
SJMP$;等待T0中断发生
ORG0100H;中断服务程序
INQP:
MOVTH0,#1EH;重装定时常数
MOVTL0,#0CH
CPLP1.0;P1.0变反输出
RETI;中断返回
【例7-3】
ORG0000H
AJMPMAIN;转到主程序
ORG000BH;T0的中断入口
AJMPINTS;转到中断服务程序
ORG0100H;主程序入口地址
MAIN:
MOVSP,#60H;设栈指针
MOVTMOD,#06H;设T0为计数方式2
MOVTL0,#0FFH;设TL0初值
MOVTH0,#0FFH;设TH0初值
SETBTR0;启动计数
SETBET0;允许T0中断
SETBEA;中断开放
SJMP$;等待T0中断发生
;中断处理程序
INTS:
PUSHA;现场保护,把寄存器A中的值压入堆栈中
PUSHDPL;把数据指针的低位DPL中的值压入堆栈中
PUSHDPH;把数据指针的高位DPH中的值压入堆栈中
;现场恢复
POPDPH;把数据指针的高位DPH中的值从堆栈中取出
POPDPL;把数据指针的低位DPL中的值从堆栈中取出
POPA;把寄存器A中的值从堆栈中取出
RETI
7.5实例解析
【实例7-1】
ORG0000H;复位地址
LJMPMAIN;转入主程序
ORG000BH;T0中断入口地址
LJMPIT0;转入T0中断服务程序
ORG0100H;主程序首地址
MAIN:
MOVTMOD,#01H;设置T0为工作方式1
MOVTH0,#3CH;装入定时常数
MOVTL0,#0B0H
MOVIE,#10000010B;T0开中断
MOVR7,#0AH;设置循环次数为10次
SETBTR0;T0运行
CLRP1.7
SJMP$;等待中断
;中断服务程序:
ORG000BH
ITO:
MOVTL0,#0B0H;重新装入时间常数
MOVTH0,#3CH
DJNZR7,LOOP;循环10次
CRLP1.7;500ms定时到了,P1.7位取反,闪烁效果
LOOP:
RETI;中断返回
END;程序结束
【实例7-2】
ORG0000H
AJMPMAIN
ORG000BH;T0的中断入口
AJMPTIME0;转入中断程序
ORG001BH;T1的中断入口
AJMPTIME1;转入中断程序
ORG0033H
MAIN:
MOVSP,#60H;设置堆栈指针初值
MOVR3,#0;清除软件计数器
SETBP3.2;将P3.2,P3.5置1,即为输入状态
SETBP3.5
MOVTMOD,#59H
MOVTH0,#3CH;装入定时器初值
MOVTL0,#0B0H
MOVTH1,#0FFH;装入计数器初值
MOVTL1,#0FEH
SETBTR0;启动定时器、计数器
SETBTR1
MOVIP,#08H;T1中断优先于T0
SETBET1;允许T1中断
SETBTF1;设TF0、TF1为中断标志
LOOP:
SETBTF0
SETBET0;允许T0中断
SETBEA;中断开放
JBTF0,$;判断TF0是否溢出,并一直等待
JBTF1,LOOP;判断TF1是否溢出,如果溢出就转到LOOP
RET
TIME0:
MOVTL0,#0B0H;设TL0初值
MOVTH0,#3CH;设TH0初值
INCR3;计数器加1
CPLTF0;TF0取反
RETI;中断返回
TIME1:
CLRTF0;清除中断标志
CLRTF1
CLRET0;禁止T0、T1中断
CLRET1
CLREA;关中断
RETI;中断返回
第8章
【例8-2】
MAIN:
MOVSP,#60H
LOOP:
MOVA,P0
ORLA,#0FH;P0.0~P0.3=1
MOVP0,A;准备读P0口
ANLA,#0FH
JNZLOOP;没有按下返回
CALLDELAY;调用延时程序,去键盘抖动,再判断键是否按下
MOVA,P0
ORLA,#0FH;P0.0~P0.3=1
MOVP0,A;准备读P0口
MOVA,P0
ANLA,#01H
JZPP0;KEY0按下调用PP0
MOVP0,A;准备读P0口
MOVA,P0
ANLA,#02H
JZPP1;KEY1按下调用PP1
MOVP0,A;准备读P0口
MOVA,P0
ANLA,#04H
JZPP2;KEY2按下调用PP2
MOVP0,A;准备读P0口
MOVA,P0
ANLA,#08H
JZPP3;KEY3按下调用PP3
JMPLOOP
DELAY:
MOVR7,#0F0H
N1:
MOVR6,#0F0H
N2:
NOP
DJNZR6,N2
DJNZR7,N1
RET
【例8-3】
MAIN:
MOVSP,#60H
LOOP:
MOVA,#01H
MOVR2,#4
OUTPUT:
MOVP1,A
RLA
CALLDELAY
DJNZR2,OUTPUT
LJMPLOOP
DELAY:
MOVR6,#0
MOVR7,#0
DELAYLOOP:
DJNZR6,DELAYLOOP
DJNZR7,DELAYLOOP
RET
END
8.3实例解析
程序设计如下:
OUTBITEQU0FE02H;位控制口
CLK164EQU0FE04H;段控制口(接164时钟位)
DAT164EQU0FE06H;段控制口(接164数据位)
INEQU0FE00H;键盘读入口
HASRCVEQU20H.0;接收标志位
LEDBUFEQU40H;显示缓冲
RCVBUFEQU50H;接收缓冲
②指令ORG0000H一般用在一段源程序的前面,用来说明紧随其后的程序段的起始地址。
下面的指令说明指令LJMPSTART的地址为0000H。
ORG0000H
LJMPSTART;执行该指令后将转去执行以START为标号
;的程序段,标志着程序的开始执行
③串行口中断子程序,程序的入口地
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 原理 应用程序