
开发板上的8只LED为共阳极连接,即单片机输出端为低电平时即可点亮LED。
程序A:
;用最直接的方式实现流水灯
ORG 0000H
START:MOV P1,#01111111B ;最下面的LED点亮
LCALL DELAY;延时1秒
MOV P1,#10111111B ;最下面第二个的LED点亮
LCALL DELAY;延时1秒
MOV P1,#11011111B ;最下面第三个的LED点亮 (以下省略)
LCALL DELAY
MOV P1,#11101111B
LCALL DELAY
MOV P1,#11110111B
LCALL DELAY
MOV P1,#11111011B
LCALL DELAY
MOV P1,#11111101B
LCALL DELAY
MOV P1,#11111110B
LCALL DELAY
MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒
AJMP START ;反复循环
;延时子程序,12M晶振延时约250毫秒
DELAY:
MOV R4,#2
L3: MOV R2 ,#250
L1: MOV R3 ,#250
L2: DJNZ R3 ,L2
DJNZ R2 ,L1
DJNZ R4 ,L3
RET
END
程序B:
;用移位方式实现流水灯
org 00h ;程序上电从00h开始
ajmp main ;跳转到主程序
org 0030h ;主程序起始地址
main:
mov a,#0feh ;给A赋值成11111110
loop:
mov p1,a ;将A送到P1口,发光二极管低电平点亮
lcall delay ;调用延时子程序
rl a ;累加器A循环左移一位
ajmp loop ;重新送P1显示
delay:
mov r3,#20 ;最外层循环二十次
d1:
mov r4,#80 ;次外层循环八十次
d2:
mov r5,#250 ;最内层循环250次
djnz r5,$ ;总共延时2us*250*80*20=0.8S
djnz r4,d2
djnz r3,d1
ret
end
51单片机经典流水灯程序,在51单片机的P2口接上8个发光二极管,产生流水灯的移动效果。
ORG 0 ;程序从0地址开始
START: MOV A,#0FEH ;让ACC的内容为11111110
LOOP: MOV P2,A ;让P2口输出ACC的内容
RR A ;让ACC的内容左移
CALL DELAY ;调用延时子程序
LJMP LOOP ;跳到LOOP处执行
;0.1秒延时子程序(12MHz晶振)===================
DELAY: MOV R7,#200 ;R7寄存器加载200次数
D1: MOV R6,#250 ;R6寄存器加载250次数
DJNZ R6,$ ;本行执行R6次
DJNZ R7,D1 ;D1循环执行R7次
RET ;返回主程序
END ;结束程序
开关控制的单片机流水灯 汇编
在单片机控制下,用一个拨动开关K1,控制8个发光二极管L1-L8,发光的时间间隔为0.5秒。
具体要求:
当拨动开关K1发出低电平(K1=0)时,L1-L8从两头向中间逐个点亮,当L1-L8全部点亮后延时2秒钟全部熄灭,如此往复循环。
当拨动开关K1发出高电平(K1=1)时,中间的L4、L5点亮,然后点亮的灯向两边扩展,直到L1-L8全部点亮后延时2秒钟全部熄灭,如此往复循环。
悬赏分:20 - 解决时间:2009-12-21 13:42
提问者: ---------
最佳答案:
;--------------------------------------------
下列程序,经过了编译、仿真,可以满足要求。
;--------------------------------------------
ORG 0000H
MOV R2, #0
M_LOOP:
MOV A, R2
INC R2
ANL A, #07H
MOV C, P1.0
MOV ACC.3, C
MOV DPTR, #TAB
MOVC A, @A + DPTR
MOV P0, A
CALL DL5KT
SJMP M_LOOP
;--------------------------------------------
TAB:
DB 0xFF, 0xE7, 0xC3, 0x81, 0x00, 0x00, 0x00, 0x00
DB 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00
;--------------------------------------------
DL5KT:
mov R5, #10
MOV R6, #100
MOV R7, #250
DJNZ R7, $
DJNZ R6, $ - 4
DJNZ R5, $ - 8
RET
;--------------------------------------------
END
流水灯汇编程序
8只LED为共阳极连接,即单片机输出端为低电平时即可点亮LED。
;用最直接的方式实现流水灯
ORG 0000H
START:MOV P1,#01111111B ;最下面的LED点亮
LCALL DELAY ;延时1秒
MOV P1,#10111111B ;最下面第二个的LED点亮
LCALL DELAY ;延时1秒
MOV P1,#11011111B ;最下面第三个的LED点亮 (以下省略)
LCALL DELAY
MOV P1,#11101111B
LCALL DELAY
MOV P1,#11110111B
LCALL DELAY
MOV P1,#11111011B
LCALL DELAY
MOV P1,#11111101B
LCALL DELAY
MOV P1,#11111110B
LCALL DELAY
MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒
AJMP START ;反复循环
;延时子程序,12M晶振延时约250毫秒
DELAY: ;大约值:2us*256*256*2=260ms,也可以认为为250ms
PUSH PSW ;现场保护指令(有时可以不加)
MOV R4,#2
L3: MOV R2 ,#00H
L1: MOV R3 ,#00H
L2: DJNZ R3 ,L2 ;最内层循环:(256次)2个周期指令(R3减一,如果比1大,则转向L2)
DJNZ R2 ,L1 ; 中层循环:256次
DJNZ R4 ,L3 ;外层循环:2次
POP PSW
RET
END
51汇编单片机LED花样流水灯(1)
start:CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
SETB P1.1
ACALL DELAY
CLR P1.2
ACALL DELAY
SETB P1.2
ACALL DELAY
CLR P1.3
ACALL DELAY
SETB P1.3
ACALL DELAY
CLR P1.4
ACALL DELAY
SETB P1.4
ACALL DELAY
CLR P1.5
ACALL DELAY
SETB P1.5
ACALL DELAY
CLR P1.6
ACALL DELAY
SETB P1.6
ACALL DELAY
CLR P1.7
ACALL DELAY
CLR P1.7
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
SETB P1.1
ACALL DELAY
CLR P1.2
ACALL DELAY
SETB P1.2
ACALL DELAY
CLR P1.3
ACALL DELAY
SETB P1.3
ACALL DELAY
CLR P1.4
ACALL DELAY
SETB P1.4
ACALL DELAY
CLR P1.5
ACALL DELAY
SETB P1.5
ACALL DELAY
CLR P1.6
ACALL DELAY
CLR P1.6
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
SETB P1.1
ACALL DELAY
CLR P1.2
ACALL DELAY
SETB P1.2
ACALL DELAY
CLR P1.3
ACALL DELAY
SETB P1.3
ACALL DELAY
CLR P1.4
ACALL DELAY
SETB P1.4
ACALL DELAY
CLR P1.5
ACALL DELAY
CLR P1.5
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
SETB P1.1
ACALL DELAY
CLR P1.2
ACALL DELAY
SETB P1.2
ACALL DELAY
CLR P1.3
ACALL DELAY
SETB P1.3
ACALL DELAY
CLR P1.4
ACALL DELAY
CLR P1.4
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
SETB P1.1
ACALL DELAY
CLR P1.2
ACALL DELAY
SETB P1.2
ACALL DELAY
CLR P1.3
ACALL DELAY
CLR P1.3
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
SETB P1.1
ACALL DELAY
CLR P1.2
ACALL DELAY
CLR P1.2
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
CLR P1.1
ACALL DELAY
CLR P1.1
ACALL DELAY
CLR P1.0
ACALL DELAY
CLR P1.0
ACALL DELAY
SETB P1.0
ACALL DELAY
SETB P1.1
ACALL DELAY
SETB P1.2
ACALL DELAY
SETB P1.3
ACALL DELAY
SETB P1.4
ACALL DELAY
SETB P1.5
ACALL DELAY
SETB P1.6
ACALL DELAY
SETB P1.7
ACALL DELAY
AJMP start
DELAY:MOV R7,#250
D1:MOV R6,#250
D2:DJNZ R6,D2
DJNZ R7,D1
RET
END
开发板上的8只LED为共阳极连接,即单片机输出端为低电平时即可点亮LED。
程序A:
;用最直接的方式实现流水灯
ORG 0000H
START:MOV P1,#01111111B ;最下面的LED点亮
LCALL DELAY;延时1秒
MOV P1,#10111111B ;最下面第二个的LED点亮
LCALL DELAY;延时1秒
MOV P1,#11011111B ;最下面第三个的LED点亮 (以下省略)
LCALL DELAY
MOV P1,#11101111B
LCALL DELAY
MOV P1,#11110111B
LCALL DELAY
MOV P1,#11111011B
LCALL DELAY
MOV P1,#11111101B
LCALL DELAY
MOV P1,#11111110B
LCALL DELAY
MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒
AJMP START ;反复循环
;延时子程序,12M晶振延时约250毫秒
DELAY:
MOV R4,#2
L3: MOV R2 ,#250
L1: MOV R3 ,#250
L2: DJNZ R3 ,L2
DJNZ R2 ,L1
DJNZ R4 ,L3
RET
END
程序B:
;用移位方式实现流水灯
org 00h ;程序上电从00h开始
ajmp main ;跳转到主程序
org 0030h ;主程序起始地址
main:
mov a,#0feh ;给A赋值成11111110
loop:
mov p1,a ;将A送到P1口,发光二极管低电平点亮
lcall delay ;调用延时子程序
rl a ;累加器A循环左移一位
ajmp loop ;重新送P1显示
delay:
mov r3,#20 ;最外层循环二十次
d1:
mov r4,#80 ;次外层循环八十次
d2:
mov r5,#250 ;最内层循环250次
djnz r5,$ ;总共延时2us*250*80*20=0.8S
djnz r4,d2
djnz r3,d1
ret
end
51单片机汇编程序集
作者:段磊 文章来源:网络 点击数:1176 更新时间:2008-9-23 20:53:39
1、片内RAM初始化子程序
2、片外RAM初始化子程序
3、片外RAM初始化子程序(双字节个单元)
4、内部RAM数据复制程序
5、外部RAM数据复制程序
6、外部RAM数据复制程序
7、外部RAM数据复制到内部RAM程序
8、限幅滤波程序
9、中位值滤波程序
10、N点算术平均滤波
11、N点加权平均滤波
12、一阶加权滞后滤波程序
13、双字节取补程序
14、N节取补程序
15、双字节无符号数加法程序
16、N字节无符号数加法程序
17、双字节无符号数减法程序
18、N字节无符号数减法程序
19、单字节无符号数乘法程序
20、单字节无符号数乘法程序
21、单字节无符号数乘法程序
22、双字节无符号数乘法程序
23、双字节无符号数乘法程序
24、N字节无符号数乘法程序
25、单字节无符号除法程序
26、单字节无符号除法程序
27、双字节无符号除法程序
28、N字节无符号除法程序(组合)
29、N字节无符号除法程序
30、N字节数据左移程序
31、原码有符号双字节减法程序
32、原码有符号双字节加法程序
33、原码有符号双字节乘法程序
34、原码有符号双字节除法程序
35、单字节顺序查找程序
36、单字节顺序查找程序
37、双字节字符串顺序查找程序
38、双字节字符串顺序查找程序
39、N字节字符串顺序查找程序
40、单字节最值查找程序
41、浮点数顺序查找程序
42、浮点数最值查找程序
43、单字节折半查找程序
;片内RAM初始化子程序
IBCLR :MOV A,R0
MOV R1,A
CLR A
IBC1 :MOV @R1,A
INC R1
DJNZ R7,IBC1
RET
;片外RAM初始化子程序
EBCLR1 :MOV A,ADDPL
MOV DPL,A
MOV A,ADDPH
MOV DPH,A
CLR C
EBC11 :MOVX @DPTR,A
INC DPTR
DJNZ R7,EBC11
RET
;片外RAM初始化子程序(双字节个单元)
EBCLR2 :MOV A,ADDPL
MOV DPL,A
MOV A,ADDPH
MOV DPH,A
MOV A,R7
JZ EBC21
INC R6
EBC21 :CLR A
MOVX @DPTR,A
INC DPTR
DJNZ R7,EBC21
DJNZ R6,EBC21
RET
;内部RAM数据复制程序
;入口 :R0,R7
;占用资源:A
;堆栈需求:2字节
;出口 :R1
IBMOV :MOV A,R0
ADD A,R7
MOV R0,A
MOV A,R1
ADD A,R7
MOV R1,A
IBM1 :DEC R0
DEC R1
MOV A,@R0
MOV @R1,A
DJNZ R7,IBM1
RET
;外部RAM数据复制程序
;入口 :ADDPH,ADDPL,R7
;占用资源:ACC
;堆栈需求:2字节
;出口 :R0,R1
EBMOV1 :MOV A,ADDPL
ADD A,R7
MOV DPL,A
CLR A
ADDC A,ADDPH
MOV DPH,A
MOV A,R7
ADD A,R1
XCH A,R0
ADDC A,#00H
MOV P2,A
EBM11 :DEC R0
CJNE R0,#0FFH,EBM12
DEC P2
EBM12 :DEC DPL
MOV A,DPL
CJNE A,#0FFH,EBM13
DEC DPH
EBM13 :MOVX A,@R0
MOVX @DPTR,A
DJNZ R7,EBM11
RET
;外部RAM数据复制程序
;入口 :ADDPH,ADDPL,R6,R7
;占用资源:ACC
;堆栈需求:2字节
;出口 :R0,R1
EBMOV2 :MOV A,ADDPL
ADD A,R7
MOV DPL,A
MOV A,R6
ADDC A,ADDPH
MOV DPH,A
MOV A,R7
ADD A,R1
XCH A,R0
ADDC A,R6
MOV P2,A
MOV A,R7
JZ EBM21
INC R6
EBM21 :DEC R0
CJNE R0,#0FFH,EBM22
DEC P2
EBM22 :DEC DPL
MOV A,DPL
CJNE A,#0FFH,EBM23
DEC DPH
EBM23 :MOVX A,@R0
MOVX @DPTR,A
DJNZ R7,EBM21
DJNZ R6,EBM21
RET
;外部RAM数据复制到内部RAM程序
;入口 :ADDPH,ADDPL,R7
;占用资源:ACC
;堆栈需求:2字节
;出口 :R0
ITEMOV :MOV A,ADDPL
ADD A,R7
MOV DPL,A
MOV A,ADDPH
ADDC A,#00H
MOV DPH,A
MOV A,R0
ADD A,R7
MOV R0,A
ITEM1 :DEC R0
DEC DPL
MOV A,DPL
CJNE A,#0FFH,ITEM2
DEC DPH
ITEM2 :MOVX A,@DPTR
MOV @R0,A
DJNZ R7,ITEM1
RET
;限幅滤波程序
;入口 :A,SDAT,DELTY
;占用资源:B
;堆栈需求:2字节
;出口 :A
JUGFILT :MOV B,A
CLR C
SUBB A,SDAT
JNC JUGFT1
CPL A
INC A
JUGFT1 :SETB A
SUBB A,#DELTY
JNC JUGFT3
MOV A,SDAT
RET
JUGFT3 :MOV A,B
MOV SDAT,A
RET
;中位值滤波程序
;入口 :ADDPH,ADDPL,N
;占用资源:ESELSORT
;堆栈需求:4字节
;出口 :A
MEDFILT :LCALL ESELSORT
MOV A,N
CLR C
RRC A
ADD A,ADDPL
MOV DPL,A
MOV A,ADDPH
MOV DPH,A
JNC MEDFT1
INC DPH
51单片机汇编程序集(二)
2008年12月12日 星期五 10:27
辛普生积分程序
内部RAM数据排序程序(升序)
外部RAM数据排序程序(升序)
外部RAM浮点数排序程序(升序)
BCD小数转换为二进制小数(2位)
BCD小数转换为二进制小数(N位)
BCD整数转换为二进制整数(1位)
BCD整数转换为二进制整数(2位)
BCD整数转换为二进制整数(3位)
BCD整数转换为二进制整数(N位)
二进制小数(2位)转换为十进制小数(分离BCD码)
二进制小数(M位)转换为十进制小数(分离BCD码)
二进制整数(2位)转换为十进制整数(分离BCD码)
二进制整数(2位)转换为十进制整数(组合BCD码)
二进制整数(3位)转换为十进制整数(分离BCD码)
二进制整数(3位)转换为十进制整数(组合BCD码)
二进制整数(M位)转换为十进制整数(组合BCD码)
三字节无符号除法程序(R2R3R4/R7)=(R2)R3R4 余数R7
;辛普生积分程序
;入口: DPTR,N,COUNT
;占用资源: ACC,R3,R4,R6,R7
;堆栈需求: 2字节
;出口: R3,R4
SJF : MOV R7,N
MOVX A,@DPTR
INC DPTR
MOV R4,A
MOV R3,#00H
DEC R7
SJF1 : MOVX A,@DPTR
INC DPTR
CLR C
RLC A
MOV R6,A
CLR A
RLC A
XCH A,R7
JNB ACC.0,SJF2
XCH A,R6
RLC A
XCH A,R6
XCH A,R7
RLC A
XCH A,R7
SJF2 : XCH A,R7
XCH A,R6
ADD A,R4
MOV R4,A
MOV A,R6
ADDC A,R3
MOV R3,A
DJNZ R7,SJF1
SJF3 : MOVX A,@DPTR
ADD A,R4
MOV R4,A
CLR A
ADDC A,R3
MOV R3,A
MOV R7,#COUNT
LCALL NMUL21
MOV A,N
MOV B,#03H
MUL AB
MOV R7,A
LCALL NDIV31
RET
NMUL21 : MOV A,R4
MOV B,R7
MUL AB
MOV R4,A
MOV A,B
XCH A,R3
MOV B,R7
MUL AB
ADD A,R3
MOV R3,A
CLR A
ADDC A,B
MOV R2,A
CLR OV
RET
NDIV31 : MOV B,#10H
NDV311 : CLR C
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
MOV F0,C
CLR C
SUBB A,R7
JB F0,NDV312
JC NDV313
NDV312 : MOV R2,A
INC R4
NDV313 : DJNZ B,NDV311
RET
;内部RAM数据排序程序(升序)
;入口: R0(起始地址),N(数据个数)
;占用资源: ACC,B,R5,R6,R7
;堆栈需求: 2字节
;出口: R0
ISELSORT : MOV R7,N
DEC R7
ISST1: MOV A,R7
MOV R6,A
MOV A,R0
MOV R1,A
MOV R2,A
MOV B,@R1
ISST2: INC R1
MOV A,@R1
CLR C
SUBB A,B
JC ISST3
MOV A,R1
MOV R2,A
MOV B,@R1
ISST3: DJNZ R6,ISST2
MOV A,B
XCH A,@R1
MOV B,R2
MOV R1,B
MOV @R1,A
DJNZ R7,ISST1
RET
;外部RAM数据排序程序(升序)
;入口: ADDPH,ADDPL(起始地址),N(数据个数)
;占用资源: ACC,B,R0,R1,R5,R7
;堆栈需求: 2字节
;出口: ADDPH-ADDPL
ESELSORT : MOV R7,N
DEC R7
ESST1: MOV A,R7
MOV R6,A
MOV DPL,ADDPL
MOV R1,DPL
MOV DPH,ADDPH
MOV R0,DPH
MOVX A,@DPTR
MOV B,A
ESST2: INC DPTR
MOVX A,@DPTR
CLR C
SUBB A,B
JC ESST3
MOV R0,DPL
MOV R1,DPH
MOVX A,@DPTR
MOV B,A
ESST3: DJNZ R6,ESST2
MOVX A,@DPTR
XCH A,B
MOVX @DPTR,A
MOV DPL,R0
MOV DPH,R1
MOV A,B
MOVX @DPTR,A
DJNZ R7,ESST1
RET
;外部RAM浮点数排序程序(升序)
;入口: ADDPH,ADDPL(起始地址),N(数据个数)
;占用资源: ACC,B,R0,R1,R2,R3,R4,R5,R6,R7,NCNT
;堆栈需求: 5字节
;出口: ADDPH,ADDPL
FSORT: MOV A,N
MOV NCNT,A
DEC NCNT
FST1 : MOV B,NCNT
MOV DPL,ADDPL
MOV R1,DPL
MOV DPH,ADDPH
MOV R0,DPH
MOVX A,@DPTR
MOV R2,A
INC DPTR
MOVX A,@DPTR
MOV R3,A
INC DPTR
MOVX A,@DPTR
MOV R4,A
FST2 : INC DPTR
MOVX A,@DPTR
MOV R5,A
INC DPTR
MOVX A,@DPTR
MOV R6,A
INC DPTR
MOVX A,@DPTR
MOV R7,A
PUSH B
LCALL FCMP
POP B
JNC FST4
MOV A,DPL
CLR C
SUBB A,#02H
MOV R1,A
MOV R0,DPH
JNC FST3
DEC R0
FST3 : MOV A,R5
MOV R2,A
MOV A,R6
MOV R3,A
MOV A,R7
MOV R4,A
FST4 : DJNZ B,FST2
MOV A,DPL
CLR C
SUBB A,#02H
MOV DPL,A
JNC FST5
DEC DPH
FST5 : MOV A,R2
MOVX @DPTR,A
INC DPTR
MOV A,R3
MOVX @DPTR,A
INC DPTR
MOV A,R4
MOVX @DPTR,A
MOV A,R0
MOV P2,A
MOV A,R5
MOVX @R1,A
INC R1
MOV A,R6
MOVX @R1,A
INC R1
MOV A,R7
MOVX @R1,A
DJNZ NCNT,FST1
RET
;BCD小数转换为二进制小数(2位)
;入口: R0(低位首址),R7
;占用资源: ACC,B,R5
;堆栈需求: 2字节
;出口: R3,R4
PDTB : CLR A
MOV R3,A
MOV R4,A
PDB1 : MOV A,R3
MOV B,#9AH
MUL AB
MOV R5,B
XCH A,R4
MOV B,#19H
MUL AB
ADD A,R4
MOV A,R5
ADDC A,B
MOV R5,A
MOV A,@R0
MOV B,#9AH
MUL AB
ADD A,R5
MOV R4,A
CLR A
ADDC A,B
XCH A,R3
MOV B,#19H
MUL AB
ADD A,R4
MOV R4,A
MOV A,B
ADDC A,R3
MOV R3,A
MOV A,@R0
MOV B,#19H
MUL AB
ADD A,R3
MOV R3,A
DEC R0
DJNZ R7,PDB1
RET
;BCD小数转换为二进制小数(N位)
;入口: R1(低位首址),M,N
;占用资源: ACC,B,R2,R3,R7
;堆栈需求: 2字节
;出口: R0
PDTBMN : MOV A,R0
MOV R2,A
MOV A,R1
MOV R3,A
MOV B,N
CLR A
PDBMN1 : MOV @R0,A
INC R0
DJNZ B,PDBMN1
MOV A,N
SWAP A
RR A
MOV R7,A
PDBMN2 : MOV A,R2
MOV R0,A
MOV A,R3
MOV R1,A
MOV B,M
CLR C
PDBMN3 : MOV A,@R1
ADDC A,@R1
DA A
JNB ACC.4,PDBMN4
SETB C
CLR ACC.4
PDBMN4 : MOV @R1,A
INC R1
DJNZ B,PDBMN3
MOV B,N
PDBMN5 : MOV A,@R0
RLC A
MOV @R0,A
INC R0
DJNZ B,PDBMN5
DJNZ R7,PDBMN2
MOV A,R2
MOV R0,A
RET
;BCD整数转换为二进制整数(1位)
;入口: R0(高位地址),R7
;占用资源: ACC,B
;堆栈需求: 2字节
;出口: R4
IDTB1: CLR A
MOV R4,A
IDB11: MOV A,R4
MOV B,#0AH
MUL AB
ADD A,@R0
INC R0
MOV R4,A
DJNZ R7,IDB11
RET
;BCD整数转换为二进制整数(2位)
;入口: R0(高位地址),R7
;占用资源: ACC,B
;堆栈需求: 2字节
;出口: R3,R4
IDTB2: CLR A
MOV R3,A
MOV R4,A
IDB21: MOV A,R4
MOV B,#0AH
MUL AB
MOV R4,A
MOV A,B
XCH A,R3
MOV B,#0AH
MUL AB
ADD A,R3
MOV R3,A
MOV A,R4
ADD A,@R0
INC R0
MOV R4,A
CLR A
ADDC A,R3
MOV R3,A
DJNZ R7,IDB21
RET
;BCD整数转换为二进制整数(3位)
;入口: R0(高位地址),R7
;占用资源: ACC,B
;堆栈需求: 2字节
;出口: R2,R3,R4
IDTB3: CLR A
MOV R2,A
MOV R3,A
MOV R4,A
IDB31: MOV A,R4
MOV B,#0AH
MUL AB
MOV R4,A
MOV A,B
XCH A,R3
MOV B,#0AH
MUL AB
ADD A,R3
MOV R3,A
CLR A
ADDC A,B
XCH A,R2
MOV B,#0AH
MUL AB
ADD A,R2
MOV R2,A
MOV A,R4
ADD A,@R0
INC R0
MOV R4,A
CLR A
ADDC A,R3
MOV R3,A
CLR A
ADDC A,R2
MOV R2,A
DJNZ R7,IDB31
RET
;BCD整数转换为二进制整数(N位)
;入口: R1(高位地址),M,N
;占用资源: ACC,B,R2,R7,NCNT,F0
;堆栈需求: 2字节
;出口: R0
IDTBMN : MOV A,R0
MOV R2,A
MOV B,N
CLR A
IDBMN1 : MOV @R0,A
INC R0
DJNZ B,IDBMN1
MOV A,R2
MOV R0,A
MOV A,M
MOV NCNT,A
IDBMN2 : MOV R7,N
CLR A
CLR F0
IDBMN3 : XCH A,@R0
MOV B,#0AH
MUL AB
MOV C,F0
ADDC A,@R0
MOV F0,C
MOV @R0,A
INC R0
MOV A,B
DJNZ R7,IDBMN3
MOV A,R2
MOV R0,A
MOV A,@R1
INC R1
ADD A,@R0
MOV @R0,A
DJNZ NCNT,IDBMN2
RET
;二进制小数(2位)转换为十进制小数(分离BCD码)
;入口: R3,R4,R7
;占用资源: ACC,B
;堆栈需求: 3字节
;出口: R0
PBTD : MOV A,R7
PUSH A
PBD1 : MOV A,R4
MOV B,#0AH
MUL AB
MOV R4,A
MOV A,B
XCH A,R3
MOV B,#0AH
MUL AB
ADD A,R3
MOV R3,A
CLR A
ADDC A,B
MOV @R0,A
INC R0
DJNZ R7,PBD1
POP A
MOV R7,A
MOV A,R0
CLR C
SUBB A,R7
MOV R0,A
RET
;二进制小数(M位)转换为十进制小数(分离BCD码)
;入口: R1,M,N
;占用资源: ACC,B,R2,R3,R7,NCNT
;堆栈需求: 2字节
;出口: R0
PBTDMN : MOV A,R0
MOV R2,A
MOV A,R1
MOV R3,A
MOV A,N
MOV NCNT,A
PBDMN1 : MOV R7,M
CLR A
CLR F0
PBDMN2 : XCH A,@R1
MOV B,#0AH
MUL AB
MOV C,F0
ADDC A,@R1
MOV F0,C
MOV @R1,A
INC R1
MOV A,B
DJNZ R7,PBDMN2
ADDC A,#00H
MOV @R0,A
INC R0
MOV A,R3
MOV R1,A
DJNZ NCNT,PBDMN1
MOV A,R2
MOV R0,A
RET
;二进制整数(2位)转换为十进制整数(分离BCD码)
;入口: R3,R4
;占用资源: ACC,R2,NDIV31
;堆栈需求: 5字节
;出口: R0,NCNT
IBTD21 : MOV NCNT,#00H
MOV R2,#00H
IBD211 : MOV R7,#0AH
LCALL NDIV31
MOV A,R7
MOV @R0,A
INC R0
INC NCNT
MOV A,R3
ORL A,R4
JNZ IBD211
MOV A,R0
CLR C
SUBB A,NCNT
MOV R0,A
RET
;二进制整数(2位)转换为十进制整数(组合BCD码)
;入口: R3,R4
;占用资源: ACC,B,R7
;堆栈需求: 3字节
;出口: R0
IBTD22 : MOV A,R0
PUSH A
MOV R7,#03H
CLR A
IBD221 : MOV @R0,A
INC R0
DJNZ R7,IBD221
POP A
MOV R0,A
MOV R7,#10H
IBD222 : PUSH A
CLR C
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
MOV B,#03H
IBD223 : MOV A,@R0
ADDC A,@R0
DA A
MOV @R0,A
INC R0
DJNZ B,IBD223
POP A
MOV R0,A
DJNZ R7,IBD222
RET
;二进制整数(3位)转换为十进制整数(分离BCD码)
;入口: R2,R3,R4
;占用资源: ACC,R2,NDIV31
;堆栈需求: 5字节
;出口: R0,NCNT
IBTD31 : CLR A
MOV NCNT,A
IBD311 : MOV R7,#0AH
LCALL NDIV31
MOV A,R7
MOV @R0,A
INC R0
INC NCNT
MOV A,R2
ORL A,R3
ORL A,R4
JNZ IBD311
MOV A,R0
CLR C
SUBB A,NCNT
MOV R0,A
RET
;二进制整数(3位)转换为十进制整数(组合BCD码)
;入口: R2,R3,R4
;占用资源: ACC,B,R7
;堆栈需求: 3字节
;出口: R0
IBTD32 : MOV A,R0
PUSH A
MOV R7,#04H
CLR A
IBD321 : MOV @R0,A
INC R0
DJNZ R7,IBD321
POP A
MOV R0,A
MOV R7,#18H
IBD322 : PUSH A
CLR C
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
MOV B,#04H
IBD323 : MOV A,@R0
ADDC A,@R0
DA A
MOV @R0,A
INC R0
DJNZ B,IBD323
POP A
MOV R0,A
DJNZ R7,IBD322
RET
;二进制整数(M位)转换为十进制整数(组合BCD码)
;入口: R1,M,N
;占用资源: ACC,B,R2,R3,R7
;堆栈需求: 2字节
;出口: R0
IBTDMN : MOV A,R0
MOV R2,A
MOV A,R1
MOV R3,A
MOV B,N
CLR A
IBDMN1 : MOV @R0,A
INC R0
DJNZ B,IBDMN1
MOV A,M
SWAP A
RR A
CLR C
MOV R7,A
IBDMN2 : MOV A,R2
MOV R0,A
MOV A,R3
MOV R1,A
MOV B,M
IBDMN3 : MOV A,@R1
RLC A
MOV @R1,A
INC R1
DJNZ B,IBDMN3
MOV B,N
IBDMN4 : MOV A,@R0
ADDC A,@R0
DA A
JNB ACC.4,IBDMN5
SETB C
CLR ACC.4
IBDMN5 : MOV @R0,A
INC R0
DJNZ B,IBDMN4
DJNZ R7,IBDMN2
MOV A,R2
MOV R0,A
RET
;三字节无符号除法程序(R2R3R4/R7)=(R2)R3R4 余数R7
;入口: R2,R3,R4,R7
;占用资源: ACC,B,F0
;堆栈需求: 3字节
;出口: (R2),R3,R4,R7,OV
NDIV31 : MOV A,R2
MOV B,R7
DIV AB
PUSH A
MOV R2,B
MOV B,#10H
NDV311 : CLR C
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
MOV F0,C
CLR C
SUBB A,R7
JB F0,NDV312
JC NDV313
NDV312 : MOV R2,A
INC R4
NDV313 : DJNZ B,NDV311
POP A
CLR OV
JZ NDV314
SETB OV
NDV314 : XCH A,R2
MOV R7,A
| RET |
该程序运行结果为个位数码管轮流现实0,1,2,3,4,5,6,7,8
然后十位数码管轮流现实0,1,2,3,4,5,6,7,8反复循环
P1.0,P1.1, P1.2,P1.3, P1.4,P1.5, P1.6,P1.7, 依次点亮然后轮流点亮
小喇叭不停发出滴答声:
注意该程序配套为我站的倚天版开发套件:如果是标准版:因他的数码管接法不同。 显示的数字不对。
该程序在本站XP开发套件上调试通过,以下是程序运行在XP版时的照片.(sorry, 照片很模糊)
数码管显示数字
注意0为点亮 1 为灭
显示数字 p0.7 p0.6 p0.5 p0.4 p0.3 p0.2 p0.1 p0.0 16进制代码
0 0 0 1 0 1 0 0 0 28H
1 0 1 1 1 1 1 1 0 7EH
2 1 0 1 0 0 0 1 0 A2H
3 0 1 1 0 0 0 1 0 62H
4 0 1 1 1 0 1 0 0 74H
5 0 1 1 0 0 0 0 1 61H
6 0 0 1 0 0 0 0 1 21H
7 0 1 1 1 1 0 1 0 7AH
8 0 0 1 0 0 0 0 0 20H
9 0 1 1 0 0 0 0 0 60H
代码表的意思和方法参照前面的教程; 注意0为点亮 1 为灭然后我们可以把代码送到P0口,就可以是数码管显示需要的数字; 当然, 必须有位选,因为我们的实验板是动态扫描数码管, 两个8的位选分别是P2.6 P2.7.
L; 标号
C;选中p2.6 数码管左边的8字使能
S;p2.7不使能。 右边的数码管消隐
MOV P0,#28H ;把28h送p0口;数码管显示 0
LCALL DELAY ;延时
M;0ffh 送p0口,数码管清除
C;点亮p1.0发光管
MOV P0,#7EH ;把7eh送p0口;数码管显示 1
LCALL DELAY
MOV P0,#0FFH
C点亮p1.0发光管
C点亮p1.0发光管
M数码管显示 2
LCALL DELAY
MOV P0,#0FFH
CLR P1.2
CLR P1.1
CLR P1.0
M数码管显示 3
LCALL DELAY
MOV P0,#0FFH
CLR P1.3
CLR P1.2
CLR P1.1
CLR P1.0
M数码管显示 4
LCALL DELAY
MOV P0,#0FFH
CLR P1.4
CLR P1.3
CLR P1.2
CLR P1.1
CLR P1.0
M数码管显示 5;
LCALL DELAY
MOV P0,#0FFH
CLR P1.5
CLR P1.4
CLR P1.3
CLR P1.2
CLR P1.1
CLR P1.0
M数码管显示 6
LCALL DELAY
MOV P0,#0FFH
CLR P1.6
CLR P1.5
CLR P1.4
CLR P1.3
CLR P1.2
CLR P1.1
CLR P1.0
M数码管显示 7
LCALL DELAY
MOV P0,#0FFH
CLR P1.7
CLR P1.6
CLR P1.5
CLR P1.4
CLR P1.3
CLR P1.2
CLR P1.1
CLR P1.0
M数码管显示 8
LCALL DELAY
MOV P0,#0FFH
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
;程序到此结果为左边的数码管显示0,1,2,3,4,5,6,7,8
;p1.0------------p1.7指示灯依次点亮
S; 左边的8消隐
C;选中p2.7 数码管右边的8字使能 ,;
MOV P0,#28H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.0
MOV P0,#7EH
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.1
MOV P0,#0A2H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.2
MOV P0,#62H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.3
MOV P0,#74H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.4
MOV P0,#61H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.5
MOV P0,#21H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.6
MOV P0,#7AH
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
CLR P1.7
MOV P0,#20H
LCALL DELAY
MOV P0,#0FFH
MOV P1,#0FFH
MOV P0,#0FFH
MOV P1,#0FFH
;这一段和上一段基本相同, 不同的是右边的数码管依次显示012345678,左边的不亮;
;同时p1口的灯流动显示:
AJMP LOOP; 注意: 程序运行到此跳转到开始标号,重复执行:
DELAY: ;延时子程序;参考前面的教程:
CLR P3.3 ;注意小喇叭在3.3口, 这里可以使小喇叭发出嗒,嗒声
MOV R7,#255
NOP
NOP
D1:MOV R6,#255
setb p3.3
D2: DJNZ R6,D2
clr p3.3
DJNZ R7,D1
SETB P3.3
RET
END
第六个试验:认识数码管扫描程序----51单片机汇编语言试验教程 收藏
玩单片机一定要玩转数码管了;上图是我们xp套件的两位数码管的截图照片;这个数码管怎样来显示1,2,3,4呢?别着急, 听我慢慢道来。
数码管实际上是由7个发光管组成8字形构成的,加上小数点就是8个。
我们的xp套件和倚天套件用的都是两位8的共阳极扫描型数码管。
什么是共阳极呢;就是他们的公共端接正极。扫描型的意思是,几位的数码管的段选都是并联的
由他们的位选位来控制哪一位的数码管来亮。 看看上面的照片,由两个黑糊糊的三极管,来控制两边的数码管
哪一边亮。
动态扫描显示接口是单片机中应用最为广泛的一种显示方式之一。其接口电路是把所有显示器的8个笔划段a-h同名端连在一起,而每一个显示器的公共极COM是各自地受I/O线控制。CPU向字段输出口送出字形码时,所有显示器接收到相同的字形码,但究竟是那个显示器亮,则取决于COM端,而这一端是由I/O控制的,所以我们就可以自行决定何时显示哪一位了。而所谓动态扫描就是指我们采用分时的方法,轮流控制各个显示器的COM端,使各个显示器轮流点亮。
在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。
现在大家应当明白了我们应当怎样做, 如果显示一个2字,那么呢应当是A亮B亮G亮E亮D亮F不亮C不亮。
现在在看看我们的倚天套件的硬件原理。
可以看到他的COM端由两个A1015的三极管控制,控制端分别接在P2.6, P2.7,字段则分别接在P0.0--0.7口。
假如我们要让左边的数码管显示一个2字
可以编以下的程序。
CLR P2.6;选中左边的数码管
SETB P2.7;不选右边的数码管
SETB P0.7;B段不亮
SETB P0.5;小数点不亮
SETB P0.1;C段不亮
CLR P0.2;其余的都亮
CLR P0.3
CLR P0.4
CLR P0.6
CLR P0.0
END
运行程序可以看到他们显示的数字为2。
在这样一种情况下, 我们会发现这个程序非常麻烦。呵呵,现在回到上面一课,跟我来作加减法;就会发现
一排数字其实就是二进制的数字。 我们把他转换为16进制。 直接送到P0口就行啦。
注意0为点亮 1 为灭
显示数字 p0.7 p0.6 p0.5 p0.4 p0.3 p0.2 p0.1 p0.0 16进制代码
0 0 0 1 0 1 0 0 0 28H
1 0 1 1 1 1 1 1 0 7EH
2 1 0 1 0 0 0 1 0 A2H
3 0 1 1 0 0 0 1 0 62H
4 0 1 1 1 0 1 0 0 74H
5 0 1 1 0 0 0 0 1 61H
6 0 0 1 0 0 0 0 1 21H
7 0 1 1 1 1 0 1 0 7AH
8 0 0 1 0 0 0 0 0 20H
9 0 1 1 0 0 0 0 0 60H
我们把他从高往低排列为二进制,例如2,就是10100010, 用计算器转换为16进制就是A2.我们在单片机里为了把16进制和10 进制有所区别, 就把16进制后面跟一个H,同时如果首位为字母的为了区别于指令, 同时前面跟一个0, 就成了0A2H了。
大家可能有一点疑问, 为啥P0.5始终为1呢。 因为它接在小数点上。我们没有用它而已。
根据上面的方法。如果我们把数码管的接线给打乱, 同样的可以分析出他的数字代码。
现在程序就简单啦:
还是显示一个2字:
CLR P2.6;选中右边的数码管
SETB P2.7;不选左边的数码管
MOV P0,#0A2H;将10100010送P0口
END
可以看到显示的结果是一样的。
把所有的代码分析出来后以后编程序就可以直接调用啦。 我们的倚天版套件注意一共用了4个数码管
他们的位选为P2.3 P2.4 P2.6 P2.7 这样他一共可以显示四位数字。甚至我们可以直接用它来做一个
显示仪表,或者闹钟了。
他的0,1,2,3,4,5,6,7,8,9 的代码分别为28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h
以下为我们的倚天版开发套件运行现实8051的程序
loop:
mov p0,#0ffh;关显示
mov p2,#0ffh;关显示
clr p2.4 ;选中第一个数码管
mov p0,#20h ;数码管显示8
lcall delay;调用延时
mov p0,#0ffh
mov p2,#0ffh
clr p2.5;选中第二个数码管
mov p0,#28h;数码管显示0
lcall delay
mov p2,#0ffh
mov p0,#0ffh
clr p2.6;选中第三个数码管
mov p0,#61h;数码管显示5
lcall delay
mov p0,#0ffh
mov p2,#0ffh
clr p2.7;选中第四个数码管
mov p0,#7eh;数码管显示1
lcall delay
ajmp loop;程序条转到第一步,反复执行
delay:;延时子程序
mov r6,#250
d1:djnz r6,d1
ret
end
单片机流水灯程序总结
文章发表于:2007-08-24 13:23
程序A:
ORG 0000H
START:MOV P1,#01111111B ;最下面的LED点亮
LCALL DELAY
MOV P1,#10111111B ;最下面第二个的LED点亮
LCALL DELAY
MOV P1,#11011111B ;最下面第三个的LED点亮 (以下省略)
LCALL DELAY
MOV P1,#11101111B
LCALL DELAY
MOV P1,#11110111B
LCALL DELAY
MOV P1,#11111011B
LCALL DELAY
MOV P1,#11111101B
LCALL DELAY
MOV P1,#11111110B
LCALL DELAY
MOV P1,#11111111B ;完成第一次循环点亮,延时约0.25秒
AJMP START ;反复循环
;延时子程序,12M晶振延时约250毫秒
DELAY:
MOV R4,#2
L3: MOV R2 ,#250
L1: MOV R3 ,#250
L2: DJNZ R3 ,L2
DJNZ R2 ,L1
DJNZ R4 ,L3
RET
END
程序B:
org 00h ;程序上电从00h开始
ajmp main ;跳转到主程序
org 0030h ;主程序起始地址
main:
mov a,#0feh ;给A赋值成11111110
loop:
mov p1,a ;将A送到P1口,发光二极管低电平点亮
lcall delay ;调用延时子程序
rl a ;累加器A循环左移一位
ajmp loop ;重新送P1显示
delay:
mov r3,#20 ;最外层循环二十次
d1:
mov r4,#80 ;次外层循环八十次
d2:
mov r5,#250 ;最内层循环250次
djnz r5,$ ;总共延时2us*250*80*20=0.8S
djnz r4,d2
djnz r3,d1
ret
end
程序C:
#include #include void delayms(unsigned char ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } } main() { unsigned char LED; LED = 0xfe; P1 = LED; while(1) { delayms(200); LED = LED>>1; //循环右移1位,点亮下一个LED P1 = LED; } } * Welcome to www.51sopc.com chiptype:ATS52 (6MHz) keil C 7.50 By Tigerman(站长) */ #include void delay(int i); int main(void) { while (1) { int i; for(i=0;i<8;i++) { P1=(1< delay(1000); } for(i=0;i<8;i++) { P1=(1<<(7-i));//反向流水灯 delay(1000); } } } void delay(int i) { int j="0"; for(j=0;j ; } c语言流水灯 c语言流水灯 /******************************************************************************* Title: 演示程序1 - LED流水灯 * Name: ex01.c * Date: 2005-5-5 * Ver: 1.0 * * ********************************************************************************* * 延时实现LED流水灯效果 * * ********************************************************************************* /#include #include void delayms(unsigned char ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } } main() { unsigned char LED; LED = 0xfe; P0 = LED; while(1) { delayms(200); LED = _crol_(LED,1); //循环右移1位,点亮下一个LED P0 = LED; } } ORG 0000H AJMP MAIN ORG 0030H MAIN: MOV A,#0FEH ;送数据初值 MOV P1,A ;数据送P1口点亮发光二极管 ACALL DELAY ;延时 MOV R3,#07H ;设置左移7次 LOOP: RL A ;左移一位 MOV P1,A ;数据送P1口点亮发光二极管 ACALL DELAY ;延时 DJNZ R3,LOOP ;R3是否为0,不为0转LOOP继续执行 AJMP MAIN ;返回主程循环执 DELAY: MOV R7,#255 ;延时子程序 D1: MOV R6,#255 D2: DJNZ R6,D2 DJNZ R7,D1 RET ;子程序返回 END ;程序结束 1.单片机系统中常用的显示器有: 发光二极管LED(Light Emitting Diode)显示器、液晶LCD(Liquid Crystal Display)显示器、CRT显示器等。 2.段选dula 和位选wela:(分别是P2^6,P2^7) 每个8段数码管都有一个公共端,这是位选(P2),低电平有效。数码管的A~G,AP是段选(P0),共阴极结构,所以高电平有效。用2个74HC573来分别控制段选和位选。注意在P0口与锁存器之间要加10K上拉电阻。 3.锁存器 74HC573 原理 锁存器,就是把单片机的输出的数先存起来,可以让单片机继续做其它事.. 比如说,74HC373就是一种锁存器。 它的LE为高的时候,数据就可以通过它.当为低时,它的输出端就会被锁定,即为刚才通过的数据,这样,就可以保持这个状态. 4.一段小程序帮助理解段选位选和锁存器 #include sbit dula=P2^6; sbit wela=P2^7; #define uchar unsigned char #define uint unsigned int uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint); void main() { 这里位选用的是P0,为啥不是P2呢?在我编程时用P2时点不亮数码管 } void delay(uint n) { } 5. 中断的概念 在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生); 暂时中断当前的工作,转去处理事件B(中断响应和中断服务); 待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断 。 6.单片机中断重点。 这里要熟练理解单片机中断源和中断条件。 总中断(EA)-----中断允许位(EX0,ET0,EX1,ET1,ES)------中断标志(IE0,TF0,IE1,TF1) IE包括:EX0,ET0,EX1,ET1,ES,EA. 中断优先级排列:IE0,TF0,IE1,TF1. 中断响应条件: 中断原有中断请求; 此中断源的中断允许位为1; CPU开中断(即EA=1)。 7.中断的子程序: void exter0() interrupt 0 /*interrupt 0是外部中断0,1是T0,2是外部中断1,3是T1,4是串口中断*/ { } 8.定时/计数器的结构 定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。 9. 定时/计数器的工作原理 加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟振荡器输出脉冲经12分频后送来;一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。 可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。 设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t 。 T=50*1/12*12=50 ms 设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2 ms。 10. GATE:门控位。GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚或也为高电平时,才能启动定时/计数器工作。即此时定时器的启动多了一条件。 非) :定时/计数模式选择位。 非) =0为定时模式;C/T(非) =1为计数模式。 M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置。 主要为方式1:TH0控制高8位,TL0控制低8位。要用TO设置TMOD的低8位,要用T1设置TMOD 的高8位。所以我用T0工作在方式1以定时方式的话,就写TMOD=0x01 然后计算TH0和TL0; 计数个数和计数初值的关系:X= -N 如果是50ms 一次的话N=50000,60ms ,N为60000.因为50ms=N*1/12(晶振周期,TX-1C板为11.0592,直接取的12MHZ)*12(固定值,12个晶振周期为1个机器周期)。 这时TH0=(65536-50000)/256 TL0=(65536-50000) %256。 然后开启定时器T0,TR0=1; 注意之前要把中断打开,EA=1,ET0=1,还有在写程序时,中断子程序为interrupt 1,而不是0了。 11.例子: #include #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; sbit d1=P1^0; uchar num,num1;tt; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint z); void main() { 设置定时器0为工作方式1 /开总中断 开定时器0中断 启动定时器0 dula=0; } void delay(uint z) { } void time0() interrupt 1 { } void time1() interrupt 3 { } 第七个试验:流水灯数字显示综合练习----51单片机汇编语言试验教程 收藏 该程序运行结果为个位数码管轮流现实0,1,2,3,4,5,6,7,8 然后十位数码管轮流现实0,1,2,3,4,5,6,7,8反复循环 P1.0,P1.1, P1.2,P1.3, P1.4,P1.5, P1.6,P1.7, 依次点亮然后轮流点亮 小喇叭不停发出滴答声: 注意该程序配套为我站的倚天版开发套件:如果是标准版:因他的数码管接法不同。 显示的数字不对。 该程序在本站XP开发套件上调试通过,以下是程序运行在XP版时的照片. 数码管显示数字 注意0为点亮 1 为灭 显示数字 p0.7 p0.6 p0.5 p0.4 p0.3 p0.2 p0.1 p0.0 16进制代码 0 0 0 1 0 1 0 0 0 28H 1 0 1 1 1 1 1 1 0 7EH 2 1 0 1 0 0 0 1 0 A2H 3 0 1 1 0 0 0 1 0 62H 4 0 1 1 1 0 1 0 0 74H 5 0 1 1 0 0 0 0 1 61H 6 0 0 1 0 0 0 0 1 21H 7 0 1 1 1 1 0 1 0 7AH 8 0 0 1 0 0 0 0 0 20H 9 0 1 1 0 0 0 0 0 60H 代码表的意思和方法参照前面的教程; 注意0为点亮 1 为灭然后我们可以把代码送到P0口,就可以是数码管显示需要的数字; 当然, 必须有位选,因为我们的实验板是动态扫描数码管, 两个8的位选分别是P2.6 P2.7. L; 标号 C;选中p2.6 数码管左边的8字使能 S;p2.7不使能。 右边的数码管消隐 MOV P0,#28H ;把28h送p0口;数码管显示 0 LCALL DELAY ;延时 M;0ffh 送p0口,数码管清除 C;点亮p1.0发光管 MOV P0,#7EH ;把7eh送p0口;数码管显示 1 LCALL DELAY MOV P0,#0FFH C点亮p1.0发光管 C点亮p1.0发光管 M数码管显示 2 LCALL DELAY MOV P0,#0FFH CLR P1.2 CLR P1.1 CLR P1.0 M数码管显示 3 LCALL DELAY MOV P0,#0FFH CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 M数码管显示 4 LCALL DELAY MOV P0,#0FFH CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 M数码管显示 5; LCALL DELAY MOV P0,#0FFH CLR P1.5 CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 M数码管显示 6 LCALL DELAY MOV P0,#0FFH CLR P1.6 CLR P1.5 CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 M数码管显示 7 LCALL DELAY MOV P0,#0FFH CLR P1.7 CLR P1.6 CLR P1.5 CLR P1.4 CLR P1.3 CLR P1.2 CLR P1.1 CLR P1.0 M数码管显示 8 LCALL DELAY MOV P0,#0FFH LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH ;程序到此结果为左边的数码管显示0,1,2,3,4,5,6,7,8 ;p1.0------------p1.7指示灯依次点亮 S; 左边的8消隐 C;选中p2.7 数码管右边的8字使能 ,; MOV P0,#28H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.0 MOV P0,#7EH LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.1 MOV P0,#0A2H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.2 MOV P0,#62H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.3 MOV P0,#74H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.4 MOV P0,#61H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.5 MOV P0,#21H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.6 MOV P0,#7AH LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH CLR P1.7 MOV P0,#20H LCALL DELAY MOV P0,#0FFH MOV P1,#0FFH MOV P0,#0FFH MOV P1,#0FFH ;这一段和上一段基本相同, 不同的是右边的数码管依次显示012345678,左边的不亮; ;同时p1口的灯流动显示: AJMP LOOP; 注意: 程序运行到此跳转到开始标号,重复执行: DELAY: ;延时子程序;参考前面的教程: CLR P3.3 ;注意小喇叭在3.3口, 这里可以使小喇叭发出嗒,嗒声 MOV R7,#255 NOP NOP D1:MOV R6,#255 setb p3.3 D2: DJNZ R6,D2 clr p3.3 DJNZ R7,D1 SETB P3.3 RET END 第三个试验:认识单片机发音程序-----51单片机汇编语言试验教程 什么是声音?上过初中的朋友都知道声音是由震动所产生的。 一定频率的震动就产生了一定频率的声音。 在我们的倚天版开发套件和XP开发套件中,实验版的P3.3口(13脚)接了一个小喇叭,如果我们往它那里送一个高电平,送一个低电平, 他就会发出滴嗒的声音。 我们把上面的闪烁发光管试验的P1.0改为P3.3就好了。 上图就是我们倚天版开发套件的小喇叭 LOOP: SETB P3.3 LCALL DELAY CLR P3.3 LCALL DELAY AJMP LOOP DELAY: MOV R7,#250 D1:MOV R6,#250 D2:DJNZ R6,D2 DJNZ R7,D1 RET END 这时候我们就可以听到小喇叭的响声啦。 可是有的朋友会问,声音又那么多种,怎么办呢?很简单, 我们把它的延时时间给改一下, 声音就会有所变化了。 LOOP: SETB P3.3 LCALL DELAY CLR P3.3 LCALL DELAY AJMP LOOP DELAY: MOV R7,#25 D1:MOV R6,#25 D2:DJNZ R6,D2 DJNZ R7,D1 RET END 这时候我们就可以听到小喇叭发出嘀“的尖叫声。适当的调整他的延时时间, 我们就可以让他发出DO,RUI,MI,FA SO, LA , XI,DO .的声音。 这就使单片机发声的基本原理。 第四个试验:小喇叭发出救护车的声音 这个实验演示了我们的倚天版开发套件小喇叭发出救护车声音的实例, 您直接汇编这个文件, 烧写进我们配送的s51里面, 然后再插入试验卡座。打开电源, 就可以听到喇叭里发出 滴答一长一短的报警声音。这个就有一点点使用价值啦/ 送出的端口是p3.3输出1khz,2khz 变频信号报警。 每一秒交换一次。 dlv: mov r2,#08h;1kz持续时间 dlv1:mov r3,#0fah dlv2:cpl p3.3;输出1khz方波 lcall d5ms;调用延时程序1 djnz r3,dlv2;持续1秒 djnz r2,dlv1 mov r2,#10h;2khz持续时间 dlv3:mov r3,#0fah dlv4:cpl p3.3;输出2khz方波 lcall d25ms;调用延时程序2 djnz r3,dlv4 djnz r2,dlv3 sjmp dlv;反复循环 d5ms:mov r7,#0ffh;延时子程序1 loop:nop nop djnz r7,loop ret d25ms:mov r6,#0ffh;延时子程序2 lin:djnz r6,lin ret end 以下是汇编以后的源代码hex。 :100000007A087BFAB2B312001CDBF9DAF57A107BBE :10001000FAB2B3120023DBF9DAF580E47FFF0000C7 :08002000DFFC227EFFDEFE2260 :00000001FF 第六个试验:认识数码管扫描程序----51单片机汇编语言试验教程 收藏 玩单片机一定要玩转数码管了;上图是我们xp套件的两位数码管的截图照片;这个数码管怎样来显示1,2,3,4呢?别着急, 听我慢慢道来。 数码管实际上是由7个发光管组成8字形构成的,加上小数点就是8个。 我们的xp套件和倚天套件用的都是两位8的共阳极扫描型数码管。 什么是共阳极呢;就是他们的公共端接正极。扫描型的意思是,几位的数码管的段选都是并联的 由他们的位选位来控制哪一位的数码管来亮。 看看上面的照片,由两个黑糊糊的三极管,来控制两边的数码管 哪一边亮。 动态扫描显示接口是单片机中应用最为广泛的一种显示方式之一。其接口电路是把所有显示器的8个笔划段a-h同名端连在一起,而每一个显示器的公共极COM是各自地受I/O线控制。CPU向字段输出口送出字形码时,所有显示器接收到相同的字形码,但究竟是那个显示器亮,则取决于COM端,而这一端是由I/O控制的,所以我们就可以自行决定何时显示哪一位了。而所谓动态扫描就是指我们采用分时的方法,轮流控制各个显示器的COM端,使各个显示器轮流点亮。 在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。 现在大家应当明白了我们应当怎样做, 如果显示一个2字,那么呢应当是A亮B亮G亮E亮D亮F不亮C不亮。 现在在看看我们的倚天套件的硬件原理。 可以看到他的COM端由两个A1015的三极管控制,控制端分别接在P2.6, P2.7,字段则分别接在P0.0--0.7口。 假如我们要让左边的数码管显示一个2字 可以编以下的程序。 CLR P2.6;选中左边的数码管 SETB P2.7;不选右边的数码管 SETB P0.7;B段不亮 SETB P0.5;小数点不亮 SETB P0.1;C段不亮 CLR P0.2;其余的都亮 CLR P0.3 CLR P0.4 CLR P0.6 CLR P0.0 END 运行程序可以看到他们显示的数字为2。 在这样一种情况下, 我们会发现这个程序非常麻烦。呵呵,现在回到上面一课,跟我来作加减法;就会发现 一排数字其实就是二进制的数字。 我们把他转换为16进制。 直接送到P0口就行啦。 注意0为点亮 1 为灭 显示数字 p0.7 p0.6 p0.5 p0.4 p0.3 p0.2 p0.1 p0.0 16进制代码 0 0 0 1 0 1 0 0 0 28H 1 0 1 1 1 1 1 1 0 7EH 2 1 0 1 0 0 0 1 0 A2H 3 0 1 1 0 0 0 1 0 62H 4 0 1 1 1 0 1 0 0 74H 5 0 1 1 0 0 0 0 1 61H 6 0 0 1 0 0 0 0 1 21H 7 0 1 1 1 1 0 1 0 7AH 8 0 0 1 0 0 0 0 0 20H 9 0 1 1 0 0 0 0 0 60H 我们把他从高往低排列为二进制,例如2,就是10100010, 用计算器转换为16进制就是A2.我们在单片机里为了把16进制和10 进制有所区别, 就把16进制后面跟一个H,同时如果首位为字母的为了区别于指令, 同时前面跟一个0, 就成了0A2H了。 大家可能有一点疑问, 为啥P0.5始终为1呢。 因为它接在小数点上。我们没有用它而已。 根据上面的方法。如果我们把数码管的接线给打乱, 同样的可以分析出他的数字代码。 现在程序就简单啦: 还是显示一个2字: CLR P2.6;选中右边的数码管 SETB P2.7;不选左边的数码管 MOV P0,#0A2H;将10100010送P0口 END 可以看到显示的结果是一样的。 把所有的代码分析出来后以后编程序就可以直接调用啦。 我们的倚天版套件注意一共用了4个数码管 他们的位选为P2.3 P2.4 P2.6 P2.7 这样他一共可以显示四位数字。甚至我们可以直接用它来做一个 显示仪表,或者闹钟了。 他的0,1,2,3,4,5,6,7,8,9 的代码分别为28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h 以下为我们的倚天版开发套件运行现实8051的程序 loop: mov p0,#0ffh;关显示 mov p2,#0ffh;关显示 clr p2.4 ;选中第一个数码管 mov p0,#20h ;数码管显示8 lcall delay;调用延时 mov p0,#0ffh mov p2,#0ffh clr p2.5;选中第二个数码管 mov p0,#28h;数码管显示0 lcall delay mov p2,#0ffh mov p0,#0ffh clr p2.6;选中第三个数码管 mov p0,#61h;数码管显示5 lcall delay mov p0,#0ffh mov p2,#0ffh clr p2.7;选中第四个数码管 mov p0,#7eh;数码管显示1 lcall delay ajmp loop;程序条转到第一步,反复执行 delay:;延时子程序 mov r6,#250 d1:djnz r6,d1 ret end 第一个试验:点亮一个发光管-----51单片机汇编语言试验教程 收藏 一、单片机的外部结构 拿到一块芯片,想要使用它,首先必须要知道怎样连线,我们用的一块称之为C51的芯片,下面我们就看一下如何给它连线。 1、 电源:这当然是必不可少的了。单片机使用的是5V电源,其中正极接40引脚,负极(地)接20引脚。 2、 振蒎电路:单片机是一种时序电路,必须提供脉冲信号才能正常工作,在单片机内部已集成了振荡器,使用晶体振荡器,接18、19脚。只要买来晶振,电容,连上就可以了,按图1接上即可。 3、 复位引脚:按图1中画法连好,至于复位是何含义及为何需要复要复位,在单片机功能中介绍。 4、 EA引脚:EA引脚接到正电源端。 至此,一个单片机就接好,通上电,单片机就开始工作了。 当然:您并不一定完全需要一片c51, 实际上我们用8051系列的任何一种芯片都是可以的。 例如s51,c52 等等。 二、 任务分析 我们的第一个任务是要用单片机点亮一只发光二极管LED,显然,这个LED必须要和单片机的某个引脚相连,否则单片机就没法控制它了,那么和哪个引脚相连呢?单片机上除了刚才用掉的5个引脚,还有35个,我们将这个LED和1脚相连。(见图1,其中R1是限流电阻) 按照这个图的接法,当1脚是高电平时,LED不亮,只有1脚是低电平时,LED才发亮。因此要1脚我们要能够控制,也就是说,我们要能够让1引脚按要求变为高或低电平。即然我们要控制1脚,就得给它起个名字,总不能就叫它一脚吧?叫它什么名字呢?设计51芯片的INTEL公司已经起好了,就叫它P1.0,这是规定,不可以由我们来更改。 名字有了,我们又怎样让它变'高'或变'低'呢?叫人做事,说一声就可以,这叫发布命令,要计算机做事,也得要向计算机发命令,计算机能听得懂的命令称之为计算机的指令。让一个引脚输出高电平的指令是SETB,让一个引脚输出低电平的指令是CLR。因此,我们要P1.0输出高电平,只要写SETB P1.0,要P1.0输出低电平,只要写 CLR P1.0就可以了。 现在我们已经有办法让计算机去将P1.0输出高或低电平了,但是我们怎样才能计算机执行这条指令呢?总不能也对计算机也说一声了事吧。要解决这个问题,还得有几步要走。第一,计算机看不懂SETB CLR之类的指令,我们得把指令翻译成计算机能懂的方式,再让计算机去读。计算机能懂什么呢?它只懂一样东西——数字。因此我们得把SETB P1.0变为(D2H,90H ),把CLR P1.0变为 (C2H,90H ),至于为什么是这两个数字,这也是由51芯片的设计者--INTEL规定的,我们不去研究。第二步,在得到这两个数字后,怎样让这两个数字进入单片机的内部呢?这要借助于一个硬件工具"编程器"。当然, 如果您使用我们的倚天版开发套件或者xp开发套件, 那么编程器和试验板都有了,只需要编程序就可以了。 这里是我们迈出单片机编程的第一步,别看很简单可是却对于您有重要的意义,没错,您在编程序了:( 打开我们前面介绍的uvw51e中文版;参照它的使用方法;写入程序, 我们把它的名字设为:001led.最后把生成的001led.hex烧入我们的倚天版套件配的s51里面 然后把芯片换到试验卡座里,这时候我们可以看到p1.0这个灯亮了。 这时可能有的朋友会问;这么简单的问题, 为啥要用单片机搞得这么复杂?接一个电池, 灯不就亮了? 没错,但是这是在编程序,如果我们不要p1.0亮。 而是要p2.0亮,那么写入clr p2.0就可以啦,不需要你动烙铁来改线。这样我们看到,硬件电路的连线没有做任何改变,只要改变写入单片机中的内容,就可以改变电路的输出效果。 由此可见,用硬件实现起来非常困难的问题,用单片机解决起来就很ez. 因此, 每一个硬件工程师掌握单片机技术是必由之路。 三、单片机内部结构分析 我们来思考一个问题,当我们在编程器中把一条指令写进单片要内部,然后取下单片机,单片机就可以执行这条指令,那么这条指令一定保存在单片机的某个地方,并且这个地方在单片机掉电后依然可以保持这条指令不会丢失,这是个什么地方呢?这个地方就是单片机内部的只读存储器即ROM(READ ONLY MEMORY)。为什么称它为只读存储器呢?刚才我们不是明明把两个数字写进去了吗?原来在C51中的ROM是一种电可擦除的ROM,称为FLASH ROM,刚才我们是用的编程器,在特殊的条件下由外部设备对ROM进行写的操作,在单片机正常工作条件下,只能从那面读,不能把数据写进去,所以我们还是把它称为ROM 第五个试验:跟我学作单片机运算加减乘除法----51单片机汇编语言试验教程 收藏 看到这个题目,呵呵, 可能好多人要打石头哥的板子;7+5等于几啊?这还用你教? 但是单片机里,数字是用 二进制来表示的:这个就有一点拗口啦/ 虽然我们的教材到这里你可能还没有学会一个指令。 但是我的意思是首先作几个试验,提高大家对单片机的兴趣。 具体的指令太多了, 不过还好,一般我们只需要记住常用的10-20条就够了。 OK,现在开始动手。 我们写入以下两条指令 MOV P1,#23H END 这个程序大家想必看得懂, 就是把23H这个16进制数送往P1口(即P1.0--P1.7) 汇编得到HEX烧写后 然后把芯片插入实验卡座; 可以看到P1.0-1.7的状态为; P1.0 灭 P1.1 灭 P1.2 亮 P1.3 亮 P1.4 亮 P1.5 灭 P1.6 亮 P1.7 亮 为什么会这样呢? 注意,因为我们的P1口的8个灯,都是一端接正5V,一端接端口的, 那么呢端口为低电平0。发光管亮。高电平不亮。 从高往低排列(从1.7---1.0) 那么就是00100011。这个数字就是23H啦。什么? 你不信? 好了,请您接着看!00100011二进制呢就是100011, 按照数学的原则前面的0不算数。 跟我打开电脑的程序/附件/计算器 ,然后把计算器设置为科学型。然后点击二进制, 输入100011 然后点击一下十六进制可以看到数字变成了23。这就是我们输入的23H了,练习:25H+36H? 程序如下: MOV R0,#25H;将立即数25送寄存器R0 MOV A,#36H;将立即数36送累加器A ADD A,R0;将R0与A的内容相加,结果在A NOP;空操作 POV P1,A;将累加器A的值送P1口。 END;结束 将程序编译以后烧入片子运行;可以看到灯的状态为 P1.0 灭 P1.1 灭 P1.2 亮 P1.3 灭 P1.4 灭 P1.5 亮 P1.6 灭 P1.7 亮 就是二进制数01011011。我们还是用上面的计算器来看看结果对不对:先将计算器设置为16进制,输入 25+36= 结果为5E 然后呢再点击二进制结果为1011110,可见结果完全正确〉 大家接着可以自行练习 减法指令SUBB 乘法指令 MUL 除法指令 DIV 的用法, 相信经过这一节的学习, 大家对这几个指令的印象会非常深刻了。同时让我们对于计算机的数字有了一个 深刻的认识。
