View previous topic :: View next topic |
Author |
Message |
adammenzies
Joined: 31 Aug 2010 Posts: 8
|
CCP_PWM_HALF_BRIDGE mode on PIC16F1933 |
Posted: Wed Nov 07, 2012 11:36 am |
|
|
Hi All,
I am trying to setup a half bridge driver using a PIC16F1933.
According to the datasheet (page 198) I should see this (ignore dead-band for now):
P1A: ____|--|___
P1B: |--|_____|--|___
But what I'm actually seeing is:
P1A: ___|--|___
P1B: ----|__|----
(i.e. P1B = !P1A)
Here is my code:
Code: | #include "16F1933.h"
/* setup fuses */
#fuses HS,NOWDT,BROWNOUT,PUT
#use delay (clock=20000000)
void main()
{
// setup all of B and C as outputs (need to change later)
set_tris_b(0x00); // Set pins B as outputs
set_tris_c(0x00); // Set pins C as outputs
// Setup the ECCP for PWM in half bridge mode.
setup_ccp1(CCP_PWM_HALF_BRIDGE | CCP_PWM_H_H, 25);
// setup timer 2 for 25kHz
setup_timer_2(T2_DIV_BY_4, 200, 1);
while(1)
{
set_pwm1_duty(75);
}
} |
Any thoughts? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19588
|
|
Posted: Wed Nov 07, 2012 1:01 pm |
|
|
set_pwm1_duty(75L);
Search the forum, or read the manual for 'why'.
Best Wishes |
|
|
adammenzies
Joined: 31 Aug 2010 Posts: 8
|
|
Posted: Wed Nov 07, 2012 1:42 pm |
|
|
Hi Ttelmah,
Ttelmah wrote: | set_pwm1_duty(75L); |
I appreciate the syntax correction, but that still didn't resolve the issue. I'm still getting P1A=!P1B instead of what's described on page 198 of the datasheet.
Here's a scope trace since ASCII art is not my forte!
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19588
|
|
Posted: Wed Nov 07, 2012 1:54 pm |
|
|
Neither your text version or your picture show P1A=P1B. P1B is off when P1A is ON, less the deadband times.
Best Wishes |
|
|
adammenzies
Joined: 31 Aug 2010 Posts: 8
|
|
Posted: Wed Nov 07, 2012 1:59 pm |
|
|
Ttelmah wrote: | Neither your text version or your picture show P1A=P1B. P1B is off when P1A is ON, less the deadband times.
|
I agree it's not P1A=P1B, but if you look at the original post I suggested P1A=!P1B. (i.e. P1B is the inverse of P1A)
This is not what's on the datasheet. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 07, 2012 2:59 pm |
|
|
Quote: | According to the datasheet (page 198)
|
Post the Figure number and the title of the Figure in the data sheet.
That's needed because datasheets have different revisions and the
page numbers change on each one. |
|
|
adammenzies
Joined: 31 Aug 2010 Posts: 8
|
|
Posted: Wed Nov 07, 2012 3:04 pm |
|
|
Quote: | Post the Figure number and the title of the Figure in the data sheet. |
It's Figure 19-6 EXAMPLE PWM (ENHANCED MODE) OUTPUT RELATIONSHIPS (ACTIVE-HIGH STATE)
The second set of plots (Half-Bridge) shows P1A and P1B with equal pulse width, 90 degrees out of phase. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 07, 2012 3:28 pm |
|
|
So basically your entire complaint is that you don't have 50% duty cycle.
Go to this page and read all the threads on 10-bit PWM mode.
http://www.ccsinfo.com/forum/viewtopic.php?t=45968&start=1
After you have done that, you will understand how to set your duty cycle
value to give you 50% duty cycle. |
|
|
adammenzies
Joined: 31 Aug 2010 Posts: 8
|
|
Posted: Wed Nov 07, 2012 4:44 pm |
|
|
PCM programmer wrote: | So basically your entire complaint is that you don't have 50% duty cycle. |
Possibly I'm not describing my issue very well. I can get 50% duty cycle no problem, and in fact it is the one exceptional value which produces the result I'm looking for.
Let's take any value less than 50%; for the sake of this discussion I'll use 33%, and for simplicity I'll assume no deadtime.
According to the datasheet, if I setup in half-bridge mode with a 33% duty cycle, I should see this:
(33% duty cycle on each channel)
But I actually see this:
(33% duty cycle on P1A, 66% duty cycle on P1B)
Am I reading the datasheet wrong? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 07, 2012 5:16 pm |
|
|
Now it looks like your problem is that you don't have any deadband time
specified. Add the following routine above main(). Then call it after you
call setup_ccp1(). Put in some number for the deadband, such as 64.
Then look at the waveforms on your oscilloscope:
Code: |
// Call this routine to set the PWM deadband.
// The deadband value can be from 0 to 127,
// and is in units of Instruction Cycles (Fosc/4).
// For example, with a 4 MHz crystal, an instruction
// cycle is 1 us.
void set_deadband(int8 deadband)
{
#byte PWM1CON = getenv("SFR:PWM1CON")
if(deadband > 127) // Do a limit check on the value.
deadband == 127;
PWM1CON = deadband;
}
|
Example of how to use the function:
|
|
|
|