;|http://www.pICavr.com-------------------------------------------------
;| 2000
;|------------------------------------------------------------------------|
;| 7LED频率计 共计 35 MHz. The decimal 小数点 |
;| point is after MHz digit, but CAN be set at any position. Two dots can |
;| be set too (timing formula will change!). |
;| |
;| 功耗: 2.5V/9mA, 3V/13mA, 5V/35mA. |
;| |
;| 硬件: |
;| : PIC 16F84 |
;| 4051 (BCD -> 1 of 8 decoder) |
;| 8个 NPN 三极管, |
;| 7LED (共阴), |
;| some resistors, caPACitors and 2 switching diodes |
;| |
;| Note: |
;| "Calculator display" means (say) 7 digit LED multiplexed display. |
;| Both common cathode and common anode can be used. SOFtware is written |
;| for both common cathode and common anode display. For common anode |
;| displays it requires very slight software (uncomment what is commented |
;| and comment what isn’t...;-) and hardware modification (switching |
;| transistors are PNP instead NPN, ther EMIters are connected with +5V |
;| and also PIN No.3 of 4051 should be grounded). |
;| |
;| PIC is used as 3 byte counter. If it counts 0.1 s maximum measured |
;| Frequency is FF FF FF, e. g. 167.77215 MHz (theoretically). |
;| |
;| In reality the maximum measured frequency will not exceed 50 MHz |
;| what is maximum input frequency of PIC precounter. But real one is |
;| around 27 MHz and with 1/6 of 74HC14 (Schmitt trigger) up to 38 MHz. |
;| | | |
;| +-+ +-+ |
;| | | | | |
;| | 470| | 470 | | |
;| | | | | | |
;| | +-+ +---\ +-+ |
;| RA4 | +------+ | | | | |
;| RA3 |--| 470 |-+--| +0-+-\ |
;| RA2 | +------+ | | \|___ |
;| ------+ +---/ /| |
;| V |
;| | |
;| --- |
;|------------------------------------------------------------------------|
;| |
;| The scale uses internal prescaler of PIC as low byte of counter, |
;| TMR0 as middle byte and some register as high byte of counter. The |
;| software DOESN’T read anything from any input port. RA4 is used as |
;| prescaler input. |
;| |
;|------------------------------------------------------------------------|
;| |
;| Measuring period is 100 000 us. |
;| Procesor cycle is T = 4/Fx us [MHz], fx is Xtal frequency |
;| |
;| Number of procesor cycles per measuring period: |
;| |
;| N = 100 000/T procesor cycles |
;| N = Fx * 100 000/4 = 25 000 * Fx |
;| |
;| The main steps of measuring period: |
;| |
;| 1. start measurement, |
;| 2. precode decimal value of digit to segments, |
;| 3. if it’s 5th digit set decimal point, |
;| 4. output to PortB, |
;| 5. output digit number to PortA |
;| (numbers from left to right are 6543210), |
;| 6. test TMR0 overflow bite, if YES increase TimerH, |
;| 7. leave digit to light, |
;| 8. increase digit number, |
;| 9. if <7 goto 2, |
;| 10. else zero digit number, decrease counter and goto 2, |
;| 11. stop measurement, |
;| 12. shift out precounter content, |
;| 13. in case of digital scale add/substract RF, |
;| 14. precode 3-byte value into 7 decimal numbers, |
;| 15. goto 1 |
;| |
;|------------------------------------------------------------------------|
;| |
;| Total timing formula: |
;| |
;| N = 25 000 * Fx = 60*[7*(36 + 3*T1) + 6 + 3*T2] + 12 + 3*T3 + Z |
;| |
;| where T1,T2,T3 are initial values of timing loops, |
;| Z are additional tunig NOPs, |
;| Fx Xtal frequency in MHz. |
;| |
;|------------------------------------------------------------------------|
;| Some ideas were taken from "Simple low-cost digital frequency meter |
;| using a PIC 16C54" (frqmeter.asm) |
;| written by James Hutchby, MadLab Ltd. 1996 |
;|------------------------------------------------------------------------|
;| |
;| This software is free for private usage. It was created for HAM radio |
;| community members. Commercial exploatation is allowed only with |
;| permission of authors. |
;| |
;|------------------------------------------------------------------------|
; include
include
;--------------------------------------------------------------------------
Index equ 0Ch ; dummy register
Count equ 0Dh ; inkremental register
Help equ 0Eh ; dummy register
LED0 equ 0Fh
LED1 equ 010h
LED2 equ 011h
LED3 equ 012h
LED4 equ 013h
LED5 equ 014h
LED6 equ 015h
LED7 equ 016h
TimerH equ 017h ; higher byte of SW counter
LowB equ 018h ; low byte of resuLTEd frequency
MidB equ 019h ; middle byte of resulted frequency
HigB equ 01Ah ; high byte of resulted frequency
Temp equ 01Bh ; temporary register
HIndex equ 01Ch ; index register
LEDIndex equ 01Dh ; LED pointer
;--------------------------------------------------------------------------
include
;--------------------------------------------------------------------------
org 0
Start clrf Index
clrf LEDIndex
clrf LED0
clrf LED1
clrf LED2
clrf LED3
clrf LED4
clrf LED5
clrf LED6
clrf LED7
clrf LowB
clrf MidB
clrf HigB
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 -> TMR0,
MOVwf OPTION_REG ; 1:256, rising edge
bcf STATUS,RP0 ;
goto Go ; line 370
;+-------------------------------------------------------------------------+
;| The bLOCk of subroutines and constants tables |
;+-------------------------------------------------------------------------+
;+-------------------------------------------------------------------------+
;| 3 byte substraction of the constant from the table, it sets carry |
;| if result is negative |
;+-------------------------------------------------------------------------+
Subc24 clrf Temp ; it will temporary save CF
MOVf Index,W ; pointer to low byte of constant
MOVwf HIndex ; W -> HIndex
call DecTable ; W returned with low byte of constant
bsf STATUS,C ; set CF
subwf LowB,F ; LowB - W -> LowB
; if underflow -> C=0
btfsc STATUS,C
goto Step1
bsf STATUS,C
MOVlw 1
subwf MidB,F ; decrement MidB
; if underflow -> C=0
btfsc STATUS,C
goto Step1
bsf STATUS,C
MOVlw 1
subwf HigB,F ; decrement HigB
btfsc STATUS,C ; if underflow -> C=0
goto Step1
bsf Temp,C ; set C
Step1 decf HIndex,F
MOVf HIndex,W ; pointer to middle byte of const
call DecTable
bsf STATUS,C
subwf MidB,F ; MidB - W -> MidB
btfsc STATUS,C ; if underflow -> C=0
goto Step2
bsf STATUS,C
MOVlw 1
subwf HigB,1 ; decrement HigB
btfsc STATUS,C ; if underflow -> C=0
goto Step2
bsf Temp,C ; set C
Step2 decf HIndex,F
MOVf HIndex,W ; pointer to middle byte of constatnt
call DecTable
bsf STATUS,C
subwf HigB,F ; HigB - W -> HigB
btfsc STATUS,C ; if underflow -> C=0
goto ClearCF
bsf STATUS,C
goto SubEnd
ClearCF rrf Temp,C ; C -> STATUS
SubEnd retlw 0
;+-------------------------------------------------------------------------+
;| 3 byte addition of the constant from the table, it sets carry if |
;| result overflows |
;+-------------------------------------------------------------------------+
Addc24 clrf Temp ; register for temporary storage of CF
MOVf Index,W ; pointer to lower byte of const into W
MOVwf HIndex ; save it into HIndex
call DecTable ; W contains low byte of const
bcf STATUS,C ; clear C
addwf LowB,1 ; W + LowB -> LowB
btfss STATUS,C ; test overflow
goto Add2
bcf STATUS,C ; clear C
MOVlw 1
addwf MidB,F ; increment MidB
btfss STATUS,C
goto Add2
bcf STATUS,C
MOVlw 1
addwf HigB,F ; increment HigB
btfss STATUS,C ; test overflow
goto Add2
bsf Temp,C ; store C
Add2 decf HIndex,F ; pointer to middle byte into W
MOVf HIndex,W
call DecTable
bcf STATUS,C
addwf MidB,1 ; W + MidB -> MidB
btfss STATUS,C
goto Add3
bcf STATUS,C ; clear C
MOVlw 1
addwf HigB,1 ; increment HigB
btfss STATUS,C
goto Add3
bsf Temp,C
Add3 decf HIndex,F ; pointer to higher byte into W
MOVf HIndex,W
call DecTable
bsf STATUS,C
addwf HigB,F ; W + HigB -> HigB,
btfss STATUS,C
goto ClarCF
bsf STATUS,C
goto AddEnd
ClarCF rrf Temp,C ; C -> STATUS
AddEnd retlw 0
;+------------------------------------------------------------------------+
;| Tables of 3-byte constants |
;+------------------------------------------------------------------------+
;| Table of decades |
;+------------------------------------------------------------------------+
DecTable addwf PCL,F ; W + PCL -> PCL
retlw 0 ; 10
retlw 0 ;
retlw 0Ah ;
retlw 0 ; 100
retlw 0 ;
retlw 064h ;
retlw 0 ; 1 000
retlw 03h ;
retlw 0E8h ;
retlw 0 ; 10 000
retlw 027h ;
retlw 010h ;
retlw 01h ; 100 000
retlw 086h ;
retlw 0A0h ;
retlw 0Fh ; 1 000 000
retlw 042h ;
retlw 040h ;
;+-----------------------------------------------------------------------+
;| Table for conversion BCD -> 7 segments |
;+-----------------------------------------------------------------------+
LEDTable addwf PCL,F ; W + PCL -> PCL
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’01100111’ ; .GF..CBA = ’9’
retlw b’10000000’ ; H....... = ’.’
;It follows COMMON ANODE data table
;LEDTable addwf PCL,F ; W + PCL -> PCL
; retlw b’11000000’ ; ..FEDCBA = ’0’
; retlw b’11111001’ ; .....CB. = ’1’
; retlw b’10100100’ ; .G.ED.BA = ’2’
; retlw b’10110000’ ; .G..DCBA = ’3’
; retlw b’10011001’ ; .GF..CB. = ’4’
; retlw b’10010010’ ; .GF.DC.A = ’5’
; retlw b’10000010’ ; .GFEDC.A = ’6’
; retlw b’11111000’ ; .....CBA = ’7’
; retlw b’10000000’ ; .GFEDCBA = ’8’
; retlw b’10011000’ ; .GF..CBA = ’9’
; retlw b’01111111’ ; H....... = ’.’
;+------------------------------------------------------------------------+
;| The main cycle entry point |
;+------------------------------------------------------------------------+
;| Routine for conversion of 3-byte number into 7 digits |
;+------------------------------------------------------------------------+
Go bsf STATUS,RP0
MOVlw b’00000000’
MOVwf TRISB
bcf STATUS,RP0
MOVlw 6*3-1 ; pointer to dec. table
MOVwf Index ; 6*3-1 -> Index
MOVlw 9 ; maximum of substractions
MOVwf Count ; 9 -> Count
clrf Help
MOVlw 6
MOVwf LEDIndex
Divide call Subc24 ; substract untill result is negative,
btfsc STATUS,C ; add last substracted number
goto Add24 ; next digit
incf Help,F
decf Count,F
btfss STATUS,Z
goto Divide
MOVlw 3
subwf Index,F
goto Next
Add24 call Addc24
MOVlw 3
subwf Index,F
Next MOVlw 9
MOVwf Count
MOVlw LED1 ; LED1 -> W
addwf LEDIndex,W ; LED1 + LEDIndex -> W
MOVwf Temp
decf Temp,F ; LEDIndex+LED1-1 -> TEMP
MOVf Temp,W
MOVwf FSR ; W -> FSR
MOVf Help,W ; Help -> W
clrf Help ; save result at LEDx
MOVwf INDF ; W -> LED(6..1)
decf LEDIndex,F
MOVlw 1
addwf Index,W
btfss STATUS,Z
goto Divide
MOVf LowB,W
MOVwf LED0 ; the rest -> LED0
;+-----------------------------------------------------------------------+
;| Registers LED0..LED6 are filled with values |
;+-----------------------------------------------------------------------+
clrf TimerH
clrf TMR0
nop
nop
clrf LEDIndex
MOVlw .60 ; set initial counter value
MOVwf Index ; 60 -> Index
clrf INTCON ; global INT disable, TMR0 INT disable
; clear TMR0 overflow bite
;+---------------------------------------------------------------------+
;| Start of the measurement: RA3 + RA4 set input |
;+---------------------------------------------------------------------+
MOVlw b’00010000’ ; all ports set L, RA4 set H
MOVwf PORTA
bsf STATUS,RP0
MOVlw b’00011000’ ; RA0..RA2 output, RA3, RA4 input
MOVwf TRISA
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 LEDTable ; W contains segments
MOVwf Temp ; test for decimal point
MOVlw 5
bsf STATUS,Z
subwf LEDIndex,W
btfss STATUS,Z
goto NoDot
bsf Temp,7 ; common cathode....
; bcf Temp,7 ; common anode....
NoDot MOVf Temp,W
MOVwf PORTB ; segments -> PORTB
MOVf LEDIndex,W ; LEDIndex -> W
nop
MOVwf PORTA ; digit number -> PORTA
;+------------------------------------------------------------------------
;Test for TMR0 overflow
;+------------------------------------------------------------------------
btfss INTCON,2 ; Test for TMR0 overflow
goto DoNothing
incf TimerH,F ; YES! Increment SW counter
bcf INTCON,2 ; clear overflow bite
goto O_K
DoNothing nop
nop
nop
;+-----------------------------------------------------------------------+
;| The first timing loop 2+3*T1 procesor cycles |
;+-----------------------------------------------------------------------+
O_K MOVlw T1
MOVwf Temp
Pause decfsz Temp,F
goto Pause
nop
;+-----------------------------------------------------------------------+
;| The end of one digit processing |
;+-----------------------------------------------------------------------+
incf LEDIndex,F
MOVlw 7 ; is 7th?
bcf STATUS,Z
subwf LEDIndex,W
btfss STATUS,Z
goto LEDCycle ; next digit
nop
;+-----------------------------------------------------------------------+
;| The second timing loop 2+3*T2 procesor cycles |
;+-----------------------------------------------------------------------+
MOVlw T2
MOVwf Temp
Again decfsz Temp,F
goto Again
nop
;+-----------------------------------------------------------------------+
;| The end of one 7-digits processing |
;+-----------------------------------------------------------------------+
clrf LEDIndex
decfsz Index,F
goto LEDCycle ; next 7 * LED
nop
;+-----------------------------------------------------------------------+
;| The third timing loop 2+9*T3+Z procesor cycles |
;+-----------------------------------------------------------------------+
MOVlw T3
MOVwf Temp
EndPause decfsz Temp,F
goto EndPause
nop
include
; nop ; Z times NOP
; nop ; 60 * (6 + 7 * (36 + 3*T1) + 3*T2) + 2 + 3*T3 + Z
;=========== 最后测试 TMR0 溢出位============
btfss INTCON,2 ; 1
goto Nothing2Do ; 3
incf TimerH,F ; 3
bcf INTCON,2 ; 4
goto Nx ; 6
Nothing2Do nop ; 4
nop ; 5
nop ; 6 60 * (6 + 7 * (36 + 3*T1) + 3*T2) + 8 + 3*T3 + Z
;===========停止测量: RA3 out; RA4 in================
Nx clrw ; For common cathode
;Nx MOVlw b’11111111’ ; For common anode
MOVwf PORTB
MOVlw b’00010000’ ; RA0..RA3 = 0
MOVwf PORTA ; W -> PORTA
bsf STATUS,RP0
MOVlw b’00010000’ ; RA0..RA3 output
MOVwf TRISA ; RA4 input
bcf STATUS,RP0
btfsc INTCON,2 ; really final check
incf TimerH,F
bcf INTCON,2
;==========分晰存储 计数值========== |
MOVf TMR0,W
MOVwf MidB ; TMR0 -> MidB
MOVf TimerH,W
MOVwf HigB ; TimerH -> HigB
clrf Temp
CountIt incf Temp,F
bsf PORTA,3 ;伪信号
bcf PORTA,3 ;
;
bcf INTCON,2
MOVf TMR0,W ; TMR0 -> W
bcf STATUS,Z
subwf MidB,W
btfsc STATUS,Z
goto CountIt
incf Temp,F
comf Temp,F
incf Temp,F
incf Temp,W
MOVwf LowB
;==========================
goto Go
;==============================
end
上一篇:PIC16F877A LCD驱动HT1621的源代码
下一篇:pic16f627键盘显示+E2PROM存取+模拟I2C总线通信等模块