View previous topic :: View next topic |
Author |
Message |
theasus
Joined: 31 May 2009 Posts: 79
|
A question about PWM setting |
Posted: Mon Nov 08, 2010 3:14 am |
|
|
I couldn't set PWM duty cycle as %100. I wrote these codes for this operation. (Version 4.108)
Code: |
#include <PIC12F683_registers.h>
pr2=50;
t2con=0b00000100;
ccp1con=0b00001100;
CCPR1L=50; //Also I have tried 49,51 |
Also I have tried:
Code: |
setup_timer_2(T2_DIV_BY_ 1, 49, 1);
set_pwm1_duty(49); //Also I have tried 49,51
setup_ccp1(CCP_PWM);
|
But I couldn't get exactly %100 duty cycle PWM. Do you have any idea? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Nov 08, 2010 3:46 am |
|
|
The problem here is the extra two bits.....
The PWM, has eight bits held in the period register, and then two more bits in the configuration register. These are only updated if you send a 'long' value to the setup. Otherwise the 'old' value gets left in these extra bits. So, if you just update the period register, you will only get (in your case) to a maximum PWM on time of 196/200.
So:
Code: |
setup_timer_2(T2_DIV_BY_ 1, 49, 1);
set_pwm1_duty(200L); //Sets all ten bits
set_pwm1_duty(0L); //To get back to 'zero'
|
To do it with the registers, you would need to set bits 5, and 4, in CCP1CON.
Best Wishes |
|
|
theasus
Joined: 31 May 2009 Posts: 79
|
|
Posted: Thu Nov 11, 2010 1:03 am |
|
|
I changed CCP1CON as you said but I couldn't set PWM duty cycle as %100. These are my codes:
Code: |
pr2=50;
t2con=0b00000100;
ccp1con=0b00111100;
CCPR1L=50;
|
|
|
|
theasus
Joined: 31 May 2009 Posts: 79
|
|
Posted: Thu Nov 11, 2010 1:28 am |
|
|
Also I want to ask a simple question but I couldn't find anywhere.
We can set PWM like this:
Code: | set_pwm1_duty(200L);
|
But we can't use this code instead of them:
Code: | a=100;
set_pwm1_duty(aL);
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Nov 11, 2010 2:52 am |
|
|
If 'a' is a long variable (int16), then it'll already work right.
To change a short variable to a long, you use a 'cast', so:
Code: |
a=200;
set_pwm1_duty((int16)a);
|
No, you can't append an 'L' to a variable to change it into a long. The second line in your code, is trying to use a variable, called 'aL'. Using 'L' to force a value to be treated as 'long', only applies to constant numbers.
In all honesty, use the compiler code, and don't fiddle with the registers yourself. Doing so, should only be used, is:
1) You know exactly what you are doing.
2) The compiler is doing something wrong.
If you think you 'must' access the registers directly, then you need to read the data sheet. This is all we would do.
Best Wishes |
|
|
|