用STC的MCU的IO方式控制74HC595驱动8位数码管。
; 用户可以修改宏来选择时钟频率.
; 显示效果为: 显示秒计数, 5秒后不喂狗, 等复位.
Fosc_KHZ EQU 22118 ;22118KHZ
STACK_POIRTER EQU 0D0H ; 堆栈开始地址
DIS_DOT EQU 020H
DIS_BLACK EQU 010H
DIS_ EQU 011H
AUXR DATA 08EH
P4 DATA 0C0H
P5 DATA 0C8H
P0M1 DATA 0x93 ;
P0M0 DATA 0x94 ;
P1M1 DATA 0x91 ;
P1M0 DATA 0x92 ;
P2M1 DATA 0x95 ;
P2M0 DATA 0x96 ;
P3M1 DATA 0xB1 ;
P3M0 DATA 0xB2 ;
P4M1 DATA 0xB3 ;
P4M0 DATA 0xB4 ;
P5M1 DATA 0xC9 ;
P5M0 DATA 0xCA ;
P6M1 DATA 0xCB ;
P6M0 DATA 0xCC ;
P7M1 DATA 0xE1 ;
P7M0 DATA 0xE2 ;
WDT_CONTR DATA 0xC1
D_WDT_FLAG EQU (1 SHL 7)
D_EN_WDT EQU (1 SHL 5)
D_CLR_WDT EQU (1 SHL 4) ;auto clear
D_IDLE_WDT EQU (1 SHL 3) ;WDT counter when Idle
D_WDT_SCALE_2 EQU 0
D_WDT_SCALE_4 EQU 1
D_WDT_SCALE_8 EQU 2 ;T=393216*N/fo
D_WDT_SCALE_16 EQU 3
D_WDT_SCALE_32 EQU 4
D_WDT_SCALE_64 EQU 5
D_WDT_SCALE_128 EQU 6
D_WDT_SCALE_256 EQU 7
P_HC595_SER BIT P4.0 ; //pin 14 SER data input
P_HC595_RCLK BIT P5.4 ; //pin 12 RCLk store (latch) clock
P_HC595_SRCLK BIT P4.3 ; //pin 11 SRCLK Shift data clock
LED8 DATA 30H ; 显示缓冲 30H ~ 37H
display_index DATA 38H ; 显示位索引
ms_cnt_H DATA 39H ; 1000ms 计数值
ms_cnt_L DATA 3AH ;
tes_cnt DATA 3BH ; 测试用的计数变量
ORG 0000H ;reset
LJMP F_Main
ORG 0100H ;reset
F_Main:
CLR A
MOV P0M1, A ;设置为准双向口
MOV P0M0, A
MOV P1M1, A ;设置为准双向口
MOV P1M0, A
MOV P2M1, A ;设置为准双向口
MOV P2M0, A
MOV P3M1, A ;设置为准双向口
MOV P3M0, A
MOV P4M1, A ;设置为准双向口
MOV P4M0, A
MOV P5M1, A ;设置为准双向口
MOV P5M0, A
MOV P6M1, A ;设置为准双向口
MOV P6M0, A
MOV P7M1, A ;设置为准双向口
MOV P7M0, A
MOV SP, #STACK_POIRTER
MOV PSW, #0
USING 0 ;选择第0组R0~R7
MOV display_index, #0
MOV R0, #LED8
MOV R2, #8
L_ClearLoop:
MOV @R0, #DIS_BLACK ;上电消隐
INC R0
DJNZ R2, L_ClearLoop
MOV ms_cnt_H, #HIGH 1000 ; 重装1000ms计数值
MOV ms_cnt_L, #LOW 1000
MOV tes_cnt, #0
MOV LED8+7, tes_cnt
L_MainLoop:
MOV A, #1 ;延时1ms
LCALL F_delay_ms
LCALL F_DisplayScan
MOV A, tes_cnt
CLR C
SUBB A, #6 ; if(tes_cnt <= 5) //5秒后不喂狗, 将复位,
JNC L_QuitWatchDog
MOV WDT_CONTR, #(D_EN_WDT + D_CLR_WDT + D_WDT_SCALE_16) ; 喂狗
L_QuitWatchDog:
MOV A, ms_cnt_L ; if(--ms_cnt == 0)
CLR C
SUBB A, #1
MOV ms_cnt_L, A
MOV A, ms_cnt_H
SUBB A, #0
MOV ms_cnt_H, A
ORL A, ms_cnt_L
JNZ L_cnt1000_NotZero
MOV ms_cnt_H, #HIGH 1000 ; 重装1000ms计数值
MOV ms_cnt_L, #LOW 1000
INC tes_cnt ; 测试计数+1
MOV LED8+7, tes_cnt ;
L_cnt1000_NotZero:
LJMP L_MainLoop
F_delay_ms:
PUSH 02H ;入栈R2
PUSH 03H ;入栈R3
PUSH 04H ;入栈R4
MOV R2,A
L_delay_ms_1:
MOV R3, #HIGH (Fosc_KHZ / 13)
MOV R4, #LOW (Fosc_KHZ / 13)
L_delay_ms_2:
MOV A, R4 ;1T Total 13T/loop
DEC R4 ;2T
JNZ L_delay_ms_3 ;4T
DEC R3
L_delay_ms_3:
DEC A ;1T
ORL A, R3 ;1T
JNZ L_delay_ms_2 ;4T
DJNZ R2, L_delay_ms_1
POP 04H ;出栈R2
POP 03H ;出栈R3
POP 02H ;出栈R4
RET
T_Display: ;标准字库
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
DB 03FH,006H,05BH,04FH,066H,06DH,07DH,007H,07FH,06FH,077H,07CH,039H,05EH,079H,071H
; black - H J K L N o P U t G Q r M y
DB 000H,040H,076H,01EH,070H,038H,037H,05CH,073H,03EH,078H,03dH,067H,050H,037H,06EH
; 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
DB 0BFH,086H,0DBH,0CFH,0E6H,0EDH,0FDH,087H,0FFH,0EFH,046H
T_COM:
DB 001H,002H,004H,008H,010H,020H,040H,080H ; 位码
F_Send_595:
PUSH 02H ;R2入栈
MOV R2, #8
L_Send_595_Loop:
RLC A
MOV P_HC595_SER,C
SETB P_HC595_SRCLK
CLR P_HC595_SRCLK
DJNZ R2, L_Send_595_Loop
POP 02H ;R2出栈
RET
F_DisplayScan:
PUSH DPH ;DPH入栈
PUSH DPL ;DPL入栈
PUSH 00H ;R0 入栈
MOV DPTR, #T_COM
MOV A, display_index
MOVC A, @A+DPTR
CPL A
LCALL F_Send_595 ;输出位码
MOV DPTR, #T_Display
MOV A, display_index
ADD A, #LED8
MOV R0, A
MOV A, @R0
MOVC A, @A+DPTR
LCALL F_Send_595 ;输出段码
SETB P_HC595_RCLK
CLR P_HC595_RCLK ; 锁存输出数据
INC display_index
MOV A, display_index
ANL A, #0F8H ; if(display_index >= 8)
JZ L_QuitDisplayScan
MOV display_index, #0; ;8位结束回0
L_QuitDisplayScan:
POP 00H ;R0 出栈
POP DPL ;DPL出栈
POP DPH ;DPH出栈
RET
END
相关文章