Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
LinkBack Thread Tools Display Modes
Old 15th May 2004, 11:13 AM   (permalink)
Default PIC 50Hz square

Hi,

I'm building a power inverter that needs a high frequency clock at about 25Khz and a low frequency one at 50Hz. I have access to various crystal speeds, and as the choice of high frequency is not vital I can see how by choosing prescaler values I can use TMR0 to give me a suitable square wave to control my bridge. However, the 50Hz output is causing more problems - it needs to be exact, but crystal speed divided by 4 divided by 256 divided by prescaler doesnt equal 50 for any crystal/prescaler combination! I realise I could use a simple op-amp and cap/resistor network to get a 50Hz square wave, but I'm hoping to be able eventually to get the PIC to give me a nice quasi sine wave (square wave with deadtime). However, If I can't get the frequency right this is a non-starter!As is probably evident, I am very innexperienced with the PIC, so any advice would be very welcome.
barkerben is offline  
Old 15th May 2004, 01:48 PM   (permalink)
Default

I don't think you really need to get exactly 50hz. An output within 1% would be good enough. A crystal controlled PIC will give a closer frequency match than any op-amp based RC oscillator. Nevertheless, it is possible to get exactly 50Hz. Using the low cost PIC16F627:

First, initialize timer 2 control register T2CON, to 1:1 prescale and 1:2 postscale+TMR2ON = b'00001100'.

Second, setup PIC to generate a 25Khz PWM signal. Assuming, you use a 4Mhz PIC16F627, initialize the period register PR2 with the value D'39'. The period is therefore equal to (39+1)*4*250nsec=40usec. Configure the CCP1 module for PWM operation. Follow the steps outlined in section 10.3.3 of the PIC16F627 datasheet.

Third, enable timer2 interrupts by setting TMR2IE bit in PIE1 as well as GIE and PEIE in INTCON. Interrupts will be generated every 80usec because of the 1:2 postscale. In the interrupt service routine (ISR), toggle any desired output pin every 125 interrupts to generate the 50Hz signal. The PWM duty cycle can also be modulated during the ISR.

The interrupt service routine is limited to 80 instructions when using a 4Mhz crystal but this may be sufficient. Or you can use a faster crystal up to 20Mhz. A faster PIC will also give a finer resolution PWM signal.
__________________
"Having to do with Motion Control"
motion is offline  
Old 15th May 2004, 02:20 PM   (permalink)
Default

was just thinking of something.

Say I want a 100hz signal purely based on tmr0. Say I scale tmr0 this way: 4Mhz/4/256 = 3906hz. So if I count tmr0 a hundred times. that would be 100hz? or 3906/100 = 39 tmr0 pulses.

Edit: 1/3906 = 256µs - this makes sense as one instruction = 1µs and prescaler is 256 and it takes this long for a timer overflow.

So, 1/100 = 0.01s (period) of 100hz, and 0.01/256x10^-6 = 39.06.

Sweetness.....

So what I've been doing so far is taking 105(pulses) too = 105hz >> WRONG


1/(105*256x10^-6) = 39hz, :lol: :lol:

This solves my problem
__________________
"Ambition is the last refuge of failure..." --Oscar Wilde
"Success is not final, failure is not fatal: it is the courage to continue that counts." -- Winston Churchill
bsodmike is offline  
Old 15th May 2004, 02:55 PM   (permalink)
Default Thanks - one more question

Thanks for that. One quick question though:

Interrupts are generated every 80 uS, and the interrupt routine can be used to send whatever pins wanted to high or low as needed. While the interrupt routine is being processed, is the counter still counting ready for the next interrupt, or does the interrupt routine stop this. If the counting stops when the interrupt is being processed, then presumably the length of the interrupt code will affect the frequency...? Sorry to be so slow, your help is much appreciated.

Cheers,

Ben
barkerben is offline  
Old 15th May 2004, 03:16 PM   (permalink)
Default Re: Thanks - one more question

Quote:
Originally Posted by barkerben
Thanks for that. One quick question though:

Interrupts are generated every 80 uS, and the interrupt routine can be used to send whatever pins wanted to high or low as needed. While the interrupt routine is being processed, is the counter still counting ready for the next interrupt, or does the interrupt routine stop this. If the counting stops when the interrupt is being processed, then presumably the length of the interrupt code will affect the frequency...? Sorry to be so slow, your help is much appreciated.
I've not played with timers very much, but as far as I'm aware the timer keeps going, but it's interrupt enable flag is turned OFF - part of your interrupt routine should turn the flag back on. Usually, the interrupt routine will also reload the required start value back into the timer - although if the timer is simply free running, you don't need to do this.

Here's the line from a timer2 routine which resets the flag:
Code:
        BCF PIR1,TMR2IF 	; Clear flag and continue.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is offline  
Old 15th May 2004, 03:44 PM   (permalink)
Default Re: Thanks - one more question

Quote:
Originally Posted by barkerben
Thanks for that. One quick question though:

Interrupts are generated every 80 uS, and the interrupt routine can be used to send whatever pins wanted to high or low as needed. While the interrupt routine is being processed, is the counter still counting ready for the next interrupt, or does the interrupt routine stop this. If the counting stops when the interrupt is being processed, then presumably the length of the interrupt code will affect the frequency...? Sorry to be so slow, your help is much appreciated.

Cheers,

Ben
The timer2 counts up continuously and automatically resets to zero once timer0 is equal to the PR2 value regardless whether interrupts are enabled or not. It proceeds on counting while servicing interrupts. The only way to stop timer2 is to clear TMR2ON bit.

TMR2IE is not disabled (cleared) by the interrupts. GIE is cleared during interrupts but is restored automatically with the RETFIE instruction. You only have to clear TMR2IF in the ISR as Nigel has suggested.

This is a more accurate way of generating periodic interrupts rather than using timer0 and reloading timer0 in the ISR. Writing to timer0 to set the delay clears the prescale registers and this results in small errors in timing. This old technique applies to the PIC16F84 because it's the only timer available.
__________________
"Having to do with Motion Control"
motion is offline  
Old 15th May 2004, 05:30 PM   (permalink)
Default

Unfortunately I only have access to a PIC16F84A, Maplins seem to be out of any others for the moment. I am fiddling with a piece of code, but have a question. I want to, if possible, generate a number of signals:

a high frequency square wave (exact f not important, but 20-30Khz) and its inverse (although could invert outside the pic)

2 50Hz square waves with duty cycles and phase shifts such that subtracting the two gives a quasi sine wave (a 50Hz square wave with deadtime)

Am I right in thinking that I can't, for instance, set pin 6 high, but have to set the entire port to a value? This seems to complicate things, as to change just one pin I have to take a copy of current outputs, modify the desired bit, then set the new outputs...
barkerben is offline  
Old 15th May 2004, 06:05 PM   (permalink)
Default

Quote:
Originally Posted by barkerben
Am I right in thinking that I can't, for instance, set pin 6 high, but have to set the entire port to a value? This seems to complicate things, as to change just one pin I have to take a copy of current outputs, modify the desired bit, then set the new outputs...
You can! Just do...

BSF PORTB,6

You may need to modify that for whatever pin 6 is on your PIC.
__________________
Dave Pusey.
PIC Programming Tutorials: http://www.mstracey.btinternet.co.uk...al/picmain.htm
Brilliant PIC Simulator: http://www.oshonsoft.com/pic.html
davepusey is offline  
Old 15th May 2004, 07:09 PM   (permalink)
Default

Quote:
Originally Posted by davepusey

You can! Just do...

BSF PORTB,6

You may need to modify that for whatever pin 6 is on your PIC.
Exactly, and to generate it's inverse (on pin 5) just do this:

Code:
BSF   PORTB, 6
BCF   PORTB, 5
.
.
;and later on, for the other change.
.
.
BCF   PORTB, 6
BSF   PORTB, 5
As easy as that.
__________________
PIC programmer software, and PIC Tutorials at:
http://www.winpicprog.co.uk
Nigel Goodwin is offline  
Old 15th May 2004, 09:11 PM   (permalink)
Default And again ...

Sorry about this - thanks for being so helpful.

I've been trying to calculate the values to put into the PWM duty cycle registers, and getting in a bit of a mess. I am looking for 50% duty cycle,
and have to fill the whole of CCPR1L and bits 4 and 5 of CCP1CON.

Duty_cycle = registervalue * Tosc * TMR2_prescale

registervalue= Duty_cycle/(Tosc * TMR2_prescale)

registervalue=(1/2*(1/25,000))/(4,000,000 * 39)

=1.28 * 10^-13

Somethings gone wrong somewhere ...!
barkerben is offline  
Old 15th May 2004, 10:08 PM   (permalink)
Default Final posting..... (promise!)

Hello again. I've put together a piece of code that I hope will make my PIC output two square waves, at 50Hz and at 25Khz - thanks to Nigel for advice on that!

The only thing I can't work out as yet is what to initialise the duty cycle registers to. I won't have a chance to try out the code until Monday, but if any kind hearted person wants to have a look at my handiwork, it is up at:

http://www.srcf.ucam.org/~dbrb2/oscillator

This is my first PIC program, so I am slightly worried it might be completely wrong, and any critiscism would be very welcome!

Cheers,

Ben
barkerben is offline  
Old 15th May 2004, 10:28 PM   (permalink)
Default I think I've found out how to initialise the duty cycle reg.

If:

PWM duty cycle = (register value) * Tosc * (TMR2 prescale value)

At 25Khz, duty cycle = T/2 = (25000*2)^-1

Tosc = 1/(4,000,000)

TMR2 prescale = 39

thus register value = 200

200=b'11001000'

So bits 4 and 5 of CCP1CON = 0 and the rest of the sequence fills CCPR1L
barkerben is offline  
Old 16th May 2004, 01:18 AM   (permalink)
Default

I had a quick glance at your code and I would like to recommend a few optimizations:

Code:
isr	
	decfsz	interrupt_count, F	
	goto	end_isr
;
	movlw	d'125'	
	movwf	interrupt_count	
;
	movlw   slow_toggle         ;slow_toggle is defined under 'constants' 
	xorwf   PORT_B,W	      ; get the inverse of the slow toggle pins and save in W reg
	andwf	PORTB,F         ; First turn OFF the pins with "0" bits
	nop		     ; insert as many dead instructions as necessary
	iorwf	PORTB,F         ; Then turn ON the pins with "1" bits       

end_isr	bcf	PIR1,TMR2IF   	;end isr, resetting interrupts
	retfie
__________________
"Having to do with Motion Control"
motion is offline  
Old 16th May 2004, 09:03 AM   (permalink)
Default Thanks

Thanks

I couldn't use the nop methid to get my phaseshift as I would need to many to fi in my interrupt (about 3000). However, by using another variable initialised at startup to a positive value, but decremented just like my interrupt counter, I can arrange for them to reach 0 at different times, and so produce my out of phase signals.

The modified code is up at:

http://www.srcf.ucam.org/~dbrb2/oscillator

Thanks for all your help - hopefully when I get this code to a PIC it will
work... in the end!


Cheers,

Ben
barkerben is offline  
Old 16th May 2004, 10:14 AM   (permalink)
Default Oh dear...

I ran the code through a simulator, and for some reason interrupts never seem to occur. I cant work out what is going wrong... (hair pulling time)!
barkerben is offline  
Reply

Bookmarks

Thread Tools
Display Modes





All times are GMT. The time now is 06:39 AM.


Electronic Circuits  |  Learning Electronics
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.

eXTReMe Tracker