ARandomOWl
New Member
Hello,
I am writing a program using the C18 compiler to do software PWM. It is working for the most part. Although I am having problems stopping the output from going low if the duty cycle is 255.
Here is my code:
I separated the PWM2 if statements to check I wasn't going crazy. The pins always go low unless I comment out "PWM2_PIN = 0;", which obviously breaks the code for any duty cycle which is not 255.
Here is my configuration, not that it should be relevant.
Can anyone see a mistake?
I am writing a program using the C18 compiler to do software PWM. It is working for the most part. Although I am having problems stopping the output from going low if the duty cycle is 255.
Here is my code:
Code:
/*
* File: main.c
* Author: Adrian Wheeldon
*
* Created on 28 July 2012
*/
#include <p18f2458.h>
#include "config.h"
void high_isr (void);
void low_isr (void);
char pwm_count = 0; // PWM interrupt cycle counter
volatile char pwm1_dc = 255; // Initial duty cycles
volatile char pwm2_dc = 255;
#pragma code high_vector = 0x08
void jump_int_high (void) {
_asm GOTO high_isr _endasm
}
#pragma code low_vector = 0x18
void jump_int_low (void) {
_asm GOTO low_isr _endasm
}
#pragma code
#pragma interrupt high_isr
void high_isr (void) {
// Check TMR2 interrupt enable and flag
if (PIE1bits.TMR2IE == 1 && PIR1bits.TMR2IF == 1) {
if (pwm_count == 0) { // If this is the beginning of the cycle, set outputs high
if (pwm1_dc != 0) PWM1_PIN = 1; // Unless DC is zero
if (pwm2_dc != 0) PWM2_PIN = 1;
}
else {
if (pwm_count == pwm1_dc && pwm1_dc != 255) PWM1_PIN = 0; // Set output low if current cycle equals required DC
if (pwm_count == pwm2_dc){
if (pwm2_dc != 255){
PWM2_PIN = 0;
}
}
}
pwm_count ++; // Increment period counter
PIR1bits.TMR2IF = 0; // Clear TMR2 flag
}
}
#pragma interruptlow low_isr
void low_isr (void) {
}
void setup (void) {
PORTA = 0x00; // Clear ports
ADCON1 = 0x0F; // set up PORTA to be digital I/Os
TRISA = 0x00; // set up all PORTA pins to be digital outputs
// Enable interrupts
INTCON = 0xC0; // Set GIE<7> and PEIE<6>
RCONbits.IPEN = 0; // Disable interrupt priorities
PIE1bits.TMR2IE = 1; // Enable TMR2/PR2 match interrupt
PR2 = 10; // Set PR2 pre-load (236 for ~250kHz)
T2CON = 4; // Start TMR2, no prescale, no post-scale
}
void main (void) {
setup ();
while (1){
//pwm1_dc = 230;
}
}
I separated the PWM2 if statements to check I wasn't going crazy. The pins always go low unless I comment out "PWM2_PIN = 0;", which obviously breaks the code for any duty cycle which is not 255.
Here is my configuration, not that it should be relevant.
Code:
/*
* File: config.h
* Author: Adrian Wheeldon
* Desc.: Configuration Bits
*
* Created on 29 July 2012, 16:00
*/
#ifndef CONFIG_H
#define CONFIG_H
#define PWM1_PIN PORTAbits.RA0 // Pins for PWM channels
#define PWM2_PIN PORTAbits.RA1
#pragma config PLLDIV = 5 // For 20MHz XTAL
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // USB clock source comes from the 96 MHz PLL divided by 2
#pragma config FOSC = HSPLL_HS // HS oscillator, PLL enabled (HSPLL)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor disabled
#pragma config IESO = OFF // Oscillator Switchover mode disabled
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config VREGEN = ON // USB voltage regulator enabled
#pragma config WDT = OFF
#pragma config CCP2MX = OFF // CCP2 input/output is multiplexed with RB3
#pragma config PBADEN = OFF // PORTB<4:0> pins are configured as digital I/O on Reset
#pragma config LPT1OSC = OFF // Timer1 configured for higher power operation
#pragma config MCLRE = ON // RE3 input pin enabled; MCLR pin disabled
#pragma config LVP = OFF
#endif /* CONFIG_H */
Can anyone see a mistake?