十年专注单片机方案开发的方案公司英锐恩,分享和初学者一起学习。英锐恩现提供服务产品涉及主控芯片:8位单片机、16位单片机、32位单片机及各类运算放大器等。
以下程序:
;************************
;60秒记数,RB0控制时间模式切换;RB1控制秒高/低位切换;
;RB2控制加1功能;RB4控制停止/启动;TMR2产生秒信号;TMR0
;控制数码管扫描
;************************
list p=16f877a
#include
;************************
__CONFIG _CP_OFF&_WDT_OFF&_PWRTE_ON&_XT_OSC&_WRT_OFF&_LVP_OFF&_CPD_OFF
;************************
cblock 0x30
second_l ;秒低位
second_h ;秒高位
_t2count ;T2记数
time_mode ;时间模式
flag ;停止标志
porta ;移位标志
porta_w ;位选通标志
fsr
_ptr ;指针
_count ;闪烁次数记数
_flag0 ;两次闪烁间隔标志
endc
cblock 0x70
w_temp
status_temp
fsr_temp
pclath_temp ;中断临时寄存器
endc
#define key0 PORTB,0
#define key1 PORTB,1
#define key2 PORTB,2
#define key4 PORTB,4 ;定义按键
#define _cycletime .249 ;循环时间
;*************************
org 0x000
nop
goto main
;************************
org 0x004
movwf w_temp
movf STATUS,w
clrf STATUS
movwf status_temp
movf PCLATH,w
movwf pclath_temp
movf FSR,w
movwf fsr_temp ;现场保护
;*************************
banksel INTCON ;中断判断
btfss INTCON,PEIE
goto _chkt0int
banksel PIE1
btfss PIE1,TMR2IE
goto _chkt0int
banksel PIR1
btfss PIR1,TMR2IF
goto _chkt0int
;****************************
;确定T2中断
;****************************
banksel PORTA
pagesel $
clrf PIR1 ;清标志
btfss time_mode,0 ;模式判断,是否普通显示模式
goto _flickerdis ;否,转闪烁显示模式
;****************************
decf _t2count,f
movf _t2count,w
skpz
goto _generaldis ;没到1秒,转普通显示
movlw .25
movwf _t2count
call _addsec ;1秒处理
goto _generaldis ;1秒处理后转普通显示
;******************
_chkt0int ;t0中断判断
banksel INTCON
btfss INTCON,T0IE
goto endofint
btfss INTCON,T0IF
goto endofint ;不是则直接中断退出
;****************************
bcf INTCON,T0IF;确定为T0中断,先清标志
btfss time_mode,0 ;判断显示模式
goto _flickerdis ; 转闪烁显示
goto _generaldis ;转普通显示
;****************************
_generaldis
clrf STATUS ;转体0,普通显示,C=0,IRP=0
comf porta_w,w
movwf PORTA ;低位选通
movlw second_l&0xff ;取秒低位首地址
movwf FSR
movf _ptr,w
addwf FSR,f ;确定时间单元地址
movf INDF,w
movwf fsr
call _tablepro;查表处理
movwf PORTC ;数码显示
btfsc porta_w,1 ;判断2位是否移位完毕
goto bb
clrc
rlf porta_w,f ;没有,准备点亮下一位
cc incf _ptr,f ;指针指向下1时间单元
movlw 0x01
andwf _ptr,f ;保证指针在2个时间单元移动
goto endofint
bb movlw 0x01 ;两位移位完毕,重新赋值开始新一轮显示
movwf porta_w
goto cc
;*******************************
_flickerdis
movlw .25 ;闪烁显示,重新赋值时间记数器
movwf _t2count
clrf STATUS ;转体0,C=0,IRP=0
btfss _flag0,0 ;两次闪烁的间隔次数控制标志,1=调整位亮,0=调整位灭
goto mm ;0则调整位灭
comf porta_w,w
movwf PORTA
movlw second_l&0xff ;取秒低位首地址
movwf FSR
movf _ptr,w
addwf FSR,f
movf INDF,w
movwf fsr
call _tablepro
movwf PORTC
btfsc porta_w,1
goto bb1
clrc
rlf porta_w,f ;准备点亮下一位
cc1 incf _ptr,f
movlw 0x01
andwf _ptr,f
decf _count,f ;闪烁次数
movf _count,w
skpnz
goto _judge_porta
goto endofint
bb1 movlw 0x01
movwf porta_w
goto cc1
;***********************************
_judge_porta
clrf _flag0 ;标志位清0
movlw .100
movwf _count
mm btfss porta,0 ;判断正在调整哪一位
goto sec_lpro ;秒低位调整
goto sec_hpro ;秒高位调整
sec_lpro
movlw b'11111101' ;低位调整,高位一直选通
movwf PORTA
movf second_h,w
LL movwf fsr
call _tablepro
movwf PORTC
decf _count,f
movf _count,w
skpz
goto endofint
movlw 0x01
xorwf _flag0,f ;标志取反
movlw .60
movwf _count
goto endofint
sec_hpro
movlw b'11111110';高位调整
movwf PORTA
movf second_l,w
goto LL
;******************
endofint ;中断退出
clrf STATUS
MOVF fsr_temp,w ;现场恢复
MOVWF FSR
movf pclath_temp,w
movwf PCLATH
movf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie
;************************
main
banksel TRISA
movlw 0x07
movwf ADCON1 ;转体1,设置A口全数字通道,输出,数码管位控
clrf TRISA
movlw b'00010111'
movwf TRISB
clrf TRISC ;数码管段码输出
movlw 0x02
movwf OPTION_REG ;TMRO分品比1:8,内部时钟,2MS中断一次,B口内部上拉
clrf STATUS ;转体0
clrf INTCON ;清标志
bsf INTCON,T0IE
bsf INTCON,PEIE ;T0&PEIE使能
banksel TRISA
movlw _cycletime
movwf PR2 ;设置T2循环周期
clrf PIE1
bsf PIE1,TMR2IE ;使能T2
banksel PORTA
clrf PORTB
RETLW 99H ;4
RETLW 92H ;5
RETLW 82H ;6
RETLW 0F8H ;7
RETLW 80H ;8
RETLW 98H ;9
;***************************************
end
(文源网络,侵删)