单片机汇编语言举例.docx
《单片机汇编语言举例.docx》由会员分享,可在线阅读,更多相关《单片机汇编语言举例.docx(11页珍藏版)》请在冰豆网上搜索。
单片机汇编语言举例
动态显示字符"8051AF"
;==============================
;定义显示缓冲区
DISP1EQU40H
DISP2EQU41H
DISP3EQU42H
DISP4EQU43H
DISP5EQU44H
DISP6EQU45H
;==============================
ORG0000H
LJMPSTART
;==============================
ORG0050H
START:
MOVSP,#060H;初始化堆栈指针
;初始化显示缓冲区
MOVDISP1,#0Fh
MOVDISP2,#0Ah
MOVDISP3,#01h
MOVDISP4,#05h
MOVDISP5,#00h
MOVDISP6,#08h
;
MOVA,#80H ;8255方式控制字
MOVDPTR,#0FF23H;8255控制口地址
MOVX@DPTR,A ;初始化8255
MAIN:
ACALLDISPLAY
SJMPMAIN
;==============================
DISPLAY:
MOVR0,#DISP1
MOVR2,#0FEH;字控制
MOVR3,#06H
DLOOP:
MOVA,@R0
MOVDPTR,#LEDMAP;取七段码表首地址
MOVCA,@A+DPTR
CPLA
MOVDPTR,#0FF21H;8255PB口地址
MOVX@DPTR,A
MOVA,R2
MOVDPTR,#0FF20H;8255PA口地址
MOVX@DPTR,A
RLA ;显示位左移
MOVR2,A
INCR0
ACALLDLY
DJNZR3,DLOOP
RET
;==============================
DLY:
;延时子程序
MOVR7,#02H
DLY1:
MOVR6,#0F0H
DJNZR6,$
DJNZR7,DLY1
RET
;==============================
LEDMAP:
;数码管七段显示码表(共阴)
db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h
db 7fh,6fh,77h,7ch,39h,5eh,79h,71h
db 00H
;==============================
END
1到100数码管显示
ORG0000H
ABITEQU20H ;个位数存放处
BBITEQU21H ;十位数存放处
TEMPEQU22H ;计数器寄存器
START:
MOVP2,#0FFH
MOVTEMP,#0;初始化计数器
STLOP:
ACALLDISPLAY
INCTEMP
MOVA,TEMP
CJNEA,#100,NEXT;=100重来
MOVTEMP,#0
NEXT:
LJMPSTLOP
;显示子程序
DISPLAY:
movp0,0ffh
MOVA,TEMP;将temp中的十六进制数转换成10进制
MOVB,#10;10进制/10=10进制
DIVAB
MOVBBIT,A;十位在a
MOVABIT,B;个位在b
;p0口接段码a,b,c,d,e,f,g,p2口接位码,选哪个数码管显示
MOVDPTR,#TAB;指定查表启始地址
MOVR0,#4
DPL1:
MOVR1,#250;显示1000次
DPLOP:
MOVA,ABIT;取个位数
MOVCA,@A+DPTR;查个位数的7段代码
MOVP1,A;送出个位的7段代码
CLRP2.0;开个位显示
ACALLD1MS;显示1ms
SETBP2.0
MOVA,BBIT;取十位数
MOVCA,@A+DPTR;查十位数的7段代码
MOVP1,A;送出十位的7段代码
CLRP2.1;开十位显示
ACALLD1MS;显示1ms
SETBP2.1
DJNZR1,DPLOP;100次没完循环
DJNZR0,DPL1;4个100次没完循环
RET
;1MS延时(按12MHZ算)
;====================================================
D1MS:
MOVR7,#80
DJNZR7,$
RET
;7段数码管各划的数字排列表
TAB:
DB0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0F8h,80h,90h
;不带小数点0123456789
END
步进电机驱动,按键改变转动方向
;==============================
;12345678
;P1.0:
HHHLLLLL
;P1.1:
LLHHHLLL
;P1.2:
LLLLHHHL
;P1.3:
HLLLLLHH
;913264C8
KEYINBITP3.4;定义按键输入
FLAGBIT00H
;==============================
ORG0000H
LJMPSTART
;==============================
ORG0050H
START:
MOVSP,#060H;初始化堆栈指针
MOVP1,#08H
MOVR2,#00H
CLRFLAG
MOVDPTR,#MOV_TABLE
MAIN:
ACALLKEYPROC
JBFLAG,MAIN1
INCR2
ACALLMOVE
SJMPMAIN
MAIN1:
DECR2
ACALLMOVE
SJMPMAIN
;==============================
MOVE:
;运转控制
MOVA,R2
ANLA,#07H
MOVCA,@A+DPTR
MOVP1,A
ACALLDLY
RET
;===========
MOV_TABLE:
DB09H,01H,03H,02H,06H,04H,0CH,08H
;==============================
KEYPROC:
JBKEYIN,KEY_DONE
ACALLDLY
ACALLDLY
JBKEYIN,KEY_DONE
CPLFLAG
JNBKEYIN,$
KEY_DONE:
RET
;==============================
DLY:
;延时子程序
MOVR7,#0AH
DLY1:
MOVR6,#0F0H
DJNZR6,$
DJNZR7,DLY1
RET
;==============================
END
左右循环点亮
ORG 0000H
LJMP START
ORG 0030H
START:
MOV R1,#00H
DJNZ R1,$
MOV SP,#60H
LOOP:
MOV A,#0FEH
LOOP_1:
MOV P1,A
CALL DELAY
RL A
CJNE A,#7FH,LOOP_1;01111111
LOOP_2:
MOV P1,A
CALL DELAY
RR A
CJNE A,#0FEH,LOOP_2;11111110
SJMP LOOP
DELAY:
MOV R0,#00H
L1:
MOV R1,#00H
L2:
DJNZ R1,L2
DJNZ R0,L1
RET
END
所有灯循环点亮
ORG0000H
LJMPMAIN
ORG0100H
MAIN:
MOVP1,#0FFH
LCALLDELAY
MOVP1,#00H
LCALLDELAY
LJMPMAIN
DELAY:
MOVR7,#0
D1:
MOVR6,#0
D2:
DJNZR6,D2
DJNZR7,D1
RET
END
产生方波
/*用定时器T0产生50HZ的方波。
由P1.0输出此方波(设时钟频率为12MHZ)。
采用中断方式。
解:
50HZ的方波周期T为T=1/50=20ms
可以用定时器产生10ms的定时,每隔10ms改变一次P1.0的电平,即可得到50HZ的方波。
定时器T0应工作在方式1。
工作在方式1时的T0初值,根据下式计算:
t=(216–X)×机器周期
时钟频率为12MHz,则机器周期=1μs
10×103=(216–X)×1
X=65536–10000=55536
转换为二进制数:
11011000 11001100B
高8位 低8位
高8位=0D8H装入TH0,低8位=0CCH装入TL0。
*/
ORG0000H
AJMPMAIN
ORG000BH
AJMPT0INT
ORG0100H
MAIN:
MOVTMOD,#01H
MOVTH0,#0D8H
MOVTL0,#0CCH
SETBET0
SETBEA
SETBTR0
SJMP$
ORG0300H
T0INT:
CPLP1.0
MOVTH0,#0D8H
MOVTL0,#0CCH
RETI
END
/*SETBET0 ;设置T0允许中断
SETBEA ;CPU开中断
这两条指令可以等效为MOVIE,#82H。
*/
定时器实现灯闪烁
ORG0000H
AJMP START
ORG30H
START:
MOVP1,#0FFH;关所有灯
MOVTMOD,#00000001B;定时/计数器0工作于方式1
MOVTH0,#15H
MOVTL0,#0A0H;即数5536
SETB TR0;定时/计数器0开始运行
LOOP:
JBC TF0,NEXT;如果TF0等于1,则清TF0并转NEXT处
AJMP LOOP;否则跳转到LOOP处运行
NEXT:
CPL P1.0
MOVTH0,#15H
MOVTL0,#9FH;重置定时/计数器的初值
AJMP LOOP
END
;简单地分析一下程序,为什么用JBC呢?
;TF0是定时/计数器0的溢出标记位,当定时器产生溢出后,该位由0变1,所以查询该位就可知宇时时间是否已到。
;该位为1后,要用软件将标记位清0,以便下一次定时是间到时该位由0变1,所以用了JBC指令,该指位在判1转移的同时,还将该位清0。
中断实现灯闪烁
;用中断实现灯的闪烁,即用定时器产生方波
ORG0000H
AJMPSTART
ORG000BH;定时器0的中断向量地址
AJMP TIME0 ;跳转到真正的定时器程序处
ORG30H
START:
MOVP1,#0FFH;关所灯
MOVTMOD,#00000001B;定时/计数器0工作于方式1
MOVTH0,#15H
MOVTL0,#0A0H;即数5536
SETBEA;开总中断允许
SETBET0;开定时/计数器0允许
SETBTR0;定时/计数器0开始运行
LOOP:
AJMPLOOP ;真正工作时,这里可写任意程序
;定时器0的中断处理程序
TIME0:
PUSHACC
PUSHPSW;将PSW和ACC推入堆栈保护
CPLP1.0
MOVTH0,#15H
MOVTL0,#0A0H ;重置定时常数
POPPSW
POPACC
RETI
END
;定时时间一到,TF0由0变1,就会引发中断,CPU将自动转至000B处寻找程序并执行
;由于留给定时器中断的空间只有8个字节,显然不足以写下所有有中断处理程序,所以在000B处安排一条跳转指令
;转到实际处理中断的程序处,这样,中断程序可以写在任意地方,也可以写任意长度了
;进入定时中断后,首先要保存当前的一些状态;定时器中预置的数是5536,所以每计60000个脉冲就是定时时间到,我们的晶振是12M,所以就是60000微秒,即60毫秒
中断变向流水灯
ORG0000H ;定义下一条指令的地址
SJMPSTART ;转向主程序
ORG 0013H ;安排外部中断1处理程序的第一条指令
SJMP:
KEYS ;直接转移到中断处理程序
START:
;主程序起点
MOV SP,#40H ;设置堆栈栈底指针
SETB IT1 ;设置外部中断1的中断方式为下降沿中断
SETB EX1 ;开放外部中断1
SETB EA ;开放总中断
MOV A,#01H ;#01H送累加器A
L1:
MOV P2,A ;累加器A中内容送P2口
MOV R7,#0FFH ;延时
L3:
MOV R6,#0FFH
L2:
DJNZ R6,L2
DJNZR7,L3
JNB FX,L4 ;FX=0时转移到L4(FX是流水灯流动方向标志)
RL A ;累加器A中内容左移一位
SJMPL5 ;转移至L5
L4:
RR A ;累加器A中内容右移一位
L5:
SJMPL1 ;转移至L1
;=================================================
;按键中断程序
;入口:
外部中断1
;功能:
确认按键后改变方向标志FX的状态
KEYS:
;中断处理程序入口
MOV R7,#20H ;首先延时去抖
K1:
MOV R6,#0FFH
DJNZ R6,$
DJNZ R7,K1
JB KEY,K2 ;延时完成后再检测按键
CPL FX ;确认按键按下,改变方向标志位状态
K2:
RETI ;中断结束返回
KEYBIT P3.3 ;定义按键变量
FX BIT 00H ;定义位变量,用于判断方向
END ;结束
中断后延时循环
/*P1口连接8个发光二极管,外部中断INT1接KEY(P2.7接按键SW8,P3.3接KEY),
作为中断申请信号,开机8个发光二极管从左到右流水,产生中断后,8个发光管全亮、全灭,延时后,再循环。
*/
ORG 0000h ;伪指令
LJMP START ;跳转到单片机的主程序
ORG 0013H ;外部中断1的入口地址
LJMP EXT1 ;跳转到中断服务程序
ORG 0100H ;伪指令,单片机主程序的开始
START:
MOVIE,#10000100b
MOVIP,#00000100b
MOVTCON,#00000000b
MOVSP,#40H
MOVP1,#0FFH
MOVP2,#00H
MOVP3,#0FFH
LOOP:
MOVA, #0FFH
CLRC
MOVR2,#08H
LOOP1:
RLCA
MOVP1,A
LCALLDELAY
DJNZR2,LOOP1
JMP LOOP
EXT1:
PUSHACC
PUSHPSW
MOVA,#00H
MOVR3,#0AH
LOOP2:
MOVP1,A
LCALLDELAY
CPLA
DJNZR3,LOOP2
POP PSW
POPACC
RETI
DELAY:
MOVR5,#20
D1:
MOVR6,#20
D2:
MOVR7,#248
DJNZR7,$
DJNZR6,D2
DJNZR5,D1
RET
END
定时器实现生日快乐
;使用导线把蜂鸣器J12的1与P3.0口相连。
;P3.0小喇叭---生日快乐。
ORG0000H
AJMPMAIN
ORG000BH
JMPTIM0
ORG0030H
;主程序
MAIN:
MOVTMOD,#01H;设定时方式
MOVIE,#82H;开中断
START0:
MOV30H,#00H;
NEXT:
MOVA,30H
MOVDPTR,#TABLE
MOVCA,@A+DPTR;查表取音调和节拍
MOVR2,A
JZEND0;为零,不进行处理.
ANLA,#0FH
MOVR5,A;将节拍存入R5
MOVA,R2
SWAPA
ANLA,#0FH
JNZSING;根据音调决定是否演奏.
CLRTR0
JMPD1
SING:
DECA
MOV22H,A;将音调存入22H.
RLA
MOVDPTR,#TABLE1
MOVCA,@A+DPTR;根据音调决定定时器初值.
MOVTH0,A;放入TH0
MOV21H,A
MOVA,22H
RLA
INCA
MOVCA,@A+DPTR
MOVTL0,A;放入TL0
MOV20H,A
SETBTR0;启动定时
D1:
CALLDELAY
INC30H
JMPNEXT
END0:
CLRTR0
JMPSTART0
;定时器中断服务程序
TIM0:
PUSHACC
PUSHPSW
MOVTL0,20H;重赋初值.
MOVTH0,21H
CPLP3.0
POPPSW
POPACC
RETI
DELAY:
MOVR7,#02H;延时子程序
D2:
MOVR4,#187
D3:
MOVR3,#248
DJNZR3,$
DJNZR4,D3
DJNZR7,D2
DJNZR5,DELAY
RET
;决定音调的定时初值.
TABLE1:
DW64260,64400,64524,64580
DW64684,64777,64820,64898
DW64968,65030,65058,65110
DW65157,65178,65217
;决定音调和节拍的表格,不同的歌曲只是此表不同
TABLE:
DB82H,01H,81H,94H,84H,0B4H,0A4h,04H,82H,01H,81H,94H,84H,0C4H,0B4H,04H;1
DB82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H,0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H ;2
DB82H,01H,81H,94H,84H,0B4H,0A4H,04H,82H,01H,81H,94H,84H,0C4H,0B4H,04H ;3
DB82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H,0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H,00;4
END