View previous topic :: View next topic |
Author |
Message |
safwat
Joined: 08 Feb 2015 Posts: 20
|
PWM generation in pic 16F877A using C programing |
Posted: Sun Feb 08, 2015 2:39 am |
|
|
hi,
I want to generate an specific kind of PWM signal. I have already generated a normal PWM signal with the CCP module (CCP generates PWM in pic 16F877A). When i gave 50% duty cycle i have seen signal in oscilloscope (in Proteus) with infinitely many periods and each period has the same width. It was all okay as it was supposed to happen like this. But now i have different assignment. I want to create a pwm signal with all even periods 50% and odd period 25% duty cycle (infinitely many period are produced in oscilloscope). That means all the even periods will have a certain fixed width and odd period will have certain fixed width. I am unable to think of any solution. Please let me know if anyone has any idea.
I used CCS C compiler to program pic 16F877A. Proteus is used to simulate.
Thank you |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Sun Feb 08, 2015 3:20 am |
|
|
It is possible, but would depend on the frequency of the PWM. If this is fast relative to the processor clock rate, you'd tend to run out of time. However, something like:
Code: |
//processor header, clock settings etc..
#define PERIOD50 (511L)
#define PERIOD25 (255L)
#INT_TIMER2
void pwm_tick(void)
{
static int1 toggle=FALSE;
if (toggle)
{
set_pwm1_duty(PERIOD25);
toggle=FALSE;
}
else
{
set_pwm1_duty(PERIOD50);
toggle=TRUE;
}
}
void main(void)
{
setup_timer_2(T2_DIV_BY_4,255,1); //from 20MHz clock about 5000Hz
setup_ccp1(CCP_PWM);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(TRUE)
{
//whatever else you want...
}
}
|
So every alternate Timer2 clock cycle, the duty is toggled between the two values.
However there has to be time to do the toggle, _before_ the earliest that the PWM might trigger in the cycle. as posted, the PWM is triggering every 4096 machine cycles, and the earlier trigger is 1/4 the way through this (so around 1000 machine cycles), which is OK. However if you ran with a fast PWM setting, then changes would get skipped... |
|
|
safwat
Joined: 08 Feb 2015 Posts: 20
|
|
Posted: Sun Feb 08, 2015 4:22 am |
|
|
it is only showing the 25% cycle. not toggling |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Sun Feb 08, 2015 6:03 am |
|
|
OK, maybe I need another coffee but since PWM is composed of a high time and a low time being 100% of the 'frame', doesn't your '50% even ( high) and 25% odd (low) (75% of a frame) equate to 66.6% hi and 33.3% low ?
Maybe a picture would help. these aging eyes !
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Sun Feb 08, 2015 9:01 am |
|
|
He's talking about doing one cycle 50/50, then one cycle 25/75, then one cycle 50/50.
Code: |
__|¯¯|__|¯|___|¯¯|__|¯|___
|
I think what I posted should work. It'll lag by one cycle (the period doesn't update till the end of the current cycle). So when you write, it'll be the next cycle that gets the update.
Are you sure you copied the code as posted (static is essential for the flag for example)?.
Beyond that, try it in a chip. This is exactly the sort of thing that Isis (the Proteus simulator) can't handle properly. |
|
|
safwat
Joined: 08 Feb 2015 Posts: 20
|
|
Posted: Sun Feb 08, 2015 11:37 am |
|
|
yea you understood exactly what i was trying to do. as you said maybe i should try it in a chip. you are most certain that it is working? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Mon Feb 09, 2015 2:07 am |
|
|
I have just put it into a chip, and yes, it works as posted. |
|
|
safwat
Joined: 08 Feb 2015 Posts: 20
|
|
Posted: Mon Feb 09, 2015 3:34 am |
|
|
please can you tell me what changes(or add) should i make in the code so that i can operate both the CCP 1 and CCP 2 module. CCP1 will have the same thing that you have done. but CCP 2 will have exactly opposite of CCP 1. that means 25% 1st cycle 50% 2nd cycle 25% again in third and so on.
and thank you very much for your help.it is going to help me a lot. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19589
|
|
Posted: Mon Feb 09, 2015 4:12 am |
|
|
Code: |
//processor header, clock settings etc..
#define PERIOD50 (511L)
#define PERIOD25 (255L)
#INT_TIMER2
void pwm_tick(void)
{
static int1 toggle=FALSE;
if (toggle)
{
set_pwm1_duty(PERIOD25);
set_pwm2_duty(PERIOD50);
toggle=FALSE;
}
else
{
set_pwm1_duty(PERIOD50);
set_pwm2_duty(PERIOD25);
toggle=TRUE;
}
}
void main(void)
{
setup_timer_2(T2_DIV_BY_4,255,1); //from 20MHz clock about 5000Hz
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(TRUE)
{
//whatever else you want...
}
}
|
|
|
|
|