Kenny
Joined: 07 Sep 2003 Posts: 173 Location: Australia
|
|
Posted: Mon Sep 08, 2003 8:59 pm |
|
|
If you want to do it in hardware to reduce overhead on the processor then it can be done with timer 1 and Compare.
Basic idea is to setup timer 1 to generate an overflow interrupt.
In the overflow interrupt service routine set a port pin high. When a compare match occurs, set the port pin low in the service routine for the compare match.
With 4Mhz and prescaler of 1, timer1 is counting Fosc/4 (1uS) so time to overflow is .065 seconds or about 15Hz.
You would need to go to a higher crystal frequency for higher pwm frequency with this method though. My earlier post was incorrect, sincere apologies.
The way around this limitation for 4MHz clock is to load a value into timer 1 when it overflows so that it takes less time to get to overflow. Eg for 100Hz pwm would need to load 55,535 (10,000 uS to overflow), and for 50% duty cycle add 1/2 the time for compare
ie. 55,535 + 5000 = 60,535.
Example sweeps pwm up and down. Changes for 100Hz pwm not added.
#include <16F877.h>
#fuses HS,NOWDT,PUT,NOLVP
#define PWM_OUT PIN_C0
#int_timer1
t1_isr() {
output_bit(PWM_OUT,1);
}
#int_CCP1
CCP1_isr() {
output_bit(PWM_OUT,0);
}
void main(void)
{
short tog_fl = 1;
// 1uS increments
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_ccp1(CCP_COMPARE_INT);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_CCP1);
enable_interrupts(global);
CCP_1 = 0;
while (1) {
disable_interrupts(global);
if (tog_fl) {
if(++CCP_1 == 0xffff) tog_fl = 0;
}
else if(--CCP_1 == 0x1) tog_fl = 1;
enable_interrupts(global);
delay_us(100);
}
} |
|