;============================================= ; DigiScal.asm ; Цифровая шкала с возможностью ; записи промежуточной частоты ; Денисов А.Ю. Тамбов 1999 ;============================================= LIST p=16F84 __CONFIG 03FF1H ;============================================= ; timing loop values ; must be from 1 to 255!!! T1 equ .67 ; rough timing loop T2 equ .221 ; fine timing loop ; values for 4 000 kHz ;============================================= ; IndF equ 00h ; Indirect addr. register Timer0 equ 01h ; TMR0 register OptionR equ 01h ; Option register - RP0=1 PC equ 02h ; Program counter Status equ 03h ; Status register FSR equ 04h ; Pointer register PortA equ 05h ; Port A TrisA equ 05h ; Tris A - RP0=1 PortB equ 06h ; Port B TrisB equ 06h ; Tris B - RP0=1 EEData equ 08h ; EEPROM Data EECon1 equ 08h ; EECON1 - RP0=1 EEAdr equ 09h ; EEPROM Address EECon2 equ 09h ; EECON2 - RP0=1 IntCon equ 0Bh ; ; KeyBuf equ 0Ch ; буфер клавиатуры KeyWait equ 0Dh ; ожидание клавиатуры Count equ 0Eh ; временный счетчик Count1 equ 0Fh ; еще один ; LED0 equ 010h ; LED1 equ 011h ; LED2 equ 012h ; LED3 equ 013h ; ячейки LED4 equ 014h ; индикатора LED5 equ 015h ; LED6 equ 016h ; LED7 equ 017h ; ; Temp equ 018h ; временный регистр LEDIndex equ 019h ; указатель LED TimerL equ 01ah ; младший байт счетчика частоты TimerM equ 01bh ; средний байт счетчика частоты TimerH equ 01ch ; старший байт счетчика частоты IF_L equ 01dh ; младший байт ПЧ IF_M equ 01eh ; средний байт ПЧ IF_H equ 01fh ; старший байт ПЧ ; ;============================================= ; W equ 0 ; destination is accumulator F equ 1 ; register ; ;============================================= ; Flag bits: CF equ 0 ; Carry DC equ 1 ; DC ZF equ 2 ; Zero ; RP0 equ 5 ;============================================= org 2100h ; частота ПЧ по умолчанию DE 008h,064h,070h ; 5.5 мгц ; DE 0h,0h,0h ; резерв DE "Copyright (C) 1999 Alexander Y Denisov" ; ;============================================= ; org 0 goto Start ; ;============================================= ; Проверка клавиатуры ;============================================= ; Inkey clrf PortA ; RA0..RA3 = 0 bsf Status,RP0 movlw b'00010011' movwf TrisA ; RA0,RA1,RA4 input bcf Status,RP0 ; movf PortA,w andlw b'00000011' return ; ;============================================= KeyQuery ; опрос клавиатуры call Inkey addwf PC,f goto Fun ; режим установки ПЧ goto plusIF ; плюс ПЧ goto minusIF ; минус ПЧ goto Go1 ; и все по новой. ; Fun incf KeyWait,f btfss KeyWait,3 goto Go movlw 0 movwf KeyWait Function call Inkey addwf PC,f goto Function ; ждем отжатия клавиш nop nop nop movf TimerL,w movwf IF_L movf TimerM,w movwf IF_M movf TimerH,w movwf IF_H call Bin2LCD goto Edt ; ;============================================= ; FunOff call Inkey addwf PC,f goto Fun1 goto NextFun ; ничего не нажато goto NextFun ; ничего не нажато goto NextFun ; ничего не нажато Fun1 incf KeyWait,f btfss KeyWait,7 goto Edt ; next 8xLED Fun11 call Inkey addwf PC,f goto Fun11 ; ждем отжатия клавиш goto WrtMem ; запись в память goto WrtMem ; запись в память goto WrtMem ; запись в память ; ;============================================= ; Перекодирование двоичного в код LCD ;============================================= ; Bin2LCD bcf Status,0 ; clear the carry bit movlw .24 movwf Count clrf LED3 clrf LED2 clrf LED1 clrf LED0 loop16 rlf TimerL,f rlf TimerM,f rlf TimerH,f rlf LED0,f rlf LED1,f rlf LED2,f rlf LED3,f ; decfsz Count,f goto adjDEC swapf LED3,w andlw 0Fh movwf LED7 movfw LED3 andlw 0Fh movwf LED6 swapf LED2,w andlw 0Fh movwf LED5 movfw LED2 andlw 0Fh movwf LED4 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 ; movlw LED2 movwf FSR call adjBCD ; movlw LED3 movwf FSR call adjBCD ; goto loop16 ; adjBCD movlw 3 addwf 0,W movwf Count1 btfsc Count1,3 ; test if result > 7 movwf 0 movlw 30 addwf 0,W movwf Count1 btfsc Count1,7 ; test if result > 7 movwf 0 ; save as MSD ; retlw 0 ; ;============================================= ; Преобразование BCD -> 7 сегментный код ;============================================= LCDTable addwf PC,F ; W + PC -> PC retlw b'00111111' ; ..FEDCBA = '0' retlw b'00000110' ; .....CB. = '1' retlw b'01011011' ; .G.ED.BA = '2' retlw b'01001111' ; .G..DCBA = '3' retlw b'01100110' ; .GF..CB. = '4' retlw b'01101101' ; .GF.DC.A = '5' retlw b'01111101' ; .GFEDC.A = '6' retlw b'00000111' ; .....CBA = '7' retlw b'01111111' ; .GFEDCBA = '8' retlw b'01101111' ; .GF.DCBA = '9' retlw b'01110001' ; .GFE...A = 'F' ; ;============================================= ;Main program ; Start bsf Status,RP0 movlw b'00010000' ; RA0..RA3 outputs movwf TrisA ; RA4 input movlw b'00000000' ; RB0..RB7 outputs movwf TrisB clrwdt ; movlw b'00100111' ; Prescaler -> Timer0, movwf OptionR ; 1:256, rising edge bcf Status,RP0 ; clrf Count ; указатели clrf LEDIndex clrf LED0 ; индикаторы clrf LED1 clrf LED2 clrf LED3 clrf LED4 clrf LED5 clrf LED6 clrf LED7 clrf TimerL ; ячейки счета clrf TimerM clrf TimerH ;============================================= ;Преобразование bin => BCD => код для индикаторов ; Go bcf EECon1,2 ; запрещение записи movlw 0 movwf EEAdr bsf Status,RP0 bsf EECon1,0 bcf Status,RP0 ; movf EEData,w movwf IF_H movlw 1 movwf EEAdr bsf Status,RP0 bsf EECon1,0 bcf Status,RP0 ; movf EEData,w movwf IF_M movlw 2 movwf EEAdr bsf Status,RP0 bsf EECon1,0 bcf Status,RP0 ; movf EEData,w movwf IF_L call Bin2LCD ; ;============================================= ; Регистры LED0..LED7 заполнены значениями, готовимся ; измерять и отображать ;============================================= ; clrf IntCon ; clear overflow bite clrf TimerH ; старший байт измерения clrf Timer0 ; собственно таймер clrf LEDIndex ; указатель цифры ; movlw .60 ; начальное значение счетчика movwf Count ; 60 -> Count ; ;============================================= ; Начало измерения и индикации: RA3 set input ;============================================= ; movlw b'00000000' ; 0 во все порты movwf PortA ; bsf Status,RP0 movlw b'00011000' ; RA0..RA2 output,RA3..RA4 input movwf TrisA ; RA4 input bcf Status,RP0 ; ; ;============================================= ; 7-step cycle of digits ;============================================= ; LEDCycle movlw LED0 addwf LEDIndex,W ; LED1 + LEDIndex -> W movwf FSR ; W -> FSR movf IndF,W ; LED(0..6) -> W call LCDTable ; W -> семисегментный код movwf Temp ; точка есть? movlw 5 bsf Status,ZF subwf LEDIndex,W btfss Status,ZF goto NoDot bsf Temp,7 NoDot movf Temp,W movwf PortB ; вывод цифры в PortB movf LEDIndex,W ; LEDIndex -> W movwf PortA ; вывод позиции в PortA ; ;============================================= ; Проверка TMR0 на переполнение ;============================================= ; btfss IntCon,2 goto DoNothing incf TimerH,F bcf IntCon,2 goto O_K DoNothing nop nop nop ; ;============================================= ; The first timing loop ;============================================= O_K movlw T1 movwf Temp Pause decfsz Temp,F goto Pause ;============================================= ; incf LEDIndex,F movlw 7 ; is 7th? bcf Status,ZF subwf LEDIndex,W btfss Status,ZF goto LEDCycle ; след. цифра nop ; clrf LEDIndex decfsz Count,F goto LEDCycle ; next 7xLED nop ;============================================= ; The second timing loop ;============================================= movlw T2 movwf Temp EndPause decfsz Temp,F goto EndPause nop ;============================================= ; Завершение измерения ;============================================= Nx clrw movwf PortB ; RB0..RB7 = 0 movwf PortA ; RA0..RA3 = 0 bsf Status,RP0 movlw b'00010000' movwf TrisA ; RA4 input bcf Status,RP0 ; nop nop ;============================================= ; Последняя проверка TMR0 на переполнение ;============================================= btfss IntCon,2 goto Analyse bcf IntCon,2 incf TimerH,F ;============================================= ; Анализ содержимого предварительного делителя ;============================================= Analyse nop movf Timer0,W ; средний байт счетчика movwf TimerM ; TMR0 -> TimerM clrf TimerL CountIt incf TimerL,F bsf PortA,3 ; _| false impulz nop bcf PortA,3 ; |_ nop movf Timer0,W ; actual Timer0 -> W bcf Status,ZF subwf TimerM,W btfsc Status,ZF goto CountIt incf TimerL,F comf TimerL,F incf TimerL,F incf TimerL,F ; младший байт счетчика goto KeyQuery minusIF comf IF_L,f incf IF_L,f btfsc Status,ZF decf IF_M,f comf IF_M,f btfsc Status,ZF decf IF_H,f comf IF_H,f ; movf IF_L,w addwf TimerL,f btfsc Status,CF incf TimerM,f movf IF_M,w addwf TimerM,f btfsc Status,CF incf TimerH,f movf IF_H,w addwf TimerH,f btfsc Status,CF ; результат отрицательный? goto Go1 ; нет btfsc Status,CF ; а не ноль? goto Go1 ; нет comf TimerL,f ; преобразование incf TimerL,f btfsc Status,ZF decf TimerM,f comf TimerM,f ; отрицательного btfsc Status,ZF decf TimerH,f comf TimerH,f ; результата Go1 movlw 0 movwf KeyWait goto Go plusIF movf IF_L,w addwf TimerL,f btfsc Status,CF incf TimerM,f movf IF_M,w addwf TimerM,f btfsc Status,CF incf TimerH,f movf IF_H,w addwf TimerH,f goto Go1 Edt clrf IntCon ; clear overflow bite movlw 0ah movwf LED7 ; признак режима ;============================================= ; 8-step cycle of digits ;============================================= ; movlw b'00000000' ; movwf PortA ; bsf Status,RP0 movlw b'00010000' ; RA0..RA3 output,RA4 input movwf TrisA ; bcf Status,RP0 ; clrf LEDIndex ; указатель цифры EdtCycle movlw LED0 addwf LEDIndex,W ; LED1 + LEDIndex -> W movwf FSR ; W -> FSR movf IndF,W ; LED(0..6) -> W call LCDTable ; W -> семисегментный код movwf Temp ; точка есть? movlw 5 bsf Status,ZF subwf LEDIndex,W btfss Status,ZF goto NoDot1 bsf Temp,7 NoDot1 movf Temp,W movwf PortB ; вывод цифры в PortB movf LEDIndex,W ; LEDIndex -> W movwf PortA ; вывод позиции в PortA ; ;============================================= ; Timing loop ;============================================= movlw .255 movwf Temp Pause1 decfsz Temp,F goto Pause1 ;============================================= ; incf LEDIndex,F btfss LEDIndex,3 goto EdtCycle ; след. цифра ; clrf LEDIndex goto FunOff ; NextFun movlw 0 ; выход из цикла редактирования movwf KeyWait goto Edt ; next 8xLED ; WrtMem ; запись в EEPROM movlw 0 movwf IntCon ; запрещение прерываний movwf EEAdr movf IF_H,w movwf EEData bsf Status,RP0 bsf EECon1,2 ; разрешение записи movlw 055h movwf EECon2 movlw 0AAh movwf EECon2 bsf EECon1,1 wr1 btfss EECon1,4 goto wr1 bcf EECon1,4 bcf Status,RP0 movlw 1 movwf EEAdr movf IF_M,w movwf EEData bsf Status,RP0 bsf EECon1,2 ; разрешение записи movlw 055h movwf EECon2 movlw 0AAh movwf EECon2 bsf EECon1,1 wr2 btfss EECon1,4 goto wr2 bcf EECon1,4 bcf Status,RP0 movlw 2 movwf EEAdr movf IF_L,w movwf EEData bsf Status,RP0 bsf EECon1,2 ; разрешение записи movlw 055h movwf EECon2 movlw 0AAh movwf EECon2 bsf EECon1,1 wr3 btfss EECon1,4 goto wr3 bcf EECon1,4 bcf Status,RP0 ; goto Go1 ; ;============================================= end