Page 1 of 1

Two pwm outputs with only one CCP

Posted: Wed Nov 17, 2010 7:38 am
by medelec35
Since no replies to 12F617 question decided to use 12f615 instead.
Since both microcontrollers only have one pwm channel, my question is:
How easy is it to add a code to bit bang a second channel so when the CCP1 pin goes high, another pin goes high at the same time.
Then each pin will go low depending on two pots settings. One pin controlled by CCP1, and the other bin controlled after a delay that was triggered by CCP1.
Obviously this 2nd pwm control has to go low before it's re-triggered.
I'm not sure if asking too much, but I have seen some very clever C coding by some people :-)
Thank you and looking forward to reading any replies.

Re: Two pwm outputs with only one CCP

Posted: Wed Nov 17, 2010 8:10 am
by Steve
Hi Martin,

Ben's currently on holiday, which is why you've not had a reply to your other question. He's due back tomorrow (or perhaps even today), so you should get a reply soon. The same goes for this question too.

Re: Two pwm outputs with only one CCP

Posted: Wed Nov 17, 2010 9:20 am
by medelec35
Ah. Thanks Steve.
TBH I did think forum has gone a bit quiet with regarding to replies.
Now I know why.

Re: Two pwm outputs with only one CCP

Posted: Thu Nov 18, 2010 2:54 pm
by Benj
Hi Medelec,

Sorry for the delay.

You can do this using a custom interrupt.

Enable code - Note that the x's should be replaced with values for the registers.

Code: Select all

	ccpr1h = x;		//Set capture compare setpoint
	ccpr1l = x;
	t1con = x;			//Setup timer and start running
	ccp1con = x;		//Configure CCP1 settings
	st_bit(pie1, CCP1IE);			//Enable CCP1 interrupt
	st_bit(intcon, PEIE);			//Enable Interrupts
	st_bit(intcon, GIE);
Handler Code

Code: Select all

if (ts_bit(pir1, CCP1IF) && ts_bit(pie1, CCP1IE))
{
   porta = porta | 0x03;
	cr_bit(pir1, CCP1IF);							//Clear interrupt
}
Disable code

Code: Select all

	cr_bit(pie1, CCP1IE);			//Disable CCP1 interrupt

Re: Two pwm outputs with only one CCP

Posted: Thu Nov 18, 2010 4:31 pm
by medelec35
Thanks Ben.
No problem. I did not know you was on holiday until Steve said.

I will give this a try and let you know how I get on.

Re: Two pwm outputs with only one CCP

Posted: Fri Nov 19, 2010 10:38 am
by medelec35
Im not quiet sure how the information in the previous post will fit together in my application.
I thought I could read PR2 which is max pwm, then set var to 30% of PR2 to set the second pwm to 30% duty as an example.
Then set GP5 to 0 when time is up, then set GP5 to 5V when pwm hardware (CCP1) goes to +5V
This is my intention:

I have a 12F615 which has one pwm. Which using 8 MHz internal osc will produce a pwm at 5KHz
There are two variables: Read_Pot1, Read_Pot2
These variables values will be determined by reading two potentiometers with ADC part of 12F615
Read_Pot1 will determine duty of PWM1 and will toggle pin 5
The second PWM duty will be determined by Read_Pot2 value and will toggle pin 2.
Im not too sure how to set up togging pin 2 which would go high as the same time as pin 5 goes high, but will go low depending on duty requied eg. 30%
I would assume PWM2 will have to be bit banged and be triggered from timer2 interrupt. Then a variable which is set to 30% of PR2 by Read_Pot2 variable. This then needs to be compared to Timer2, If 30% is reached then pin 2 goes low.
I am currently using timer1 fir measuring seconds. But if that is the only way then fair enough.

Would it be possible to show the code with variable names e.g Read_Pot1, Read_Pot2 etc include please?.
Can this be done by using PWM component of Flowcode and just adding the bit bang of pwm2 in code form which is my preference?
Or has setting up of pwm has to be all done by code?

Re: Two pwm outputs with only one CCP

Posted: Fri Dec 03, 2010 3:10 pm
by medelec35
So if I have two pots connected. ADC0 and ADC1.
I need to control two independent PWM signals at a frequency of 5KHz.
This would be easy if there were two PWM channels, but unfortunately on this target device, there is only one channel available.
So that's why I need to bit bang 2nd pwm source. I was wondering if I can tap into the pwm channel the pwm component macro has set up, and set a port high e.g. GP4 when CCP1 goes high (duty set by ADC0) then GP4 would go low after a given time (duty set by ADC1).

Or Can enhanced CCP be used, so P1A and P1B be adjusted independently?
I would be very grateful If anyone can help.
Thank you.

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 06, 2010 11:51 am
by Steve
I'm by no means an expert, but here are my thoughts...

P1A and P1B are not independent, so this in not an option. Looking at the datasheet, I think you have 2 choices - use the "compare" mode of that chip to generate a software interrupt at certain times, or just bitbang both PWM channels.

You may need to limit the resolution of the duty cycle to accommodate these approaches.

Re: Two pwm outputs with only one CCP

Posted: Sat Dec 11, 2010 11:07 pm
by medelec35
Steve wrote:or just bitbang both PWM channels.

You may need to limit the resolution of the duty cycle to accommodate these approaches.
I have given this approach a try, but failed.
Maybe its the resolution part you mentioned that is causing it to fail?

I'm not saying your wrong, its probably my theory which is totally wrong.
Here is my theory:
Target frequency=8MHz
PWM Freq = 5KHz
Duty = 0 to 100% Variable
Since PWM Freq = 5KHz = 200uS, then Timer interrupt = 5KHz*100 = 500KHz = 2uS. This is where the theory has probably gone wrong, and would cause issues.
After compiling and running, only can obtain PWM at 38Hz.
Any help is appreciated.
Thank you.

Edit: I have also tried timer2, which can interrupt at 500KHz

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 13, 2010 10:30 am
by Mikat
That 38Hz could mean that the int freq is original 3800Hz...
I notice the c code tmr0 += 254; should set the tmr0 value at 254, but i think it should be tmr0 = 254;?

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 13, 2010 11:00 am
by medelec35
Hi Mikat.
Thank you for your reply.
Mikat wrote:That 38Hz could mean that the int freq is original 3800Hz...
The first thing I did was to toggle a pin every 500ms to determine if Osc is working at correct frequency.
I also changed config so there is an output of osc/4 appearing at RA6, which is correct at 2MHz.
To get Internal osc at 8MHz and enable ICD to function correctly, osccon=0x70 is contained within LED0 customised coding.
Mikat wrote:I notice the c code tmr0 += 254; should set the tmr0 value at 254, but i think it should be tmr0 = 254;?
This was something Steve had suggested here:
http://www.matrixmultimedia.com/mmforum ... 33&p=15859
Frequency only slighly altered (dropped about 2Hz) when + was removed.

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 13, 2010 12:37 pm
by Mikat
Ok i do some scoping and the first thing is that if i set tmr0 over 243 duty crashes very slow...
I think the reason is that the interrupt macro code is still running while timer0 overflows...
Changing the register value set end of the macro makes things little better...
But i think you have mission impossible...
Little calculation 8MHz gives 0,125µs per clock, and that gives 0,5 µs per command... So in 2µs it gives only 8 commands,and i think thas WAY TOO LITTLE to handle that interrupt and interrupt macro code....
Try that code on 18f2620 with hs-pll and didnt get below 0,8ms period...
8MHz can only run about 400Hz pwm before dutycycle crashes...


Mika

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 13, 2010 1:30 pm
by medelec35
Thanks again Mikat.
I believe you are correct in what you say.
I am also starting to believe you can't create dual or even a single BitBang PWM at 5KHz.
So back to the drawing board of utilising single CCP1 to produce two lots of PWM.
This seems above my limits of knowledge. So any more help will be thankfully received.

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 13, 2010 2:12 pm
by Mikat
I think that the wall is limitations of the chip...
Only way i see that it as some change for success is that ccp1 trigs interrupt, witch takes pin hi, and set timer1 value ,and then timer1 int trigs pin down... But still 8 commands is quite low to do that, i think...
Ben or Steve maybe could answer how many commands takes simple interrupt...
But the above way you dont need generate interrupt witch is 100 times to duty...
Still you might get problems with very low duty cycles..
That way i do very accurate pwm for servo,the period is 1-2ms and duty can be adjusted about 1µs precision ...

Mika

Re: Two pwm outputs with only one CCP

Posted: Mon Dec 13, 2010 10:08 pm
by medelec35
Thanks Mikat.
My original idea was to use ccp1, and enable the other pin and a time would turn non CCP pin off, but that was over my head and was hoping some one smarter than me (that's not difficult :P ) could come up with a nice solution to a difficult challenge.
This is my next attempt. Not tested but in theory should work to a fashion.
According to simulator, Both pwm signals can be independently controlled and is at approx 5KHz, but resolution is not that great. I am working on finding a number that can go up to safely before corruption of timer 2 occurs.
Since there should not really be a delay in an interrupt which could last longer than the interrupt its self takes to trigger.
But still on the look out for a better way.. Not giving up just yet :-)

Re: Two pwm outputs with only one CCP

Posted: Tue Dec 14, 2010 5:54 am
by Mikat
That might work, but...
If you have duty cycle near 100% you dont have much time to run other code... And if you have 100% duty the program kind is forever in that int loop...
What are the range of the duty cycle you need?

Mika

Re: Two pwm outputs with only one CCP

Posted: Tue Dec 14, 2010 7:07 am
by medelec35
Mikat wrote:That might work, but...
If you have duty cycle near 100% you don't have much time to run other code
Both codes run simultaneously so if duty1=98% and duty2=10%.
Both pins will go high. The time on branch is the 98% one.
But when time for 10% has elapsed then that pin will go low only leaving PWM1 on. then after given time PWM1 pin will go low.
Only thing with this method is interrupt corruption can occur if too high value is chosen
Mikat wrote:What are the range of the duty cycle you need?
Trying to get as much as I can between 0 and 100%
I would be happy if get resolution to select duty to the nearest 2%. E.g duty of 0,2,4,6,8,10% etc
I am controlling two DC motors, and need to have good control of the speed. I know the easiest way is to change chip for one which has 2 CCP pwm's. But need to stick with a 8 pin chip, and don't believe there are any 8 pin devices with 2 pwm channels.

Re: Two pwm outputs with only one CCP

Posted: Tue Dec 14, 2010 8:26 am
by Mikat
medelec35 wrote:
Mikat wrote:That might work, but...
If you have duty cycle near 100% you don't have much time to run other code
Both codes run simultaneously so if duty1=98% and duty2=10%.
Both pins will go high. The time on branch is the 98% one.
Yes i noticed that but if you have 98% duty,that means that the program loops in interrupt 98% of the time...
So you have only 2% of the time to handle rest of the program...
When program is in the interrupt macro, you cant do anything else, so the "main" program "freezes" until the macro is completed...

Mika

Re: Two pwm outputs with only one CCP

Posted: Tue Dec 14, 2010 8:05 pm
by medelec35
Mikat wrote:Yes i noticed that but if you have 98% duty,that means that the program loops in interrupt 98% of the time...
So you have only 2% of the time to handle rest of the program...
When program is in the interrupt macro, you cant do anything else, so the "main" program "freezes" until the macro is completed...
Mika
Ah I can see what your saying.
hmm not so sure about that point. assuming worse case scenario. If duty of interrupt is 100% = 5KHz = 200uS duration beteen each interrupt. Since instructions are running at a duration of
8MHz/4 = 2MHz = 500ns. There are quiet a few ns in between 200Us.
But I'm not saying your wrong as I could have my theory's wrong!