www.pudn.com > st-asm.rar > 84seg4.asm


;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作相同处理 
;PIC单片机学习网-----http://www.pic16.com 
;烧写时应注意:配置位已经在程序中写明,加载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是否有按下 
   GOTO SET_1 
   BTFSS PORTA,4     ;扫描键S3是否有按下 
   GOTO SET_2 
   GOTO LOOP         ;循环扫描 
LOOP1 
   MOVLW 8 
   MOVWF COUNTER    ;循环左移计数器置8 
   CLRF BUFFER     ;清除缓冲器 
   MOVF DIGIT,W  
   MOVWF BUFFER1  
LOOP2  
   RLF BUFFER1,1    ;二进制数转换成BCD码(以便显示) 
   RLF BUFFER,1 
   DECFSZ COUNTER,1 ;左移8次 
   GOTO ADJUST  
   SWAPF BUFFER,W   ;显示值高低位交换,先处理高位 
   ANDLW 0FH        ;屏蔽掉高位 
   MOVWF DISPBUF_H  ;存入寄存器 
   MOVFW BUFFER     ;显示值低位处理 
   ANDLW 0FH        ;屏蔽掉高位 
   MOVWF DISPBUF_L  ;存入寄存器  
   GOTO LOOP 
ADJUST  
   MOVLW 3         ;二进制转BCD的调整 
   ADDWF BUFFER,W  ;每次移位后都检查低四位LSD+3是否大于7 
   MOVWF SUM  
   BTFSC SUM,3 
   MOVWF BUFFER 
   MOVLW 30H 
   ADDWF BUFFER,W ;如果是则再加3,否则不加。 
   MOVWF SUM 
   BTFSC SUM,7 
   MOVWF BUFFER   ;接着再将高四位MSD作相同处理 
   GOTO LOOP2 
;- -------------------------------------------- 
SET_1 
   BTFSC PORTA,3 ;去除键抖动 
   GOTO LOOP 
   CALL DELAY 
   BTFSC PORTA,3 
   GOTO LOOP 
   MOVLW 99      ;计数值为99后不再加1 
   XORWF DIGIT,0 
   BZ LOOP 
   INCF DIGIT,1  ;不为9计数值加1 
   GOTO LOOP1  
;---------------------------------------------------- 
SET_2 
   BTFSC PORTA,4 ;去除键抖动 
   GOTO LOOP 
   CALL DELAY 
   BTFSC PORTA,4 
   GOTO LOOP  
   MOVF DIGIT,1  ;计算值为0后不再减1 
   BZ LOOP 
   DECF DIGIT,1  ;不为0计数值减1 
   GOTO LOOP1  
;------------------------------------------------- 
DELAY             ;廷时常数 
   MOVLW 150 
   MOVWF COUNT1 
L2  
   MOVLW 255 
   MOVWF COUNT2 
L3  
   DECFSZ COUNT2,1 ;递减循环 
   GOTO L3 
   DECFSZ COUNT1,1 
   GOTO L2 
   RETLW 0 
;-------------------- ---------------------------------- 
CONVERT  
   MOVWF PC      ;将W寄存器内的7段显示码地址放入PC  
TABLE            ;PC执行新地址指令, 跳到相对的地址执行?  
   RETLW 081H ;0 ;RETLW指令,将七段显示码存入W后返回 
   RETLW 0E7H ;1  
   RETLW 092H ;2 
   RETLW 0A2H ;3 
   RETLW 0E4H ;4 
   RETLW 0A8H ;5 
   RETLW 088H ;6 
   RETLW 0E3H ;7 
   RETLW 080H ;8 
   RETLW 0A0H ;9 
;----- ----------------------------------------------- 
   END