Page 1 of 1
PWM8 with OutputCapture on mega328p
Posted: 10 January 2013, 14:23 PM
by jay
Reworking a old project (another IR vacation TV timer) that uses a ZX40 for scheduling and PWM to generate the IR command data stream. A PIC12F683 generated the carrier freq as gated by the PWM stream and controls the LEDs. I thought I'd move to a zx-328n, use the PWM as before, then use a PWM8 to generate the carrier. It doesn't appear that I can use the PWM8 to generate carrier frequencies (~37kHz for some devices and ~58kHz for others).
OutputCapture uses Timer 1 PWM8 uses Timer 2 so there would be no conflict, but as I read it, PWM8 can only generate a set of base frequencies.
I would like to remove the PIC, but don't understand how.
Any suggestions?
Thanks
Re: PWM8 with OutputCapture on mega328p
Posted: 10 January 2013, 16:58 PM
by dkinzer
jay wrote:[A]s I read it, PWM8 can only generate a set of base frequencies.
That is true but you needn't use the timer in PWM mode to generate a simple square wave. The code below sets up Timer2 in CTC (Clear on Timer Compare) mode. In this mode the timer counts from zero up to N and then resets to zero. The second part of the configuration is to set the COM2xN bits to toggle the output compare pin on every compare match - the frequency of the compare match must, therefore, be twice the desired frequency.
For the two frequencies mentioned, I concluded that the timer's prescaler must be set to divide-by-1. The expression giving the OCR2A value should be easily understood if you realize that the OCR2A register gives the value of N, the +1 in the middle combined with the subsequent division by 2 implements rounding, and the final -1 accounts for the fact that a counter has N states when counting from 0 to N-1. The resulting frequencies are 37.04KHz and 58.14KHz when operating at 14.74 MHz.
Code: Select all
Const frequency as UnsignedLong = 58000
Const prescaler as UnsignedLong = 1
#if Option.TargetDevice = "ZX24n"
Const pin as Byte = D.7
#elseif Option.TargetDevice = "ZX328n"
Const pin as Byte = B.3
#else
#error need OC2A pin for target device
#endif
Sub Main()
' set up Timer2 to generate a square wave on OC2A
Register.OCR2A = CByte(((Register.CPUFrequency \ prescaler \ frequency) + 1) \ 2 - 1)
Register.TCCR2A = &H42 ' set OC2A to toggle on compare
Register.TCCR2B = &H01 ' set prescaler to divide-by-1, CTC mode
Call PutPin(pin, 0)
End Sub
Note that if the OC2A pin isn't convenient to use, you could configure the timer to toggle the OC2B pin. How to accomplish this is left as an exercise for the interested reader.
For more information on how AVR timers work and how to configure them in various modes, see
Dean Camera's AVR Timer Tutorial.
Posted: 10 January 2013, 17:14 PM
by jay
Don thanks so much. I was starting to think about putting a pic back in..
Also, thanks for the pointer to Dean's articles. Some good late night reading.
Best regards,
..jay