PIC16F628A Software PWM

Thread Starter

odm4286

Joined Sep 20, 2009
243
Hello everyone, is it possible to achieve a 2Khz freq with a standard output pin on the PIC16F628A? My pcb design is pretty set in stone and the peizo buzzer is already tied to RB4. Thanks in advance!

Almost forgot, running at 4Mhz
 
Last edited:

jpanhalt

Joined Jan 18, 2008
8,314
Yes, it can be done, and I have done it at even higher frequencies. Something to consider is that while doing software PWM, you will either be occupying the PIC fully generating the signal, be using carefully timed loops, or be using an interrupt driven routing (say off TMR2) . The latter is relatively easy to do in Assembly language, as the timing can be critical. Remember, 2 kHz is 500 us per cycle, and you can do a lot of processing between having to set or clear your output pin.

The advantage of using hardware PWM is that it effectively multitasks the MCU. That is, the PWM runs by itself and the MCU can do other things until it needs to change the PWM.

John

Edit: 03.08.16 Changed "pulse" to "cycle" and "pulse" to "output pin." What I intended was not what my fingers typed.
 
Last edited:

Thread Starter

odm4286

Joined Sep 20, 2009
243
Yes, it can be done, and I have done it at even higher frequencies. Something to consider is that while doing software PWM, you will either be occupying the PIC fully generating the signal, be using carefully timed loops, or be using an interrupt driven routing (say off TMR2) . The latter is relatively easy to do in Assembly language, as the timing can be critical. Remember, 2 kHz is 500 us per pulse, and you can do a lot of processing between having to set or clear your pulses.

The advantage of using hardware PWM is that it effectively multitasks the MCU. That is, the PWM runs by itself and the MCU can do other things until it needs to change the PWM.

John
Thanks for the info. Yes I am a little worried about the lack of "multitasking" but I should be fine. I just need to generate an alarm with the peizo, flash some lights, and dump a byte in the TXREG. So even if have to "alarm" for 1.5 seconds, then flash my light, handle TXREG, and repeat, I am OK with that.

Funny I didn't notice until I already placed my PCB order. Since this iteration was already tested I didn't want to cancel the order and start moving things around when I could accomplish the same with software. You a live and you learn I guess ;)
 

John P

Joined Oct 14, 2008
1,780
You can make a virtue out of this 2KHz tone. You need to set up an interrupt at a 4KHz rate, and use no other interrupts. Then when you service the interrupt, test for whether the beeper is sounding, and if so, complement the output (note 4KHz not 2KHz, as the output has to go both high and low in 1/2000 sec). Also decrement the count representing the time that the beeper is on.

Then you have the option of checking for anything else that the processor might need to do, like drop a character into the UART's buffer or decide whether lights should be on or off. You could do these things directly in the interrupt, or you could set a flag (I always call it "tick") and return to the main() routine. Then if the flag is found to be set you clear it, and do all those things in main() instead. For simple designs, it's pretty much a judgment call which approach to take.
 

JohnInTX

Joined Jun 26, 2012
3,900
You can make a virtue out of this 2KHz tone. You need to set up an interrupt at a 4KHz rate, and use no other interrupts. Then when you service the interrupt, test for whether the beeper is sounding, and if so, complement the output (note 4KHz not 2KHz, as the output has to go both high and low in 1/2000 sec). Also decrement the count representing the time that the beeper is on.

Then you have the option of checking for anything else that the processor might need to do, like drop a character into the UART's buffer or decide whether lights should be on or off. You could do these things directly in the interrupt, or you could set a flag (I always call it "tick") and return to the main() routine. Then if the flag is found to be set you clear it, and do all those things in main() instead. For simple designs, it's pretty much a judgment call which approach to take.
+1 The approach John P describes is a good one and was used in these threads to do just that - including the software PWM to drive the beeper. Lots of stuff to wade through in the threads but it's in there.

http://forum.allaboutcircuits.com/threads/pic-12f629-question.116963/
http://forum.allaboutcircuits.com/threads/sla-charger-backup-system.119454/
 
Top