pic16f84 LED频率计

发布者:fuehrd努力的最新更新时间:2017-12-05 来源: eefocus关键字:pic16f84  LED频率计 手机看文章 扫描二维码
随时随地手机看文章

;|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      ; timing loop values 

;-------------------------------------------------------------------------- 

            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 


关键字:pic16f84  LED频率计 引用地址:pic16f84 LED频率计

上一篇:PIC16F877A LCD驱动HT1621的源代码
下一篇:pic16f627键盘显示+E2PROM存取+模拟I2C总线通信等模块

小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved