;Таймер с четырмя состояниями с использованием прерываний.
LIST P=16F628A
INCLUDE P16F628A.INC
__CONFIG _INTOSC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_ON&_MCLRE_OFF&_LVP_OFF
ERRORLEVEL -302
CBLOCK 20H
W_TEMP:1,STATUS_TEMP:1,FSR_TEMP:1
J:1,K:1
LED3:1,LED2:1,LED1:1,LED0:1
TEMPL:1,TEMPH:1
COUNT:1,MEM:1,CATOD:1,INDEX:1
TEMP:2,TEMP_T1CON:1
ENDC
BANK0 MACRO
BCF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK1 MACRO
BSF STATUS,RP0
BCF STATUS,RP1
ENDM
ORG 0
GOTO START
ORG 4
GOTO ISR
START MOVLW 7
MOVWF CMCON
CLRF PORTB
CLRF PORTA
BANK1
MOVLW B'11110000'
MOVWF TRISA
MOVLW B'00000001'
MOVWF TRISB
BSF PIE1,TMR1IE ;Разрешаем прерывание от таймера1
BANK0
CLRF TEMP+1 ;Сбрасываем счетчик
CLRF TEMP
CLRF TEMP_T1CON
MOVLW B'00000001'
MOVWF T1CON ;Запускаем таймер
BSF INTCON,INTE ;Прерывание на порте Б 0
BSF INTCON,PEIE ;Разрешаем прерывание от переферии
BSF INTCON,GIE ;Разрешаем глобальные прерывания
MAIN MOVLW LED3
MOVWF FSR
MOVLW 1
MOVWF CATOD
LOOP MOVFW INDF
CALL TABLE
MOVWF PORTB
MOVFW CATOD
MOVWF PORTA
CALL DELAY
CLRF PORTA
INCF FSR,F
RLF CATOD,1
BTFSS CATOD,4
GOTO LOOP
GOTO MAIN
DELAY MOVLW .4
MOVWF J
JLOOP MOVLW .255
MOVWF K
KLOOP DECFSZ K,F
GOTO KLOOP
DECFSZ J,F
GOTO JLOOP
RETURN
TABLE ADDWF PCL,F
RETLW B'10000000'
RETLW B'11110010'
RETLW B'01001000'
RETLW B'01100000'
RETLW B'00110010'
RETLW B'00100100'
RETLW B'00000100'
RETLW B'11110000'
RETLW B'00000000'
RETLW B'00100000'
BIN2BCD MOVLW .16
MOVWF COUNT
CLRF LED0
CLRF LED1
CLRF LED2
CLRF LED3
LOOP8 RLF TEMPL,F
RLF TEMPH,F
RLF LED0,F
RLF LED1,F
DECFSZ COUNT,F
GOTO ADJDEC
SWAPF LED1,W
ANDLW 0FH
MOVWF LED3
MOVFW LED1
ANDLW 0FH
MOVWF LED2
SWAPF LED0,W
ANDLW 0FH
MOVWF LED1
MOVFW LED0
ANDLW 0FH
MOVWF LED0
RETURN
ADJDEC MOVLW LED0
MOVWF FSR
CALL ADJBCD
MOVLW LED1
MOVWF FSR
CALL ADJBCD
GOTO LOOP8
ADJBCD MOVLW 3
ADDWF INDF,W
MOVWF MEM
BTFSC MEM,3
MOVWF INDF
MOVLW 30H
ADDWF INDF,W
MOVWF MEM
BTFSC MEM,7
MOVWF INDF
RETLW 0
ISR MOVWF W_TEMP
SWAPF STATUS,W
BCF STATUS,RP0
MOVWF STATUS_TEMP
MOVFW FSR
MOVWF FSR_TEMP
BTFSC PIR1,TMR1IF ;Было переполнение таймера?
GOTO TMR1INT ;Да
BTFSS INTCON,INTF ;Прерывание на порте Б0?
GOTO EXIT_ISR ;Небыло вообще прерываний
BCF INTCON,INTF ;Сбрасываем флаг
MOVLW 0FH
ANDWF T1CON,F ;Чистим прдделитель(старший полубайт)
MOVLW 10H
ADDWF TEMP_T1CON,F;Увеличиваем на 1 старший полубайт
BTFSC TEMP_T1CON,6;Проверяем,на мнужно только 2 бита
GOTO CLEAR ;Почистим,если больше 2-бит
MOVFW TEMP_T1CON ;Закидываем в W
IORWF T1CON,F ;Изменяем только предделитель
GOTO TMR1INT
CLEAR CLRF TEMP_T1CON
TMR1INT BCF PIR1,TMR1IF ;Да было.Обязательно сбросить флаг.
INCF TEMP+1,F ;Увеличим счетчик
BTFSC STATUS,Z ;Если байт переполнился,то 0
INCF TEMP,F
MOVF TEMP+1,W ;Вывод на индикатор
MOVWF TEMPL
MOVF TEMP,W
MOVWF TEMPH
CALL BIN2BCD
EXIT_ISR MOVFW FSR_TEMP
MOVWF FSR
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
END
НАЗАД Cи ATtiny2313 ASSEMBLER ATtiny2313 ДАЛЕЕ