CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Power pwm H-bridge motor control. help me

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 15, 2012 3:55 pm     Reply with quote

Here's an example of complementary PWM output on pins B0 and B1
with an 18F4431. I tested this in hardware with compiler vs. 4.135.
It should also work with the 18F2431 because it's in the same PIC family.
Code:

#include <18F4431.h>
#fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=20M)

// Note: The following numbers work with a 20 MHz oscillator frequency.

#define POWER_PWM_PERIOD 249  // Gives 20 KHz pwm frequency
#define DEAD_TIME  2    // Gives dead time of 1.6 usec

//=======================================
void main()
{
// Setup PWM0 and PWM1 pins as complementary PWM outputs.
// All other PWM pins are configured as OFF (not used).
setup_power_pwm_pins(PWM_COMPLEMENTARY, 0, 0, 0);

// Mode = Free Run 
// Postscale = 1   (1-16) Timebase output postscaler
// TimeBase = 0   (0-65355) Initial value of PWM Timebase
// Period = 2000  (0-4095) Max value of PWM TimeBase
// Compare = 0     (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

setup_power_pwm(PWM_FREE_RUN  | PWM_CLOCK_DIV_4 |  PWM_DEAD_CLOCK_DIV_16, 1, 0, POWER_PWM_PERIOD, 0, 1, DEAD_TIME); 

// This setting gives a 50% duty cycle.  For example, the last value
// of .5 gives 50%.  A last value of .4 would give a 40% duty cycle.
set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .5));

while(1);
}
yadelim



Joined: 14 Aug 2012
Posts: 4

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 7:30 am     Reply with quote

Dear pcm prgrammer...
Firstly thanks to your kindly reply. The problem is not to produce complementary pwm signals.
It doesn't show the problem when i write to duty the numbers 0-999
but its a problem when i write the variable (pwmayar) to duty... the code under line.

Pwm duty must between 0-999 but always low. I see the pwmayar changing on the lcd but duty doesn't change. Whats the problem?
Code:
     
signed int16 pwmayar;
int1 yon;

if (pwmayar >125) pwmayar = 125; // pwmayar max:125
if (pwmayar <(-125)) pwmayar = (-125); // pwmayar min:-125
if (yon) {set_power_pwm0_duty ((int16)(499 + (4 * pwmayar)));}
else {set_power_pwm0_duty ((int16)(499 - (4 * pwmayar)));}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 12:12 pm     Reply with quote

Quote:
Pwm duty must between 0-999.

Why does it have to be a number in that range ? Why can't you use a
decimal fraction, like 0.00 to 1.00 ?

Example:
Code:

float pwm_duty;
.
.
.
pwm_duty = 0.50;   // 50% duty cycle

set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * pwm_duty);
yadelim



Joined: 14 Aug 2012
Posts: 4

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 1:38 pm     Reply with quote

"yon" according to the variable, the direction of the engine change.
yon = 1
When I press the x button. engine, turn left,
When I press the y button. engine, turn right,
yon = 0
When I press the x button. engine, turn right,
When I press the y button. engine, turn left,

According to me my will.
and according to your description;
will be as follows?
(sorry for bad english)

Code:

int8 pwmayar;
int1 yon;
float pwm_duty;

if (pwmayar >250) pwmayar =250; // pwmayar max:250
if (pwmayar <1) pwmayar = 1; // pwmayar min:1

pwm_duty=(float) (pwmayar/250);

if (yon){ set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * pwm_duty));}
else {pwm_duty=(float)(1-pwm_duty);
         set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) *pwm_duty));}




it does not cause?;
Code:

if (pwmayar >125) pwmayar = 125;
if (pwmayar <(-125)) pwmayar = (-125);
if (yon) {set_power_pwm0_duty ((int16)(499 + (4 * pwmayar)));}
else {set_power_pwm0_duty ((int16)(499 - (4 * pwmayar)));}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 16, 2012 3:29 pm     Reply with quote

You have to tell the compiler to do floating math, by making at least one
of the numbers in the division into a floating point number.
See below how I have edited the 250 into 250.0 - this will now make it do
floating point math:
Quote:

pwm_duty=(float) (pwmayar/250.0);
yadelim



Joined: 14 Aug 2012
Posts: 4

View user's profile Send private message

PostPosted: Fri Aug 17, 2012 5:52 am     Reply with quote

Dear pcm programmer

thanx for your kindly reply to solve our problem...

best regards
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group