华工MCU与DSP专题二.docx
《华工MCU与DSP专题二.docx》由会员分享,可在线阅读,更多相关《华工MCU与DSP专题二.docx(35页珍藏版)》请在冰豆网上搜索。
华工MCU与DSP专题二
专题二:
指令系统和软件方法
一.指令系统(MCS-51系列)
111条指令,5类功能,6种寻址方式。
1.功能分类:
(1)数据传送类:
如MOVA,#DATA
(2)算术运算类:
如ADDA,RN
(3)逻辑操作类:
如ANLA,direct
(4)位操作类:
如SETBbit
(5)控制转移类:
如CJNE@R1,#DATA,Rel
2.寻址方式:
(1)立即寻址:
MOVA,#70H;A←70H,立即数
(2)直接寻址:
MOVA,70H;A←(70H),RAM内容
(3)寄存器寻址:
MOVA,R3;A←(R3),寄存器内容
(4)寄存器间接寻址:
MOVA,@R0;A←((R0)),
R0所指内部RAM内容
(5)基寄存器加变址寄存器间接寻址:
──对查表访问特别有用
MOVCA,@A+DPTR;(远程查表)
变址基址(属单字节指令)
;(A+DPTR所指ROM内容送A)
MOVCA,@A+PC;(近程查表)
变址基址(属单字节指令)
;(A+PC所指ROM内容送A)
(6)相对寻址:
──只适于双字节转移指令
JCrel;(PC为基址,加偏移量,
偏移量作为转移地址)。
┕带符号数,+127~-128,
用2的补码表示。
结果为:
转移地址=PC+2+偏移量
2.指令符号意义汇总:
Rn—所选的寄存器区(n=0~7)
Ri—区中2个可作地址寄存器,
即R0,R1(i=0或1)
direct—8位内RAM地址,SFR地址,I/O
(2,10,16进制均可)
端口,控制寄存器,状态寄存器等。
#DATA—8位常数
#DATA16—16位常数
B—乘法,除法中用,
属专用寄存器(直接寻址)。
C—进位标志,进位位,
作布尔操作中的“累加器”。
二.伪指令(常用几种)
特征:
汇编时不产生目标代码,不影响程序执行。
1.ORG(起点)
放在源程序段或数据块之始,后续绝对地址或标号,
如:
ORG0030H
AJMPMAIN
2.DB(定义字节)
把字节常数或字节串存入内存连续单元
如:
ORG8000H
DA1:
DB73H,01H;←字节常数
DA2:
DB“K”“M”;←ASCⅡ码字符串
3.DW(定义一个字)
功能与DB相似,但用两个字节,主要用来定义地址。
如标号:
DW字或字串
TABA:
DW7583H
MOVDPTR,#TABA
4.EQU(等值)
把操作数或汇编符号赋给标号,使两边量相等,须先定义后使用。
如:
RegiEQUR2
AreaEQU2000H
MOVARegi;A←R2
5.DATA(定义标号的16位地址)
不管定义先后均可使用。
如:
Addr1DATA0100H
Addr2DATA2000H
MOVDPTR#Addr1
LJMPAddr2
6.END(汇编结束)
一个源程序中只许出现一次,放于最末。
如:
ORG0000H
┇
END;程序之末
CLRA;←后续程序不汇编
NOP
三.程序设计主要步骤
1.程序流程框图:
按问题要求编制(流程线不能交叉)。
2.源程序初始化:
内部RAM工作单元分配表,变量设定,
寄存器控制字设定,启动等…
3.源程序编制
用汇编语言等编写主程序和子程序。
4.上机调试
查找故障,局部修改,最后脱机运行。
四.常用程序设计的讨论
1.程序初始化形式
(含中断服务程序为例)
ORG0000H
AJMPMAIN;主程序入口,跳过中断区
ORG0003H
AJMPINT0;设置外中断0子程序入口
ORG0030H
MAIN:
NOP;主程序
MOVSP,#60H;安置堆栈位置
┇
NOP
INT0:
CLREA;中服(与主程序地址连续)
┇
RETI;中服返回
或者如
ORG0100H;中服地址另选,须预留充分
INT0:
CLREA
┇
RETI;中服返回
2.软件延时子程序及计算法
(6MHZ晶振例,1个机器周期:
2μS)
ORG****H
DLY:
MOVR6,#200;1机器周期指令
DLY0:
MOVR7,#248;1机器周期指令
DLY1:
DJNZR7,DLY1;2机器周期指令
DJNZR6,DLY0;2机器周期指令
RET;2机器周期指令
2-1
3.中断服务程序现场保护
(1)原则:
中服的执行不应改变主程序使用的内容,寄存器,变量等内容。
凡中服要用到的A,PSW等资料,中服应入栈保护,返回前复原。
如:
ORG0003H;外中断0入口地址
LJMPSERVE
┇
ORG****H;中服子程序首址
SERVE:
PUSHPSW;视需要变量入栈
PUSHACC
PUSHB
PUSHDPL;低字节先入
PUSHDPH
PUSH07H;R0~R7需用具体地址
MOVPSW,#00001000B
┇;此为换2区寄存器
┇
POP07H;出栈复原,后进先出
POPDPH;高字节先出
POPDPL
POPBPOPACCPOPPSW
RETI;中断返回
(2)现场保护后的堆栈情况:
2-2
4.中断返回与软件抗干扰关系
(1)中断返回的职能(RETI)
1)通知中断系统,清除“中断优先级激活触发器”标志,(中断系统内有2个不可寻址的“优先级激活触发器”,该触发器在响应中断时置位)
2)装入由堆栈弹出的PC值,恢复原程序的执行。
(2)
正常的中断返回情况
2-3
(3)
受干扰后强行拉回情况
2-4
结果:
因各级中断优先级标志均未清除,程序从start开始执行,就遇到未清的标志而无响应,(出现死机现象)
(4)清中断标志的软件抗干扰措施
2-5
(人为设置ERR和ERR1处理子程)
ERR:
CLREA;禁止中断
MOVDPTR,#ERR1
;人为清低级标志子程入口
PUSHDPL;作PC值备用
PUSHDPH
RETI;人为高级中断返回
结果:
(1)弹出两字节的DPTR作PC值
(2)清高级“优先级激活触发器”中断标志
(3)PC值指向→#ERR1
ERR1:
CLRA;累加器清零
PUSHACC;置两个0作PC值备用
PUSHACC
RETI;人为低级中断返回
结果:
(1)弹出两字节的ACC作PC值
(2)清低级“优先级激活触发器”中断标志
(3)PC值指向→#0000H
(4)各级中断“优先级激活触发器”标志已清,程序从start处可往下执行
;MIAN1.asmfordemo
;2006
;
ORG0000H
START:
AJMPMAINP
ORG0003H
AJMPINT00;toINT0
ORG000BH
AJMPTIME0;lowintpt.
ORG001BH
AJMPTIME1;highintpt.
ORG0030H
MAINP:
CLREA;mainprogram
MOVSP,#60H
MOVP1,#0FFH
MOVP3,#0FFH
MOVTMOD,#11H;settimer
CLRPSW.5;flagfornoise
SETBET0;permitintpt.
SETBET1
SETBEX0
SETBPT1;highpriority
SETBTR0;startT1
SETBTR1;startT0
SETBEA;totalopen
LOOP:
CPLP0.0;mainLEDflash
MOVR7,#38;delay0.5s
ACALLDLY
JNBPSW.5,LOOP;nonoiseflag
STOP:
AJMPSTOP
;///sub
INT00:
SETBPSW.5;K1noiseflag
RETI
;///sub
TIME0:
CPLP0.1;lowinterrupt
MOVTL0,#0;timeconstant
MOVTH0,#0
SETBTR0
RETI
;///sub
TIME1:
CPLP0.2;highintpt.
MOVTL1,#0;timeconstant
MOVTH1,#0
JNBP3.4,YES;K2forlow
AJMPCC1
YES:
MOVR7,#15;20ms去抖
ACALLDLY
JNBP3.4,ERR;checksignal
CC1:
SETBTR1
RETI
ERR:
AJMPSTART;forcetostart
;///
DLY:
PUSH07H;///subdelay
DLA:
PUSH07H
DLB:
PUSH07H
DLC:
DJNZR7,DLC
POP07H
DJNZR7,DLB
POP07H
DJNZR7,DLA
POP07H
DJNZR7,DLY
RET
END
;MIAN3.asmfordemo
;2006
;
ORG0000H
START:
AJMPMAINP
ORG0003H
AJMPINT00;toINT0
ORG000BH
AJMPTIME0;lowintpt.
ORG001BH
AJMPTIME1;highintpt.
ORG0030H
MAINP:
CLREA;mainprogram
MOVSP,#60H
MOVP1,#0FFH
MOVP3,#0FFH
MOVTMOD,#11H;settimer
CLRPSW.5;flagfornoise
SETBET0;permitintpt.
SETBET1
SETBEX0
SETBPT1;highpriority
SETBTR0;startT1
SETBTR1;startT0
SETBEA;totalopen
LOOP:
CPLP0.0;mainLEDflash
MOVR7,#38;delay0.5s
ACALLDLY
JNBPSW.5,LOOP;nonoiseflag
STOP:
AJMPSTOP
;///subINT0
INT00:
SETBPSW.5;K1noiseflag
RETI
;///subT0
TIME0:
CPLP0.1;lowinterrupt
MOVTL0,#0;timeconstant
MOVTH0,#0
SETBTR0
RETI
;///subT1
TIME1:
CPLP0.2;highintpt.
MOVTL1,#0;timeconstant
MOVTH1,#0
JNBP3.4,YES;K2forlow
AJMPCC1
YES:
MOVR7,#15;20ms
ACALLDLY
JNBP3.4,ERR;check
CC1:
SETBTR1
RETI
ERR:
CLREA;release
MOV56H,#0AAH
;flagforreset
MOV57H,#55H
MOVDPTR,#ERR1
;makeaddr.of1RETI
PUSHDPL
PUSHDPH
RETI
ERR1:
CLRA
PUSHACC
PUSHACC
;makeaddr.of2RETI
RETI
;///
DLY:
PUSH07H;///subdelay
DLA:
PUSH07H
DLB:
PUSH07H
DLC:
DJNZR7,DLC
POP07H
DJNZR7,DLB
POP07H
DJNZR7,DLA
POP07H
DJNZR7,DLY
RET
END
5.查表程序(“表”一般放于ROM中)
(1)近程查表:
PC作基址寄存器,A作表的变址
(装入表到指令之间的偏移量)
→MOVA,#06H;偏移量
→8500MOVCA,@A+PC;(PC)←8501+6
┇变址基址
┇
→8507DB25H;A←25H
→DB28H
好处:
查表指令和表靠在一起;
不影响DPTR,(可另作它用)
(2)远程查表:
DPTR作基址寄存器,A作变址寄存器
(须装入表的首址,装入表的项数)。
MOVA,#00H;装入偏移项
MOVDPTR,#TAB;装入表首址
MOVCA,@A+DPTR;结果A←30H
┇(单字节,二周期)
┇
→TAB:
DB30H;表存放内容
DB35H
特点:
表格TAB可放在64K空间任何地址上。
6.散转程序
原理:
(1)把散转分支的入口地址排成散转表
(2)用DPTR指向散转表首址。
(3)A装入散转表入口地址偏移量
(4)用转移指令转向该分支程序
例:
入口(R3)=散转地址序号(0,1,2,…)
MOVDPTR,#TAB;表首址
MOVA,R3;
RLA;形成A←R3*2
JMP@A+DPTR;散转
→TAB:
AJMPBRANCHO;第0分支
AJMPBRANCH1;第1分支
AJMPBRANCH2;第2分支
┇
注:
(1)AJMP组成二字节间隙的散转表,
故R3内容乘2,使A为偶数倍。
(2)AJMP只能2KB地址内散转,可补
入长跳LAMP,转到其他任何区域。
BRANCHO:
LJMPB64KB0
BRANCH1:
LJMPB64KB1
BRANCH2:
LJMPB64KB2
1.短转移SJMP的偏移量计算
(机器汇编能自动计算,下述手工方法例)
格式:
SJMPRel(相对地址)
;属2字节指令
操作:
(PC)←(PC)+2
(PC)←(PC)+相对地址
(1)关于相对地址Rel:
带符号数,2的补码的偏移字节数,-128~+127
(倒后)(前进)
例:
0003HMOVR0,#34
0005HBACK:
MOVA,#10H;1字节指令
0007HMOVR1,#33
0009HSJMPBACK;后向转移
000BHINCR1
000CHSJMPFORE;前向转移
000EHMOVA,#16
0010HMOVR0,#20
0012HFORE:
DECR1
0013HINCDPTR
┇
求BACK:
(偏移量);加负数相当于加补码
09H+02H=0BH
05H-0BH=05H+(-0BH)
(0BH)补=(0BH)反+1=F4H+01H=F5H
∴05H+F5H=FAH
求FORE:
(偏移量);被减数大直减或加补码
0CH+02H=0EH
∴12H-0EH=04H
(2)偏移FEH,则“原地”循环
例:
0060HLOOP:
SJMPLOOP
62H+[60H-(60H+02H)]=60H
(源)(目的地)(源地址)
┕--偏移量--┛
五.一些程序指令的用法
1.数值比较转移
CJNEA,#DATA,Rel(偏移标号)
原则:
须结合进位位C来判断
例:
要实现A≥37跳转到LOOP
A<37跳转到OK
CJNEA,#37,LP1;不等于
AJMPLOOP;A=37
LP1:
JNCLOOP;A>37(C=0)
AJMPOK;A<37(C=1)
LOOP:
NOP;大于等于
┇
2.屏蔽字节某(些)位
ANLA,#DATA
例:
设P1口内容为10010011,欲屏蔽高四位
MOVA,P1
ANLA,#0FH
结果(A):
10010011
00001111
00000011
3.选取字节某些位
ORLA,#DATA
例:
设P1口内容为10010011,欲选取高四位
MOVA,P1
ORLA,#0FH
结果(A):
10010011
00001111
10011111
上述两种操作,视具体应用而定。
4.程序跳转区域
2-6
AJMP2K内
LJMP64K内
例:
ORG0003H
AJMPIN0
┇
IN0:
CLREA
INC21H
2046:
AJMPBRY;两字节指令,2K之末
2048
NOP
┇
BRY:
SETBP1.2;写法没错,未必能跳
RETI
5.待机工作方式(idle)
目的:
在单片机非操作期间休闲起来,呈睡眠节电状态:
时钟信号只供给中断逻辑,定时器和串行口,CPU的全部状态保留(如SP,PC,PSW,A,R0~R7,I/O口)。
启动待机:
执行电源控制寄存器PCON(87H)的DO位(IDL)置1的指令便可进入待机态。
2-7
唤醒方法:
(1)中断激活,(IDL)位被硬件清除
(2)RESET硬件复位
例:
(用中断激活方式唤醒)
*用带公共触点键盘产生中断信号
2-8a
SETBIE7;EA中断总允许
SETBIE2;EX1外中断1允许
SETBIP2;PX1外中断优先
┇
AA1:
MOVPCON,#01H;进入待机态
SETBP3.0;中断唤醒后的指令
SETBP3.1
┇
AJMPAA1;跳转再进入待机
注:
中断RETI返回后,才执行紧跟“待机态”的后续指令
*用普通矩阵键盘产生中断信号
2-8b
注:
初态时需P1口全为零(但不能用于待机态)。
任一键按下,与门均产生中断信号。
二极管可防止多键同时按下造成出错。
演示电路:
(1)上电或S复位后,按K2入idle态。
电流表数值下降。
(2)按键盘任一键,唤醒idle态,电流表数值上升;按‘0’键再入idle态。
正常电流约ICC=6ma
待机电流约ICC=1.5ma
;Idle1.ASMfordemo
;2006
ORG0000H
START:
AJMPMAINP
ORG0003H
AJMPINT00;forINT0
ORG0030H
MAINP:
NOP;mainprogram
MOVSP,#60H
SETBEX0;INTOopen
SETBEA;totalopen
LOOP:
CLRP0.0;mainLEDon
JNBP3.4,YES;pushforidle
AJMPCC1
YES:
MOVR7,#15;20ms去抖
ACALLDLY
JNBP3.4,IDLE
CC1:
AJMPLOOP
IDLE:
MOVPCON,#01H执行后
;enteridle
NOP;waitforun-idle
AJMPIDLE
;///sub
INT00:
CLREA;interrupt
AGA:
ACALLKEY;keepvalueinA
CJNEA,#0F6H,CC2;for'1'
CLRP0.1;LED1on
AJMPAGA
CC2:
CJNEA,#0F3H,CC3;for'3'
CLRP0.2
AJMPAGA
CC3:
CJNEA,#0BDH,AGA;for'0'
SETBP0.1;LED2off
SETBP0.2;LED3off
MOVP1,#0FFH;allhigh
SETBEA
RETI
;///inversemethod
;**scan1
KEY:
MOVP1,#0F8H;0forrow
MOVA,P1;readcol.
ANLA,#0F8H
CJNEA,#0F8H,K1
AJMPKEY;waitforpushing
K1:
MOVR7,#15;20ms
ACALLDLY
MOVP1,#0F8H;0again
MOVA,P1;readagain
ANLA,#0F8H
CJNEA,#0F8H,K2;besure
AJMPKEY
K2:
MOVB,A;keeptemp.
;**scan2
MOVP1,#07H;0forcol.
MOVA,P1
ANLA,#07H
CJNEA,#07H,K3;besure
AJMPKEY
K3:
ORLA,B;makekeyvalue
MOVB,A;temp.keep
K4:
MOVA,P1;**release
ANLA,#07H
CJNEA,#07H,K4
MOVR7,#15;20ms
ACALLDLY
MOVA,P1
ANLA,#07H
CJNEA,#07H,K4
MOVA,B;getvalue
RET
;///sub
DLY:
PUSH07H;delay
DLA:
PUSH07H
DLB:
PUSH07H
DLC:
DJNZR7,DLC
POP07H
D