Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

pic16f84 output frequency determine

Status
Not open for further replies.

neazoi

Advanced Member level 6
Advanced Member level 6
Joined
Jan 5, 2008
Messages
4,157
Helped
13
Reputation
26
Reaction score
15
Trophy points
1,318
Location
Greece
www.microwave.gr
Activity points
37,198
Hello I experiment with a 50% duty cycle square wave generator on a pic16f84.
I am using just a pin as a square wave output.

Using a 4MHz crystal, how can I calculate the output frequency?

My goal is to output 135-137KHz square wave signal.




My code is below

Code:
; counter variable

CNT	EQU	16		; uS delay. Modify this, to change frequency

 
Loop
  movlw 1                       ;  Turn on Port A

  movwf PORTA                   ;

  movlw CNT
  call MDELAY			; CNT uS delay
 
  movlw 0                       ;  Turn off the LED on Port A
  movwf PORTA                   ;

  movlw CNT
  call MDELAY			; CNT uS delay 


  goto Loop


; delay for w uS. Set the w register to the desired delay value

MDELAY:
		MOVWF	CNT		;LOAD DELAY TIME

COUNT:		NOP			;TWO NO OPERATIONS
		NOP					;TO OBTAIN THE DELAY
		DECFSZ	CNT,1		;DECREMENT THE COUNTER
		GOTO	COUNT		;GOTO COUNT IF NOT FINNISHED
		RETURN
 
  end
 
Last edited:

movwf takes 1 instruction cycle
call takes 2 instruction cycle


movwf takes 1 instruction cycle
2 nop takes 2 instruction cycle
decfsz takes 1 if result is 1 and 2 if result is 0
goto takes 2 instruction cycle

so to sum up MDELAY takes 54 insctruction cycles now check your clock frequency divide it by four to get your get time for each instruction cycle , multiply with total instructions in a subroutine you will get the time delay for each instruction

Regards
 

You can make a precise 135KHz signal by using TMR0 interupts. At 4MHz clock you want the interrupt to happen at 270KHz rate so you can change output state on alternate interrupts. To do that, you should load TMR0 with 0xFC each time an interupt occurs.

Unfortunately, 137KHz isn't possible to synthesize using ony an 8-bit timer. If you can use a PIC with a 16-bit timer such as the pin compatible 16F628A or 16F1847 it gets a whole lot easier.

The problem with using software loops is you can't do anything else at the same time, if the program flow diverts to cater for something else happening, the number of instructions is almost certain to change and therefore the delays they introduce and the output frequency will also change. Timers are the best solution by far but sadly the rather old 16F84 isn't well equipped with them.

Brian.
 

A convenient way to check (and possibly adjust) execution of loops and also complete subroutines is the MPLAB simulator with it's stop watch.
 

Hi,

As said a simple software loop will give a frequency of 137khz or 136.94878 to be exact. F = 1/T
 

Attachments

  • 000099.jpg
    000099.jpg
    28.2 KB · Views: 78

Another alternative is to use an NCO equipped PIC, this video explains it:
https://www.microchip.com/microchip.webcontent.provider/Video.aspx?id=p4FY9XjpTOo

Unlike timer or loop based control, which provide steps in attainable frequencies, the NCO allows you to tune it's oscillator numerically.

Yet another alternative is DDS which at those frequencies should be possible using a small PIC but that method would be quite complicated to code.

You could also consider a simple PLL, using the PIC to produce a tuning voltage for a VCO and measuring it's frequency back through one of the ports to keep it in lock.

Brian.
 
Thank you all! All the replies have been very helpfull.

I will try the code in #6 to see how it works.

Since only a square wave output is needed (driving a class-E amplifier), I think a DDS is a waste of money and time here. I intend to use this as a local oscillator for a direct upconversion from the PC soundcard. since the 135-137KHz amateur band is only about 2KHz wide, actual mixed output frequency can be adjusted by sending different tones from the sound card.
By lack when trying different crystals, I have found that a 3.27MHz crystal, will output a 136.529KHz square wave signal by simply setting portA and then continuously toggling it (xorwf within a continuous loop). The output is a low distortion square wave when using a 560 ohms in series with a 1M oscilloscope port.
When using a 20MHz crystal with the same code the output goes to about 800KHz but it is more triangle shaped.
 

hello,

The code in post #6 will give HZ not Khz..
with FOSC=4MHz cycle=1µS
you can not get 135 or 137 Khz..
you need to use a higher frequency like 16Mhz => cycle 0.25µS
F=136Khz => 1000000/136000 => 7.353 µS

you need to spend around
29 cycles of MCU to get 137Khz
or 30 cycles to get 133Khz
or 28 cycles to get 142Khz

Use a quartz of 16Mhz for PIC16F84

or you can use a litle PIC DIP8 as PIC12F1840 ,with internal Fosc 16Mhz ( use LATA instead of PORTA)
i did a test for 1Mhz output with this PIC **broken link removed**
and with PLL FOSC=64MHz !

126Khz_asm.jpg
 

hello,

The code in post #6 will give HZ not Khz..
with FOSC=4MHz cycle=1µS
you can not get 135 or 137 Khz..
you need to use a higher frequency like 16Mhz => cycle 0.25µS
F=136Khz => 1000000/136000 => 7.353 µS

you need to spend around
29 cycles of MCU to get 137Khz
or 30 cycles to get 133Khz
or 28 cycles to get 142Khz

Use a quartz of 16Mhz for PIC16F84

or you can use a litle PIC DIP8 as PIC12F1840 ,with internal Fosc 16Mhz ( use LATA instead of PORTA)
i did a test for 1Mhz output with this PIC **broken link removed**
and with PLL FOSC=64MHz !

View attachment 108862

Thank you!
That is what I thought, 4MHz is too low and only a very short code can do this.
The only reason I stick to the 16f84 is that I have read a tutorial about it, whereas I am really novice in other MCUs.

What if I need quadrature output at 135-137KHz?
I have a tolerance of +/-10KHz above or below that range for the quadrature oscillator.

The current solution is to produce a signal using a 13.21MHz and then divide it down using a 74f74 to get two 90deg signals
But if the micro can do it already that would be great. I just cannot get the timings right. :(
 

Quadrature output..
do you means 2 outputs with depahasage 90 between them.
and same frequency!

like this , on pin RA4 and pin RA5?

Code:
 // 133430Hz
    _asm {
    movlb 2
    ICI:
    bsf LATA,4,0  //    0,25    0,25
    nop    //  0,25    0,50
    nop    //  0,25//    0,75
    nop    //  0,25//    1,00
    nop    //  0,25//    1,25
    nop    //  0,25    1,50
    nop    //  0,25    1,75
    bcf LATA,5,1 //    0,25    0,25
    nop    //  0,25    2,25
    nop    //  0,25    2,50
    nop    //  0,25    2,75
    nop    //  0,25    3,00
    nop    //  0,25    3,25
    nop    //  0,25    3,50
    bcf LATA,4,0 //    0,25    0,25
    nop    //0,25    0,50
    nop    //0,25    0,75
    nop    //0,25    1,00
    nop    //0,25    1,25
    nop    //0,25    1,50
    nop    //0,25    1,75
    bsf LATA,5,0 //    0,25    0,25
    nop    //0,25    2,25
    nop    //0,25    2,50
    nop    //0,25    2,75
    nop    //0,25    3,00
    nop    //0,25    3,25
    nop    //0,25    3,50
    BRA ICI    //0,5    4,00
    }  // fin de zone asm
 // boucle indefiniment au dessus !

if not egnouh accurate, you can use PLL .. so 64MHz
cycle=1/16 of µS
 
Last edited:

Quadrature output..
do you means 2 outputs with depahasage 90 between them.
and same frequency!

like this , on pin RA4 and pin RA5?

Code:
 // 133430Hz
    _asm {
    movlb 2
    ICI:
    bsf LATA,4,0  //    0,25    0,25
    nop    //  0,25    0,50
    nop    //  0,25//    0,75
    nop    //  0,25//    1,00
    nop    //  0,25//    1,25
    nop    //  0,25    1,50
    nop    //  0,25    1,75
    bcf LATA,5,1 //    0,25    0,25
    nop    //  0,25    2,25
    nop    //  0,25    2,50
    nop    //  0,25    2,75
    nop    //  0,25    3,00
    nop    //  0,25    3,25
    nop    //  0,25    3,50
    bcf LATA,4,0 //    0,25    0,25
    nop    //0,25    0,50
    nop    //0,25    0,75
    nop    //0,25    1,00
    nop    //0,25    1,25
    nop    //0,25    1,50
    nop    //0,25    1,75
    bsf LATA,5,0 //    0,25    0,25
    nop    //0,25    2,25
    nop    //0,25    2,50
    nop    //0,25    2,75
    nop    //0,25    3,00
    nop    //0,25    3,25
    nop    //0,25    3,50
    BRA ICI    //0,5    4,00
    }  // fin de zone asm
 // boucle indefiniment au dessus !

if not egnouh accurate, you can use PLL .. so 64MHz
cycle=1/16 of µS


Yes two signals 90deg phased out.
This code is for your pic right?
Are you sure it is accurate to the 1 degree? It really matters on I/Q mixers.
 

Yes this code is for 12F1840 (or 18Fxxx)
you must use PORTA for 16F84 , but maxi frequency for 16F84 is less than 64Mhz
maybe up to 20Mhz
(i tried 40Mhz ..without waranty !)
so you better have to change MCU type or find another solution

for safety result
use PLL => 16x4=64Mhz so periode timing can be adjusted +- one cycle of 62.5nS
periode is around 7353 nS
so adjustment could be +-0,8%
if you have exact number of cycle between each bit change
delta will be less than 1°
 
Last edited:

just a suggestion

you will never get it exact you will always be an instruction
cycle or more out, use a DSS, it be better and more stable
the PIC clock is not very stable. and it could be any thing
unless you adjust it some how.
 

just a suggestion

you will never get it exact you will always be an instruction
cycle or more out, use a DSS, it be better and more stable
the PIC clock is not very stable. and it could be any thing
unless you adjust it some how.

Yes, that is what I thought. In his example, the NOP (which I have tried in mine too) can never achieve perfect matched cycle, and the lots of NOPs dectease the max frequency.

As I said, what I have done now, is I have used the PIC to produce a divided-down frequency and then I have used a 74F74 to divide it down by 4 and in 4 different phases. This way the 4-phases track the incomming signal and the 90deg phase shift is maintained.
Maybe the PIC is not needed as simple TTL could be used for the first division, is one frequency is required.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top