## 50Hz square wave example for PIC16F1829

This post presents two example programs for the PIC16F1829 microcontroller that generate 50Hz square waves. The first example uses simple bit banging to generate the waveform. The second example uses the dedicated PWM hardware module.

### Example 1: bit banging

In this example program, I set a single pin as a digital output (RC5), then generate a 50Hz square wave using straightforward bit banging.

The clock oscillator is left at its default frequency of Fosc = 500kHz. Therefore, the oscillator period Tosc = 2us. Since the PIC16F1829 performs one machine instruction every four oscillator cycles, the instruction cycle, Tcy = 8us.

//
// PIC16F1829 50Hz 50% duty cycle example program
// Written by Ted Burke (http://batchloaf.com)
// Last updated 5-6-2013
//
// To compile with XC8:
//     xc8 --chip=16F1829 main.c
//

#include <xc.h>

// Select the internal oscillator (default Fosc = 500kHz, which gives
// an instruction cycle Tcy = 8us), disable low voltage programming,
// disable reset pin, disable watchdog timer
#pragma config FOSC=INTOSC,LVP=OFF,MCLRE=OFF,WDTE=OFF

int main(void)
{
// Make RC5 a digital output
TRISCbits.TRISC5 = 0;

// Now just switch RC5 high and low repeatedly
while(1)
{
LATCbits.LATC5 = 1; // Set RC5 high
_delay(1250); // 10ms delay @ Fosc = 500kHz, Tcy = 8us
LATCbits.LATC5 = 0; // Set RC5 low
_delay(1250); // 10ms delay @ Fosc = 500kHz, Tcy = 8us
}

return 0;
}


I don’t have a PIC16F1829 to try this out on, so the best I could do was test it using MPLAB SIM (the simulator in MPLAB v8.50). Here’s a screenshot I captured of the Simulator Logic Analyzer tool (under the View menu in MPLAB) displaying the generated waveform.

The x-axis units in the figure above are instruction cycles, so the period of the generated signal is approximately 2500 instruction cycles.

$\textrm{frequency} = \frac{1}{2500 \times 8 \times 10^{-6}} = 50 \textrm{Hz}$

Careful examination of the waveform in the figure above reveals that the period is actually not precisely 2500 instruction cycles. This may be due to the overhead associated with the additional instructions caused by the while loop and bit-banging. If precision is required, the delay values could be carefully tweaked to compensate. However, it is worth bearing in mind that the frequency of the internal RC oscillator can vary, so if precision is required an external crystal oscillator might be a better choice.

### Example 2: using the PWM module

Here’s another example of a 50Hz square wave. This time, the PWM module is used:

//
// PIC16F1829 50Hz 50% duty cycle example program
// Written by Ted Burke (http://batchloaf.com)
// Last updated 7-6-2013
//
// To compile with XC8:
//     xc8 --chip=16F1829 main.c
//

#include <xc.h>

// Select the internal oscillator (default Fosc = 500kHz, which gives
// an instruction cycle Tcy = 8us), disable low voltage programming,
// disable reset pin, disable watchdog timer
#pragma config FOSC=INTOSC,LVP=OFF,MCLRE=OFF,WDTE=OFF

int main(void)
{
// Set up PWM
T2CON = 0b00000111;   // Enable TMR2 with prescaler = 64
PR2 = 155;            // PWM period = (PR2+1) * 64 * Tcy = 19.968ms
CCPR1L = 78;          // pulse width = CCPR1L * 64 * Tcy = 9.984ms
CCP1CON = 0b00001100; // Enable PWM on CCP1
TRISCbits.TRISC5 = 0; // Make CCP1 pin an output

// Now just do nothing while PWM module does the work
while(1);

return 0;
}


Configuring the PWM module is a little more complicated than just bit banging to generate the signal. However, it has (at least) two very important benefits:

1. The program can get on with other tasks while the square wave is generated continuously in the background by the dedicated PWM hardware module.
2. Since there are no extra instructions associated with a while loop or anything else, it’s much easier to determine the exact length of the waveform period and pulse width (measured in instruction cycles).
This entry was posted in PIC and tagged , , , , , , , , , , , . Bookmark the permalink.

### 9 Responses to 50Hz square wave example for PIC16F1829

1. help says:

Haha… actually i already have did the “lazy way” as you do and i got the same result.
But after i saw your post, what i willing to have, is learn a different method to get the 50Hz via your way. It look more “Advanced”.
So, you have to be hardworking to teach me here. (^_^)

• batchloaf says:

Ok, I’ll try to add another example using the PIC’s hardware PWM generator. I don’t think I’ll have time to do it today though.

2. help says:

Hardware?
not we could just use the Proteus for the simulation?

• batchloaf says:

Yes, you can probably simulate it in Proteus (although I haven’t used that software myself). The real PIC has dedicated hardware for generating PWM signals very precisely in the background while your C program is getting on with other tasks. Proteus can probably simulate that hardware functionality, but when you run it on the real system, the PWM will be generated by dedicated hardware on the chip.

When I said about using the dedicated hardware to generate the squarewave, that was in contrast to the bit banging approach – writing a loop to set a digital output pin equal to 0, 1, 0, 1, 0, 1,… etc.

Hopefully my example which I will post soon will clarify the difference.

• batchloaf says:

Ok, I added in another example. This time I used the PWM hardware module, which is probably a better idea in the long run. Let me know if you have any questions.

Ted

3. Help says:

it take me few days to understand the code.
it really advanced than the previous, as a newbie , I learned new thing : )
thank you VERY much, if I have somemore question i’m will back here again.
THANKS!!

• batchloaf says:

You’re very welcome! Best of luck getting whatever you’re working on finished.

Ted

4. bala says:

Can anybody give me circuit diagram for pwm square wave generator i want to control a bldc motor with this… Thanks in advance

5. John says:

Hey I am using a PIC 16F1829 and I want to determine the frequency of an incoming square wave how would I go about this. I am trying to use the ccp_capture_div_16 but the code it proving to be difficult can you help?
Thanks,