Jiminez Promo 1 604638263eb39

Microcontroller Delivers High-Precision Frequencies

March 22, 2021
Taking time-base generators to another level, this Idea for Design describes a PIC microcontroller that can generate highly precise frequencies from 1 Hz to 4 MHz.

Members can download this article in PDF format.

What you'll learn:

  • How to set up an PIC microcontroller to deliver high-precision frequencies from 1 Hz to 4 MHz.
  • Examples of the frequencies delivered by this microcontroller design.

In timing applications, a time-base generator is a crucial component for achieving accurate readings. In the past, classic time-base generators from the MM5369 family were used to generate accurate time-base signals. In this design (Fig. 1), the PIC microcontroller 16F1619 is used to generate high-precision frequencies within the range of 1 Hz to 4 MHz.

The microcontroller’s pulse-width-modulation (PWM) and capture, compare, and PWM (CCP) modules deliver a PWM signal with a specific duty cycle, period, and resolutions that are configured by registers PRx, TxCON, CCPRxH, CCPRxL, and CCPxCON. The PWM module has a 10-bit resolution output and uses Timer2 and PR2 registers to set the signal’s period. The CCPRxL and CCPRxH registers configure the duty cycle. Therefore, if we keep the duty cycle at 50%, we can make an oscillator, and by controlling the period set register, we’re able to generate a desired frequency signal.

Knowing this, we need to calculate the PWM pulse width, duty cycle, and period, using the equations below.

Pulse-Width Equation

The pulse width is determined by the period of internal oscillator, DCH and DCL registers, and the Timer2 Prescale value:

(Equation 1)

Pulse Width = CCPRxL:CCPxCON * Tosc * (TMRx Prescalar value)       

where:

(Equation 2)

Tosc = 1/Fosc

PWM-Period Equation

The PWM period is specified by register PR2 of TIMER2. This period can be calculated using Equation 3:

(Equation 3)

PWM Period = [(PRx) + 1] * 4 * Tosc * (TMRx Prescalar value)       

where:

(Equation 4)

PWM Period: 1/Output Frequency  

and PRx is a Register of Timer X.

Duty-Cycle Ratio Equation

The PWM duty cycle is specified by writing a 10-bit value to multiple registers CCPR1L, and DC1B <1:0> bits of the CCP1CON register:

(Equation 5)

Duty Cycle Ratio - (CCPRxH:CCPRxL)/[4(PRx+1)]

PWM Resolution

The resolution determines the number of available duty cycles for a given period:

(Equation 6)

Resolution = (log[4(PRx+1)])/log(2) bits

At this point, we know all of the equations that are needed, and how registers can be configured.

Now, if we want a 250-Hz signal oscillator, for example, we can use Equation 4 to get:

(Equation 7)

PWM Period: 1/Out Frequency = 1/250Hz = 0.004s

We need a period equal to 4 ms, so by using Equation 3, we can get the PR2 value based on the TMR2 prescale value:

(Equation 8)

PWM Period = [(PPRx) + 1] * 4 * Tosc * (TMRx Prescaler value)

Solving for PRx we get Equation 9:

(Equation 9)

PR2 = ([PWM Period]/[4 & Tosc * (TMRx Prescaler value)]) - 1

setting the internal clock to 4 MHz:

(Equation 10)

Tosc = 1/Fosc = 1/4 MHz = 2.5*10-7s

And setting the TMR2 prescale to 1:16, we can substitute these values into Equation 9 to get PR2:

 (Equation 11)

PR2 = (0.004s/[4*2.5*10-7s*(1:16 Prescaler value)]-1 = 250-1 = 249    

Then for 250 Hz, we need to set PR2 to a 249 decimal value. Now that we have a PR2 value for this frequency, we have to set registers CCPRxL and CCPRxH for a 50% duty cycle. Then, using Equation 5, we get:

(Equation 12)

Duty Cycle Ratio= (CCPRxH:CCPRxL)/[4(PRx+1)]

Solving for CCPRxH and CCPRxL, we get:

(Equation 13)

CCPRxH:CCPRxL = Duty Cycle Ratio * 4(PRx +1) = 50% * 4(249 + 1) = 500 

The result is 500, which in binary code is 0111110100. Thus, we have the 10 bits for CCPRx, and we set FMT = 0, for a right justified alignment (Table 1).

Now, to convert this to PBP3 code, we need to set all registers as shown below. In this case, we need to generate a 250-Hz signal:

 
/For 250Hz/ 
RC3PPS  = %00001101    ; setting CCP1 as an output and enabling PPS.
CCP1CON = %10001100    ; selecting PWM mode and CCP1 enabled.
PR2     = %11111001    ; setting PR2 = 249
T2CON   = %11000000    ; Enabling TMR2 and Prescale to 1:16.
CCPR1L  = %11110100    ; value obtained from equation
CCPR1H  = %00000001    ; value obtained from equation
/end/

RC3 is the CCP1 output—that pin is going to generate the oscillator output.

Considering a microcontroller as an efficient controlled oscillator, we have to set the frequency ranges. Therefore, if we manipulate PR2 from 0 to 255, we get 256 different frequencies values for each prescale. Knowing this, we can take PR2 as our input variable and, at the same time, set it as a constant with prescaler and duty-cycle values. Then the microcontroller can solve the PWM equation to determine the output frequency.

For example, if we get a prescale set of 1:128 and the Internal oscillator is 4 MHz, we can get a Constant Factor to solve Equation 9 for that frequency.

Thus, solving for Fout we get:

(Equation 14)

Fout = 1/[4*Tosc*(TMRx Prescaler value)*(PR2 + 1)]

Then if we separate all the constants values, we get 7812.5 as Constant Factor:

(Equation 15)

Fout = 1/[PR2 + 1] * 1/[4*Tosc*(TMRx Prescaler value)] = 1/(PR2 + 1) * 7812.5   

The nearest integer number for this factor is 78125, but it’s greater than a 16-bit number. Therefore, we need to multiply two numbers to get 78125 to take advantage of the 32 bits as an internal result; 15625 x 50 gives this number.

Now solving for Fout, each frequency value that we can reach will depend on the PR2 value. Thus, the minimum value for PR2 = 255 is 30.52 Hz, and for PR2 = 0 it’s 7.81 kHz. So, if we apply all of this over again, but with a different prescaler value, we can take other range of reachable frequencies.

The last step is to set the CCP register, which we set at 50% of the duty cycle using Equation 5:

(Equation 16)

(CCPRxH:CCPRxL) = 2 * (PR2 + 1)

If we save this as a word type variable, we get all 16 bits. To separate them, we can use a byte command to extract the 8 bits and save them on CCPRxL and CCPRxH.

An example of the frequencies this design can deliver is shown in Tables 2, 3, and 4. In Table 2, the microcontroller uses the internal oscillator at 16 MHz. Table 3 shows a frequency range within 30 Hz and 4 MHz. And Table 4 shows the frequency and duty-cycle accuracies.

Figures 2, 3, 4, and 5 show the scope images for four different delivered frequencies by the PIC microcontroller.

Figures 6, 7, and 8 show the actual assembled PC circuit with three different freqeucy selection cases.  

The listing below shows the code using the PBP3 compiler from melabs.com.

Code for the Oscillator

'*  Name    : Controlled Oscillator.BAS                         
'*  Authors  : Ricardo Jimenez and Kevin A. Martinez                                 
'*  Notice  :   Compiled with PBP3 version 3.1 from melabs.com                          
'*  Date    :   1/04/2021                                                                           
'*  Notes   :   PIC16F1619 with external 4.000 MHz XTAL                                               
;    on interrupt goto SET;   IF INTERRUPT GO TO LABEL SEL
 #CONFIG; FUSSES 
    __config _CONFIG1,  _FOSC_HS & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOREN_ON & _CLKOUTEN_OFF
    __config _CONFIG2,  _WRT_OFF & _PPS1WAY_OFF & _ZCD_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
    __config _CONFIG3,  _WDTCPS_WDTCPS4 & _WDTE_ON & _WDTCWS_WDTCWS100 & _WDTCCS_LFINTOSC
  #ENDCONFIG
;#CONFIG
;    __config _CONFIG1,  _FOSC_HS
 ;   #endconfig
;SETTING INTERNAL OSCILLATOR
OSCCON =  %01101000;    16MHZ 
;OSCSTAT = %00010001;  INTERNAL CLOCK
OSCTUNE = 0;
;SETTING PORTS
;--PORTB--
TRISB = 0; ALL AS outputs  
ANSELB = 0; ALL AS DIGITAL
WPUB = 0; PULL UPS DISABLED
;--PORTC--
TRISC = %00011000; RC3 and RC4 as inputs
ANSELC = %00000000; ALL AS DIGITAL
WPUC = 0; PULL UPS DISABLED
;--PORTA--
TRISA = %00101100; RA5,RA3 and RA2 as inputs
ANSELA = 0;   ALL DIGITAL
WPUA = 0;     PULL-UP resistors disabled
;--LCD CONFIGURATION ----------------------
define OSC 16
DEFINE LCD_DREG PORTB ' PORTC is LCD data port
DEFINE LCD_DBIT 4 ' PORTB.4 is the data LSB
DEFINE LCD_RSREG PORTA ' RS is connected to PORTA.0
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTA ' E is connected to PORTA.1
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4 ' 4  data line
DEFINE LCD_LINES 2 '  2-line display
DEFINE LCD_COMMANDUS 1500 ' Use 1500uS command delay
DEFINE LCD_DATAUS 44 ' Use 44uS data delay
;---------SETTING UP LCD-------------------------------------------------------

LCDOUT $FE,$28;  $28 FUNCTION SET, 4 BITS
LCDOUT $FE,$10;  $10 SHIFT DISPLAY
LCDOUT $FE,$0C;  $0C DISPLAY ON
LCDOUT $FE,$06;  $06 ENTRY MODE SET
;------------------------------------------------------------------------------
f var word: fout var word: prx var word: pr var word: CCP var word: x var word
C var word: A var byte: F32b var word: i var byte: FD var byte[4]: fent var word
k var byte
;--------------------INTERRUPT CONFIGURATION-------------------------

;INTCON = %11001000;ENABLE INTERRUPT
;IOCAN = %001000; RA3 INTERRUPT
;;------------------ADC CONFIG-----------------------------------
ADCON0 = %00001101;ADC ENABLED
ADCON1 = %10000000; RIGHT JUSTIFIED
;---------- ----------------------------------------------------
;-----Initializing variables----------
f=255;
A=1;
;-----------------Creating Special Characters------------------
LCDOUT $FE,$40,$01,$01,$01,$01,$01,$01,$01,$1F 'L symbol
pause 50
LCDOUT $FE,$48,$1F,$01,$01,$01,$01,$01,$01,$01 'L symbol
pause 50
LCDOUT $FE,$50,$00,$00,$00,$00,$00,$00,$00,$1F 'L symbol
pause 50
LCDOUT $FE,$58,$1F,$00,$00,$00,$00,$00,$00,$00 'L symbol
pause 50
;-----------------initializing PWM-----------------------------
RC5PPS=%00001100;       SETTING CCP1 AS AN OUTPUT AND ENABLE IT
CCP1CON=%00001100;      PWM mode selection and CCPx disabled
CCPTMRS=%11110100;      CCP1 AND CCP2 ARE BASED OFF TIMER 2
PAUSE 50;               pause to save the PWM configuration 
;---------------------------first start lcd show ------------------
 lcdout $fe,$80," MICRO-CONTROLLED      "    ; MESSAGES 
 lcdout $fe,$c0," OSCILLATOR ",0,1,0,1,2;
pause 1000;
WHILE(1)        ;waiting interrupt
 if PORTA.3=0 then 
    LCDOUT $fe,1;
    goto SETRange
 endif
 pause 15 ; Debouncing
 LCDOUT $fe,1;
 lcdout $fe,$80,"    PRESS BUTTON          "    ; MESSAGES 
 lcdout $fe,$c0,"      TO START            "
wend

SETRange: 
 CCP1CON.7 =0; CCP1 Disabled
 lcdout $fe,$80,"Please Select Range:   "    ; MESSAGES
 gosub Range;
 gosub BTNsel;;
 pause 50 
 if PORTA.2=0 then ;waiting 'ENTER' Button to start Range set
    LCDOUT $fe,1;
    goto SETfreq
 endif
 goto SETRange
return
 ;----------------------------------------------------------
SETfreq:
 SELECT CASE A
    CASE 1
        GOTO RANGE0
    CASE 2
        GOTO RANGE1
    CASE 3
        GOTO RANGE2
    CASE 4 
        GOTO RANGE3
    CASE 5 
        GOTO RANGE4
    CASE 6 
        GOTO RANGE5
    END SELECT
;--------------choosing Range---------------------------------------
Range:
if A=1 then
   lcdout $fe,$c0,"   30Hz To 100Hz      "
elseif A=2 then
    lcdout $fe,$c0,"  100Hz To 300Hz    "
elseif A=3 then
    lcdout $fe,$c0,"  300Hz To 1000Hz   "
elseif A=4 then
    lcdout $fe,$c0,"  1KHz To 10KHz     "
elseif A=5 then
    lcdout $fe,$c0,"  10KHz To 100KHz    "
elseif A=6 then
    lcdout $fe,$c0,"  100KHz To 4MHz     "
endif
return               
;------------------------Buttons + and - --------------------------
BTNsel:
if PORTC.3=0 then
    f = f-1;
    A = A+1
elseif PORTC.4=0 then
    f = f+1;
    A = A-1;
endif
if a >6 then
    a=1
elseif A<1 then 
    a=6
endif
pause 20
return
;------------------------------------------------------------- 
RANGE0:    ;-----------30Hz to 100Hz-------------------------
k=0
f=255
Pause 25
T2CON=%11110000;        enabling timer 2
while(1)
gosub BTNsel
if f>255 then    ; Minimum Range Limit 
    f=77
elseif f<77 then  ; Maximum Range Limit
    f=255
endif
if PORTA.3=0 then  ; waiting to "RESET OR BACK" Button
    goto SETRange
    a=1
endif
prx = f+1 ;Setting PRX value for equation 
x=50;    ; CONSTANT 16 bits FACTOR from PWM equation
C=15625  ; CONSTANT 16 bits FACTOR from PWM equation
F32b= C*x  ; Saving and using 32bits Value for real constant factor
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fent,".",dec FD[1],dec FD[0],"Hz     "
if PORTA.2=0 then goto Sout  ;" Waiting "ENTER" BUTTON
pause 15 ; Debouncing
wend
;-------------------------------------------------------------
RANGE1:    ;---------------100Hz to 200Hz---------------------
OSCCON = %01101000; $6A, 4MHZ
pause 50 
k=0
Pause 25
T2CON=%11100000        ;enabling prescaler 1:64
f=155
while(1)
gosub BTNsel
if f>155 then 
    f=103
    gosub RANGE1_2
elseif f<77 then
    f=155 
    gosub RANGE1_2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=15625
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fent,".",dec FD[1],dec FD[0],"Hz     "
if PORTA.2=0 then goto Sout
pause 15
wend

RANGE1_2: ;------------200Hz to 300Hz----------------------------
Pause 25
T2CON=%11010000        ;enabling prescaler 1:32
while(1)
gosub BTNsel
if f>155 then 
    f=77
    gosub RANGE1
elseif f<103 then 
    gosub RANGE1
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=31250
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fent,".",dec FD[1],dec FD[0],"Hz     "
if PORTA.2=0 then goto Sout
pause 15
wend
;-------------------------------------------------------------
RANGE2:    ;----------300Hz to 488Hz------------------------
OSCCON = %01101000; $6A, 4MHZ
pause 50  
k=0
Pause 25
T2CON=%11000000        ;enabling prescaler 1:16
f=207
while(1)
gosub BTNsel
if f>207 then 
    f=124
    gosub RANGE2_2
elseif f<127 then
    f=255 
    gosub RANGE2_2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=62500
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fent,".",dec FD[1],dec FD[0],"Hz     "
if PORTA.2=0 then goto Sout
pause 15
wend

RANGE2_2:  ;----------------------488Hz to 1000Hz-----------------------------
k=5
Pause 25
T2CON=%10110000        ;enabling prescaler 1:8
while(1)
gosub BTNsel
if f>255 then 
    f=127
    gosub RANGE2
elseif f<124 then 
    gosub RANGE2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=12500
F32b= C*x
fout = div32 prx
gosub DIGIT
if f=124 then   ; special case for 1000Hz
gosub RANGE2_3
endif
lcdout $fe,$80,"Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec FD[3],dec FD[2],dec FD[1],".",dec FD[0],"0","Hz     "
if PORTA.2=0 then goto Sout
pause 15
wend
;-----------------Special Case 1000Hz --------------------
RANGE2_3:
fout=1000
while(1)
gosub BTNsel
if f>124 then 
    gosub RANGE2
elseif f<124 then 
    f=123
    gosub RANGE2_2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fout,"Hz     "
if PORTA.2=0 then goto Sout
pause 15
Wend
;-------------------------------1Khz to 10Khz-----------------------
RANGE3: ;--------------------1Khz to 1.9Khz--------------------
OSCCON = %01101000; $6A, 4MHZ
pause 50  
k=1
f=249
Pause 25
T2CON=%10100000;        enabling prescaler 1:4
while(1)
gosub BTNsel
if f>249 then 
    f=49
    gosub RANGE3_2
elseif f<128 then 
    f=255
    gosub RANGE3_2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=10;
C=25000
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fout,"Hz     "
if PORTA.2=0 then goto Sout
pause 15
wend
RANGE3_2: ;--------------------1.9Khz to 10Khz--------------------
k=1
Pause 25
T2CON=%10010000;        enabling prescaler 1:2
while(1)
gosub BTNsel
if f>255 then 
    f=128
    gosub RANGE3
elseif f<49 then 
    f=249
    gosub RANGE3
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=10;
C=50000
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fout,"Hz     "
if PORTA.2=0 then goto Sout
pause 15
wend
;-------------------------10Khz to 100Khz--------------------------
RANGE4:;-------------------10Khz to 15.5khz--------------------
k=1
f=199
;SETTING INTERNAL OSCILLATOR TO 16Mhz
OSCCON = %01111010; 16Mhz 
Pause 100
T2CON=%10010000;        enabling prescaler 1:2
while(1)
gosub BTNsel
if f>199 then 
    f= 39
    gosub RANGE4_3
elseif f<128 then 
    f=255
    gosub RANGE4_2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=20000
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fout,"Hz     "
if PORTA.2=0 then goto Sout
pause 50
wend
RANGE4_2:;-------------------15.5Khz to 65khz--------------------
k=1
;SETTING INTERNAL OSCILLATOR TO 16Mhz
OSCCON = %01111010; 16Mhz 
Pause 100
T2CON=%10000000;        enabling prescaler 1:1
while(1)
gosub BTNsel
if f>255 then 
    f= 128
    gosub RANGE4
elseif f<61 then 
    f=60
    gosub RANGE4_3
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=40000
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fout,"Hz     "
if PORTA.2=0 then goto Sout
pause 50
wend
RANGE4_3:;-------------------65Khz to 100khz--------------------
k=2
;SETTING INTERNAL OSCILLATOR TO 16Mhz
OSCCON = %01111010; 16Mhz 
Pause 100
T2CON=%10000000;        enabling prescaler 1:1
while(1)
gosub BTNsel
if f>62 then 
    f= 61
    gosub RANGE4_2
elseif f<39 then 
    f=199
    gosub RANGE4
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x= 100;
C= 4000
F32b= C * x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fent,".",dec FD[1],dec FD[0],"KHz     "
if PORTA.2=0 then goto Sout
pause 50
wend
;-------------------------100KHz to 4Mhz------------------------------------------
RANGE5: ;--------------100KHz to 571.42KHz-------------------------------
k=2
f=39
;SETTING INTERNAL OSCILLATOR TO 16Mhz
OSCCON = %01111010; 16Mhz 
Pause 100
T2CON=%10000000;        enabling prescaler 1:1
while(1)
gosub BTNsel
if f>39 then 
    f= 6
elseif f<6 then 
    f=39
    gosub RANGE5_2
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
x=100;
C=4000
F32b= C*x
fout = div32 prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec fent,".",dec FD[1],dec FD[0],"KHz     "
if PORTA.2=0 then goto Sout
pause 50
wend

RANGE5_2:;Special Case 666.66Khz and 800Khz
k=4
f=5
while(1)
gosub BTNsel
if f>5 then 
    f= 6
    gosub RANGE5
elseif f<4 then 
    f=3
    gosub RANGE5_3
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
fout = 40000/prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec FD[3],dec FD[2],dec FD[1],".",dec FD[0],"0","KHz     "
if PORTA.2=0 then goto Sout
pause 50
wend

RANGE5_3:;Special Case 1Mhz to 4MHz
k=3
f=3
while(1)
gosub BTNsel
if f>3 then 
    f= 4
    gosub RANGE5_2
elseif f<0 then 
    f=39
    gosub RANGE5
endif
if PORTA.3=0 then 
    goto SETRange
    a=1
endif
prx = f+1
fout = 40000/prx
gosub DIGIT
lcdout $fe,$80," Frequency Selection:      "    ; MESSAGES
lcdout $fe,$c0,"   ",dec FD[4],".",dec FD[3],dec FD[2],dec FD[1],"MHz     "
if PORTA.2=0 then goto Sout
pause 50
wend
;-------------------------------------------------------------
DIGIT:
for i=0 to 5
    FD[i]= fout dig i
next i
    fent = Fd[2] + FD[3]*10 + fd[4]*100 + fd[5]*1000
return
;---------------------------------------------------------------------

Sout:
PR2=f ;Constant from equation, f is the constant
CCP = 2*prx  ; solving the equation for CCP 16 bits
CCPR1H = CCP.BYTE1;  saving each 8 bits from 16 bits CCP
CCPR1L = CCP.BYTE0;
CCP1CON.7 =1; enabling CCP1 Pwm out
pause 15;
gosub showfrequency
return

showfrequency:
WHILE(1)        ;waiting interrupt
    if PORTA.3=0 then goto SETRange
    pause 50
    lcdout $fe,$80,"Running.... ",0,1,0,1,0,1,2,"   "   ; MESSAGES
    if k=0 then
    lcdout $fe,$c0,"Frequency =",dec fent,".",dec FD[1],dec FD[0],"Hz    "
    elseif k=2 then
    lcdout $fe,$c0,"Frequency =",dec fent,".",dec FD[1],dec FD[0],"KHz    "
    elseif k=3 then
    lcdout $fe,$c0,"   ",dec FD[4],".",dec FD[3],dec FD[2],dec FD[1],"MHz     "
    elseif k=1 then
    lcdout $fe,$c0,"Frequency =",dec fout,"Hz    "
    elseif k=4 then
    lcdout $fe,$c0,"   ",dec FD[3],dec FD[2],dec FD[1],".",dec FD[0],"0","KHz     "
    elseif k=5 then
    lcdout $fe,$c0,"   ",dec FD[3],dec FD[2],dec FD[1],".",dec FD[0],"0","Hz     "
    endif
    pause 250
    lcdout $fe,$80,"Running.... ",1,0,1,0,1,0,3,"   "  ; MESSAGES
    pause 250
wend
return

About the Author

Ricardo Jimenez

Ricardo Jimenez holds a master's degree in electronics from the Instituto Tecnologico de Mexicali. 

Sponsored Recommendations

Comments

To join the conversation, and become an exclusive member of Electronic Design, create an account today!