0% found this document useful (0 votes)
83 views3 pages

PIC16F877A PWM Demo Program

This document contains a C program that demonstrates the use of the PWM module on a PIC16F87x microcontroller. It allows the user to select the PWM period, prescaler, and duty cycle via serial input. The program then configures Timer 2 and the CCP modules to generate PWM outputs with the specified parameters.

Uploaded by

André Aleixo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
83 views3 pages

PIC16F877A PWM Demo Program

This document contains a C program that demonstrates the use of the PWM module on a PIC16F87x microcontroller. It allows the user to select the PWM period, prescaler, and duty cycle via serial input. The program then configures Timer 2 and the CCP modules to generate PWM outputs with the specified parameters.

Uploaded by

André Aleixo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

//

// demopwm.c
//
// Description: Demonstration of use of the PIC16F87x PWM module.
//
// Based on EX_PWM.C CCS example program
//
// Author: Martin Dubuc
//
// Creation date: December 20, 2003
//

#include <16f877A.h>

#ORG 0x1F00,0x1FFF {} /* Reserve memory for bootloader for the 8k 16F876/7 */

//#device PIC16F877A *=16 /* Allow RAM to expand beyond 256 bytes */

#device adc=10 /* Make sure that we are sampling on 10 bits. This directive
is required for compiler version 2.7. */

/* Set the clock speed */


#use delay(clock=20000000)
#fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP

/* Directive for RS-232 interface */


#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include "input.c"

#define VARIABLE_PERIOD 1 // If this symbol is defined, let the user select the
// period and prescaler, otherwise,
// if VARIABLE_PERIOD = 0, use fixed values.

main() {
char selection;
byte duty, period;
byte prescale;

// We use serial input to capture PWM parameters to make


// an easy demo.

setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM


setup_ccp2(CCP_PWM); // Configure CCP1 as a PWM

#if VARIABLE_PERIOD // This is default


for ( ; ; ) {
// Select value for the period (100% duty cycle)
printf("Period (100%% duty cycle): ");
period = gethex();
printf("\r\n");

// Set the prescaler


do {
// Select prescaler (t2div)
printf("\r\nSelect prescaler:\r\n");
printf(" 1: Prescaler = 1\r\n");
printf(" 2: Prescaler = 4\r\n");
printf(" 3: Prescaler = 16\r\n");
printf("Selection: ");
selection = getc();
putc(selection);
printf("\r\n");
} while((selection < '1') || (selection > '3'));

// The cycle time will be (1 / clock) * 4 * t2div * (period + 1)


// In this program, if period is 0x80 (or 128 decimal), with
// a clock of 20000000:
// For the three possible prescaler selections the cycle time is:
// (1/20000000) * 4 * 1 * 128 = 25.6 us or 39 khz
// (1/20000000) * 4 * 4 * 128 = 102.4 us or 9.8 khz
// (1/20000000) * 4 * 16 * 128 = 409.6 us or 2.4 khz

switch(selection) {
case '1':
prescale = 1;
setup_timer_2(T2_DIV_BY_1, period, 1);
break;
case '2':
prescale = 4;
setup_timer_2(T2_DIV_BY_4, period, 1);
break;
case '3':
prescale = 16;
setup_timer_2(T2_DIV_BY_16, period, 1);
break;
}

#else
period = 0x80;
prescale = 4;
setup_timer_2(T2_DIV_BY_4, period, 1);
#endif

printf("Frequency = %ld kHz\r\n", 5000 / period / prescale);

while(TRUE) {
printf("Enter duty cycle: ");
duty = gethex();
printf("\r\n");

// Set the duty cycle


set_pwm1_duty(duty);
set_pwm2_duty(duty); // This sets the time the pulse is
// high each cycle.
// If period is 128 (or '80' hex),
// a value of 64 (or '40' hex) will set
// the duty cycle to 50%, i.e.
// the pulse is high 50% of time.
// WARNING: A value too high or low will
// prevent the output from
// changing. A value too high
// will make the CCPx high
// at all times.
if (duty == 0x10) { // If '10' is entered for duty, exit loop to be able to
// select other values for period and prescaler
break;
}
}
}
}

You might also like