;ST套件从0到99的键控计数器,定时器0中断实例源程序
;本例说明定时器0中断程序的编写,熟悉另一种
;动态显示二位数码管的方法,中断法,我们以3MS中断一次从而交换两位数码管轮流点亮。
;轮流让需显示的多个数码管分别各显示一段时间,有的朋友可能会问:这样不是可以看到
;程序中使用一个寄存器(DIGIT)作计数器,程序复位时计数器值为1,每按一下SW2计数器
;值加1,直到99;每按一下SW3计数器值减1,直到0,同时将计数结果输出数码管显示。
;因为数码管只能显示0-9的十进制输出,所以计数器DIGIT需转换成十进制再输出,程序中将
;涉及到将十六进制转成十进制BCD码的方法。二进制调整为BCD码的方法是将二进制码左移8次
;每次移位后都检查低四位LSD+3是否大于7,如果是则再加3,否则不加。接着再将高四位MSD作相同处理
;烧写时应注意:配置位已经在程序中写明,加载HEX文件时会自动加载,烧写时不用再手动设置配置位。
;实验时请注意套件跳线选择
;****************************************************************
LIST P=16F84A,R=DEC ;定义器件为16F84,默认数制为十进制
;-----------------------------------------------
__CONFIG B'11111111110001';_CP_OFF&_WDT_OFF&_PWRITE_ON&_XT_OSC
;没有代码保护
;看门狗关闭
;上电廷时器开启
;振荡器模式为XT
;---------------------
RTCC EQU 01H
PC EQU 02H ;变量单元定义
STATUS EQU 03H
PORTA EQU 05H
PORTB EQU 06H
INTCON EQU 0BH
OPTION_REG EQU 1H
TRISA EQU 5H
TRISB EQU 6H
;-----------------------STATUS
C EQU 0
Z EQU 2
RP0 EQU 5 ;寄存器体选
;-------------------------INTCON
T0IF EQU 2 ;定时器0溢出中断标志位
T0IE EQU 5 ;定时器0溢出中断允许/禁止
GIE EQU 7 ;总中断允许/禁止
;-------------------------
COUNTER EQU 10H
COUNT1 EQU 11H
COUNT2 EQU 12H
TABADD EQU 13H
FLAGS EQU 14H ;显示位选标志位
DISPBUF_H EQU 15H ;显示器高位
DISPBUF_L EQU 16H ;显示器低位
BUFFER EQU 17H
BUFFER1 EQU 18H
SUM EQU 19H
DIGIT EQU 1AH ;0-99计数器
W_TEMP EQU 1BH ;W现场保护寄存器
STATUS_TEMP EQU 1CH ;STATUS现场保护寄存器
;--------------------
ORG 0000H
GOTO MAIN
ORG 004H
TMR0SERV
MOVWF W_TEMP ;现场保护
SWAPF STATUS,W ;用SWAPF才不会影响标志位
MOVWF STATUS_TEMP ;将W和STATUS存入各保护寄存器
MOVLW 0FFH
MOVWF PORTB ;先熄灭数码管以免闪烁
BSF PORTA,1
BSF PORTA,2
MOVLW TABLE
MOVWF TABADD ;将转换表的首地址存入TABADD
MOVFW DISPBUF_L ;计数值(W)与转换表的起始地址相加
BTFSS FLAGS,1
MOVFW DISPBUF_H
ADDWF TABADD,W
CALL CONVERT ;存入W后调用转换表子程序
MOVWF PORTB ;送RB口显示
BTFSS FLAGS,1 ;根据标志位选择是点亮那一个数码管
BCF PORTA,1
BTFSC FLAGS,1
BCF PORTA,2
COMF FLAGS,1
MOVLW 155 ;送定时器初值
MOVWF RTCC
BCF INTCON,T0IF ;清定时器0溢出中断标志位
SWAPF STATUS_TEMP,W ;恢复中断前STATUS,W的值
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W ;(用SWAPF才不会影响STATUS的值)
RETFIE
;------------------------------------------------
MAIN
CLRF PORTA
CLRF PORTB ;初始化IO口
BSF STATUS,RP0 ;设置寄存器体1
MOVLW 00011000B ;将SW2,SW3设置为输入,其它所有IO口设置为输出
MOVWF TRISA
MOVLW 00000000B
MOVWF TRISB
MOVLW 10000100B
MOVWF OPTION_REG ;预分频器分配给定时器0,分频比1:32
BCF STATUS,RP0 ;恢复寄存器体0
MOVLW 155
MOVWF RTCC ;定时器送初值(255-155)*32US=3.2MS,每3.2MS一次中断
MOVLW 0FFH ;先让数码管全部不显示
MOVWF PORTB
CLRF DIGIT ;显示计数器清0
CLRF DISPBUF_L ;数码管先显示00
CLRF DISPBUF_H
BCF INTCON,T0IF
BSF INTCON,T0IE ;定时器0溢出中断允许
BSF INTCON,GIE ;总中断允许
;--------------------------------------------------
LOOP
BTFSS PORTA,3 ;扫描键S2是否有按