rocky79
Member level 5
- Joined
- Sep 20, 2010
- Messages
- 83
- Helped
- 1
- Reputation
- 2
- Reaction score
- 0
- Trophy points
- 1,286
- Activity points
- 1,903
Hello
I have been trying to make PWM work on PIC 12f1840 using CCS compiler
Since I am using a 10 bit PWM I am expecting a 1023 level to be close to 100% duty cycle
and 512 to be close to 50%
however I keep getting the wrong PWM duty cycle, at level of 100 I get close to 60% duty cycle. It sounds like I am getting a really low resolution PWM but why?
Here are my PWM settings which should get me a 10 bit PWM
Clock frequency=4Mhz
Pr2=255
TMR2 prescaler=16.
Here is the code:
I have been trying to make PWM work on PIC 12f1840 using CCS compiler
Since I am using a 10 bit PWM I am expecting a 1023 level to be close to 100% duty cycle
and 512 to be close to 50%
however I keep getting the wrong PWM duty cycle, at level of 100 I get close to 60% duty cycle. It sounds like I am getting a really low resolution PWM but why?
Here are my PWM settings which should get me a 10 bit PWM
Clock frequency=4Mhz
Pr2=255
TMR2 prescaler=16.
Here is the code:
Code:
#include <12f1840.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOMCLR
#use delay(clock = 4000000)
#use fast_io (A)
//----------------------------------- ---------
//GPIO BIT ASSIGNMENT FOR I/O REGISTERS PORT A
//--------------------------------------------
//address of the TRISIO registe
#byte TRISA = 0x8C//getenv("SFR:TRISA")
#byte ANSELA = 0x18C//getenv("SFR:ANSELA")
// setting up PWM parameters
#byte PR2=0x1B
#byte T2CON=0x1C
#word CCP1CON=0x293
#bit CCP1CON_4=CCP1CON.4
#bit CCP1CON_5=CCP1CON.5
#word CCPR1L=0x291
#byte PIR1=0x11
#bit PIR1_1=PIR1.1
int16 duty;
#bit duty_0=duty.0
#bit duty_1=duty.1
void pwm(int16 a2d);
void main(void){
int16 i;
//SET UP THE CAPSENSE PINS [RA0-RA1] FOR ANALOG INPUT
ANSELA=0b00000011;
//----------------------manual PWM config--------------------------------
//Disable the PWM pin (CCPx) output driver(s) by
//setting the associated TRIS bit(s) to INPUT
TRISA= 0b00001111;
//Load the PR2 register with the PWM period value.
PR2=255; // 255hz
//Configure the CCP module for the PWM mode
//by loading the CCPxCON register with the
//appropriate values.
CCP1CON=0b00001100; // Set CCP1 PWM active high
//Load the CCPRxL register and the DCxBx bits of
//the CCPxCON register, with the PWM duty cycle
//value.
duty = 0; // set duty cycle to 0
CCP1CON_4 = duty_0; // Store duty to registers as
CCP1CON_5 = duty_1; // a 10-bit word
//store the eight MSbs in CCPR1L.
CCPR1L = duty >> 2; // store the remaining low byte
//clear the TMR21F interrupt flag bit of PIR1 register
PIR1_1=0;
// Set prescaler to 16
T2CON=0b00000110;
//Wait until Timer2 overflows, TMR2IF bit of the
//PIR1 register is set.
wait_for_TMR2IF:
if (PIR1_1 == 0)
{
goto wait_for_TMR2IF;
}
//enable PWM by setting pin to output
TRISA= 0b00001011;
while(1)
{
for(i=0;i<1020;++i)
{
//Output a PWM wave
pwm(i);
delay_ms(2);
}
delay_ms(2000);
}
}
void pwm(int16 a2d)
{
duty=a2d;
CCP1CON_4 = duty_0; // Store duty to registers as
CCP1CON_5 = duty_1; // a 10-bit word
CCPR1L = duty >> 2; // store the remaining low byte}
}