《PIC16F877A数字时钟时钟程序(17页).doc》由会员分享,可在线阅读,更多相关《PIC16F877A数字时钟时钟程序(17页).doc(17页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、-PIC16F877A数字时钟时钟程序-第 17 页;Digit clock;DATE :20101205;Author:Tang HS;M C U :PIC16F877A;Date: 2010/12/07.14:35-Ver01-CS-ICD:0xAFCE-ISP:0xb7ce-;功能: 1.LED显示:时分秒 ;格式: hh mm ss 备注:按键未定义;Date: 2010/12/07.22:15-Ver01-CS-ICD:0xAFCE-ISP:0xb7ce-;功能: 1.LED显示:时分秒 ;格式: hh mm ss 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KE
2、Y;RB2-SUB_KEY;RB3-EXIT_KEY;Date: 2010/12/09.18:06-Ver02-CS-ICD:0xAFCE-ISP:0xef0e-;Date: 2010/12/10.00:47-Ver03-CS-ICD:0xb08d-ISP:0xfaa7-;功能: 1.LED显示:时分秒 ;格式: hh mm ss 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY 都OK; 3.MOVLW 纠正 MOVV REG,1 引起的 SUB_不良;Date: 2010/12/10.13:10-Ver03.1-CS-
3、ICD:0xb08b-ISP:0xfaa4-; 4.时差。 50ms原来计数20次改为19次;250us原来计数200次改为197次;Date: 2010/12/10.17:30-Ver03.2-CS-ICD:0x296B-ISP:0x7387-; 5.在Set_ini中-增加 CALL SET_Flag;指定Flag,1=1;标志位- -解决Ver03.1-第一次按SET键时不能调HourL&HourH的问题 ;程序清单 _CONFIG 3F39H;设置配置位中振荡方式为XT,其它全部禁止或关闭 include P16F877A.INC ;-ram varable-HourH equ 20H
4、 ;HourL equ 21H ;MinH equ 22H ;MinL equ 23H ;SecH equ 24h ;SecL equ 25h ; B0010 0101;N250us equ 26h ;250us*200=50ms;N50ms equ 27h ;50ms*20=1000ms;Nsec equ 28h ;data1 equ 29h ;定义一个廷时变量寄存器data2 equ 2Ah ;定义另一个廷时变量寄存器keyvalue EQU 2Bh ;FlagKey EQU 2Ch ; W_STK equ 2Dh ;-STATUS_STK equ 2Eh ;PCLATH_STK equ
5、2Fh ;FSR_STK equ 30h ;-COUNT0 equ 31h ; DELAY use 0011 0000COUNT1 equ 32h ;COUNT2 equ 33h ;N250us equ 35h ;250us*200=50msN50ms equ 36h ;50ms*20=1000msNsec equ 37h ;-Counstant-n1 equ d1;d13 ;定义一个外层循环廷时常数d13(10ms)n2 equ 0ffh ;定义一个内层廷时常数RBCOUNST equ 0x1f ;rb0rb4读取后异或常数;-bit1-c equ 0 ;定义进位标志位位地址rp0 equ
6、5 ;定义状态寄存器的页选位RP0NOT_RBPU equ 7 ;定义选择寄存器RB的上拉电阻位RBPUz equ 2 ;定义0状态位的位地址F_release EQU 0 ;F_pressed equ 1 ;-FlagKey-bit2-;#define F_release FlagKey,0 ;按键释放标志位;#define F_pressed FlagKey,1 ;按键闭合标志位;-Flag -;Flag,0 ; 时间调整标志位;Flag,1 ; FSR=21H=HourL;Flag,2 ; FSR=23H=MinL;Flag,3 ; FSR=25H=SecL ORG 0000H NOP
7、;放置一条ICD必需的空操作指令 GOTO MAIN ORG 0004H GOTO ISR_TMR0 ; ORG 0008H ;NAME : CONMERT1 数码管位码 查表子程序CONVERT1 ;取数码管位码 ADDWF PCL,1 ;地址偏移量加当前PC值TABLE1 RETLW 0FDH ;第一位数码管 RETLW 0FEH ;第二位数码管 RETLW 0F7H ;第三位数码管 RETLW 0FBH ;第四位数码管 RETLW 0DFH ;第五位数码管 RETLW 0EFH ;第六位数码管;NAME : CONVERT 数码管段码 查表子程序CONVERT ;取数码管段码 ADDWF
8、 PCL,1 ;地址偏移量加当前PC值TABLE RETLW 0C0H ;0 RETLW 0F9H ;1 RETLW 0A4H ;2 RETLW 0B0H ;3 RETLW 99H ;4 RETLW 92H ;5 RETLW 82H ;6 RETLW 0F8H ;7 RETLW 80H ;8 RETLW 98H ;9 RETLW 7FH ;. retlw 00h ;11; /-Main program -/ ; return ;MAIN CALL Sys_ini; CALL Clear_RAM; BSF INTCON,GIE ; 打开全局中断,启动定时器 CALL RAM_ini ;LOOP_
9、DIS CALL Display_led; NOP; bcf STATUS,RP0; BTFSC PORTB,0 ; RB0=0? 键按下否? GOTO LOOP_DIS ; no CALL Display_led ; Yes CALL Display_led; BTFSC PORTB,0 ; RB0=0? 再次确认键按下否? GOTO LOOP_DIS ; no CALL Set_in; CALL keyscan;LoopEND GOTO LOOP_DIS;Set_in BSF Flag,0 ; Set1闪烁显示处理放在中断进行 MOVLW 0x21 ; HourL-FSR MOVWF FS
10、R ; ;CALL SET_Flag; BSF Flag,1; 1 BCF Flag,2; 0 BCF Flag,3; 0 keyscanRealase0 ; 按键释放,子程序名 CALL Display_led ; movf PORTB,W ;读取RB口数据到W(d=0) andlw 0x1f ;屏蔽高4位 bcf STATUS,Z ; xorlw 0x1f ; btfss STATUS,Z ; goto keyscanRealase0 ;Z=0有键按下 ;call delay ;Z=1无键按下 CALL Display_led; CALL Display_led; movf PORTB,W
11、 ;读取RB口数据到W(d=0) andlw 0x1f ;屏蔽高4位 bcf STATUS,Z ; xorlw 0x1f ; btfss STATUS,Z ; goto keyscanRealase0 ;Z=0有键按下,waitting for release ;Z=1无键按下exit RETURN ;KEY0_SUB ;SET_KEY INCF FSR,1 ;21-23-25h INCF FSR,1 ; MOVF FSR,W ; SUBLW 0x27 ;-27- BTFSS STATUS,Z ; FSR=27H? GOTO $+3 ; MOVLW 0x21; MOVWF FSR; CALL
12、SET_Flag; RETURN;KEY1_SUB ;ADD_KEY INCF INDF,1; CALL ArrangTime ; RETURN;KEY2_SUB ;SUB_KEY ;MOVF INDF,1; ;BTFSS STATUS,Z ; INDF=0? ;GOTO $+4 ;NO:Jump to DECF INDF,1; ;MOVLW .9 ;=Yes:Re-setup REGF ;MOVF INDF,1 ;=Yes: 9-REGF ;GOTO $+2 ;=Yes:and jump to CALL Time_sub; ;DECF INDF,1; CALL Time_sub; RETUR
13、N;KEY3_SUB ;EXIT_KEY ;CALL Set_out BCF Flag,0 ; Clear 0 MOVLW 0x00 ; HourL-FSR MOVWF FSR ; RETURN ;keyscan ;-1-按键闭合- BTFSS Flag,0 ; 1 继续按键处理 goto keyscan_end ; 0 退出按键处理 CALL ArrangTime ; CALL Display_led ; MOVF PORTB,W ;读取RB口数据到W(d=0) ANDLW 0x1f ;屏蔽高4位 RBCOUNST A1=A BCF STATUS,Z ;将z清0 XORLW 0x1f ;即R
14、A与0x0f作异或运算,若两数相同,结果为0,Z置1 ;若两数相异,结果非0,Z=0 BTFSC STATUS,Z ;0jump keyclose GOTO keyscan ; Z=1无键按下退出按键扫描 ;call delay ; Z=0有键按下,延时按键去抖动 CALL Display_led ; CALL Display_led ; ;-2- MOVF PORTB,W ;读取RB口数据到W(d=0) ANDLW 0x1f ;屏蔽高4位 MOVWF keyvalue ;保存键值到keyvalue BCF STATUS,Z ;将z清0 XORLW 0x1f ;即RA与0x0f作异或运算,若两
15、数相同,结果为0,Z置1;若两数相异,Z=0不相同 BTFSC STATUS,Z ;0jump keyclose GOTO keyscan ; Z为1退出按键扫描 ;incf portc,1 ;key fuction sub.KEY0 BTFSC keyvalue,0 ; KEY0? GOTO KEY1; CALL KEY0_SUB; goto Adjust_Time;KEY1 BTFSC keyvalue,1 ; KEY1? GOTO KEY2; CALL KEY1_SUB; goto Adjust_Time;KEY2 BTFSC keyvalue,2 ; KEY2? GOTO KEY3;
16、CALL KEY2_SUB; goto Adjust_Time;KEY3 BTFSC keyvalue,3 ; KEY3? GOTO Adjust_Time ;KEY1; CALL KEY3_SUB;ADJ_OUTAdjust_Time ;CALL ArrangTime ;keyscanRealase ; 按键释放,子程序名 CALL Display_led ; movf PORTB,W ;读取RB口数据到W(d=0) andlw 0x1f ;屏蔽高4位 bcf STATUS,Z ; xorlw 0x1f ; btfss STATUS,Z ; goto keyscanRealase ;Z=0有
17、键按下 ;call delay ;Z=1无键按下 CALL Display_led; CALL Display_led; movf PORTB,W ;读取RB口数据到W(d=0) andlw 0x1f ;屏蔽高4位 bcf STATUS,Z ; xorlw 0x1f ; btfss STATUS,Z ; goto keyscanRealase ;Z=0有键按下 goto keyscan ;Z=1无键按下 keyscan_end RETURN;-keyscan_end-;*Adjust_TIME END*;=SET_Flag SUB =SET_Flag BCF STATUS,RP0; selec
18、t bank0; MOVF FSR,W; SUBLW 0x21; BTFSS STATUS,Z; FSR=21H? GOTO SET_F2 ; ;CALL ArrangHour;- BSF Flag,1; 1 BCF Flag,2; 0 BCF Flag,3; 0 SET_F2 MOVF FSR,W; SUBLW 0x23; BTFSS STATUS,Z; FSR=23H? GOTO SET_F3; ;CALL ArrangMin;- BCF Flag,1; 0 BSF Flag,2; 1 BCF Flag,3; 0 SET_F3 MOVF FSR,W; SUBLW 0x25; BTFSS S
19、TATUS,Z; FSR=25H? GOTO SET_END ; ;CALL ArrangSec;- BCF Flag,1; 0 BCF Flag,2; 0 BSF Flag,3; 1 SET_END RETURN ;=SET_Flag END=; NAME : Time_sub (Key2_SUB) Time_sub BTFSS Flag,1 ; FSR=21h=HourL GOTO $+2; CALL Hour_sub; BTFSS Flag,2 ; FSR=23h=HourL GOTO $+2; CALL Min_sub; BTFSS Flag,3 ; FSR=25h=HourL GOT
20、O $+2; CALL Sec_sub; RETURN ;=Hour_sub=Hour_sub MOVF HourL,F ; F-F BTFSS STATUS,Z ; HourL=0? GOTO HourL_NotZero ;No INDF- MOVF HourH,F ; BTFSS STATUS,Z ;HourH=0? GOTO HourH_NotZero ; Not Zero MOVLW .2 ; MOVWF HourH ;2-hourH MOVLW .3 ; MOVWF HourL ;3-HourL GOTO Hour_sub_end ;HourH_NotZero ; DECF Hour
21、H,F ; HourH- MOVLW .9 MOVWF HourL ;9-HourL GOTO Hour_sub_end;HourL_NotZero; DECF HourL,F;Hour_sub_end RETURN;=Hour_sub END=Min_sub MOVF MinH,F ; BTFSS STATUS,Z ; MinH=0? GOTO MinH_NotZero ; NO MOVF MinL,F ; F-F BTFSS STATUS,Z ; MinL=0? GOTO MinL_NotZero ; NoHour00 ;(1)-00- MOVLW .5 ; MOVWF MinH ; 5-
22、MinH MOVLW .9 ; MOVWF MinL ; 9-MinL GOTO Min_sub_end ;MinH_NotZero; MOVF MinL,F ; F-F BTFSS STATUS,Z ; MinL=0? GOTO MinL_NotZero ; No ;-(2)-x0- DECF MinH,F ; MinH- MOVLW .9 MOVWF MinL ; 9-MinL GOTO Min_sub_end ;MinL_NotZero;(3)0x & xx DECF MinL,F;Min_sub_end RETURN ;=Min_sub END=Sec_sub MOVF SecH,f
23、; BTFSS STATUS,Z ; SecH=0? GOTO SecH_NotZero ; NO MOVF SecL,F ; F-F BTFSS STATUS,Z ; SecL=0? GOTO SecL_NotZero ; NoSec00;(1)-00 MOVLW .5 ; MOVWF SecH ; 5-SecH MOVLW .9 ; MOVWF SecL ; 9-SecL GOTO Sec_sub_end ;SecH_NotZero; MOVF SecL,F ; F-F BTFSS STATUS,Z ; SecL=0? GOTO SecL_NotZero ; No ;(2)-x0 DECF
24、 SecH,F ; SecH- MOVLW .9 ; MOVWF SecL ; 9-SecLSecL_NotZero; DECF SecL,F;Sec_sub_end RETURN ;=Sec_sub END=;NAME : ArrangTimeArrangTime BTFSS Flag,1 ; FSR=21h=HourL GOTO $+2; CALL ArrangHour; BTFSS Flag,2 ; FSR=23h=HourL GOTO $+2; CALL ArrangMin; BTFSS Flag,3 ; FSR=25h=HourL GOTO $+2; CALL ArrangSec;
25、RETURN ;ArrangMin ;if FSR= SecL goto hear- MOVF MinL,W ; SUBLW .10 ; BTFSS STATUS,Z ;到10M? GOTO END_Min ; ;CALL CLR_MinL_D2a; CLRF MinL; INCF MinH,F; MOVF MinH,W ; SUBLW .6 ; BTFSS STATUS,Z ;到60M? GOTO END_Min ;CALL CLR_MinH_D3a ; CLRF MinH; CLRF MinL;END_Min RETURNArrangSec ;if FSR= SecL goto hear-
26、 MOVF SecL,w ; SUBLW .10 ; BTFSS STATUS,Z ;到10S? GOTO END_Sec ;没到10s ;CALL CLR_SecL_D0a ; CLRF SecL ; INCF SecH,F ; -SecH+ MOVF SecH,W ; SUBLW .6 ; BTFSS STATUS,Z ;到60S? GOTO END_Sec ;没到60S ;CALL CLR_SecH_D1a ; CLRF SecH; CLRF SecL ; ;INCF MinL,F;END_Sec RETURN;if FSR= HourL goto hear - OK -ArrangHo
27、urA ;小时做调整有2种情况:1 h=10 ; 2 h=24 ; MOVF HourH,W ;小时不调整有2种情况:3 h 20H: 20H: h=24H) goto END_HourHourLequ10A MOVF HourL,W ; SUBLW .10 BTFSS STATUS,Z ;HourL=10 GOTO END_Hour ;(3: h: h=10H)END_Hour RETURN ;CLR_HourL_D4a CLRF HourL; else if(HourL=10) hourL=0;Hourh+; INCF HourH,F; RETURN;CLR_HourH_D5a CLRF
28、HourH ; if (HourH=2&HourL=4) hourH=0;HourL=0; CLRF HourL ; ;INCF DayL,F; RETURN;* ArrangTime END *;NAME : Sys_ini 变量初始化清零-子程序Sys_ini ;-I/O- BSF STATUS,RP0 ;设置文件寄存器体1 MOVLW 0x07 ; MOVWF ADCON1 ;RA0 5设为数字I/O CLRF TRISA ;将RA设置为输出-数码管位码 CLRF TRISC ;将RC设置为输出-数码管段码 BCF OPTION_REG,NOT_RBPU ;RB1RB4作(按键)输入必须
29、设上拉电阻(RBPU=0) MOVLW 0XFF; MOVWF TRISB ;将RB设置为输入按键输入RB0RB3 BCF STATUS,RP0 ;恢复到文件寄存器体0 CLRF PORTC ;送计器初值00H到RC口显示 MOVLW 03fh ;bxx11 1111 MOVWF PORTA ;关闭数码管(位码)显示 ;-TMR0- BANKSEL OPTION_REG BCF OPTION_REG,T0CS ;TMR0工作于定时器方式 BSF OPTION_REG,PSA;TMR0不用分频 BANKSEL INTCON BCF INTCON,T0IF ;清除TMR0的中断标志 BCF INT
30、CON,GIE ;总中断禁止 BSF INTCON,T0IE ;TMR0中断允许 BCF STATUS,RP0 ;恢复到文件寄存器体0- MOVLW 0x07 ;256-6=250us MOVWF TMR0 ;TMR0设初值 RETURN ;NAME : Clear_RAM 变量初始化清零-子程序;Clear RAM (202f)40h routine-;20(B0010 0000);Bank select-IRP AND FSR,7-;2F(B0011 0000)Clear_RAM MOVLW 0x20 ; Starting Address is 0x20 MOVWF FSR ; Use indirect addressingNEXT CLRF INDF ; Clear INDF address INCF FSR,F ; Increase FSR for next address BTFSS FSR,6 ; Register clear complete? GOTO NEXT ; RETURN ; CALL Sys_ini ;NAME : RAM_ini 变量初始化设置RAM_ini ; CLRF FlagKey ; CLRF keyvalue ; CLRF Flag ; CLRF N250us; CL