Professional Documents
Culture Documents
DC Motor Bidirectional Speed Control Using PWM PDF
DC Motor Bidirectional Speed Control Using PWM PDF
PWM
This mini-project explains the use of PIC16F877A internal PWM module to control the speed of a DC
motor, it also describes the use of H-Bridge circuit to control the direction of rotation.
PWM concerns about the duty cycle of a square wave signal, it's the technique in which we change
the pulse width to get the desired duty cycle.
Now the final step is to set your duty cycle using the function: set_pwm1_duty(duty_parameter);
to get the duty_parameter of your desired duty cycle, note the following:
the maximum value of duty_paramter (MAX) = ((preload+1)*4) -1
so in our case the maximum value is ((255+1)*4)-1 = 1023 and it represents a 100% duty cycle.
now if we need a duty cycle of 50% it would be 1023*0.5 = 512, and a duty cycle of 25% would be
1023*0.25 = 256, thus,
Note: the capital letter L at the end of the parameter instructs the compiler to treat the number as
Long integer.
Buttons UP/Down are used to increase/decrease the speed (the duty cycle)
Button Direction is used to flip the direction of rotation (CW/CCW)
CCP1 Pin 17 carries the PWM signal and connected to the motor enable pin ENA
Diodes D1-D4 are free-wheeling diodes used to protect the circuit from reverse currents.
C1 is an electromagnetic interference elimination capacitor, to protect against voltage spikes.
The C-Code
/*
PIC16F877A and L298 H-Bridge Motor Speed/Direction Controller
Electronics Lovers
www.facebook.com/Electronics.loverz
*/
#include <16f877a.h>
#fuses XT,NOLVP,NOWDT,NOPROTECT
#use delay(clock=4000000)
int16 duty_cycle=512;
void main()
{
setup_adc(ADC_OFF); // Turn ADC OFF
setup_adc_ports(NO_ANALOGS); // All Ports are digital I/O
output_high(Wire1);
output_low(Wire2); // Set the motor to CW direction
/* PWM Configurations */
setup_timer_2(T2_DIV_BY_1,255,1); // Set PWM frequency
setup_ccp1(CCP_PWM); // Configure CCP1 to PWM mode
set_pwm1_duty(512L); // default duty cycle = 50% (Half Speed)
while(1)
{
while(input(Up) && input(Down) && input(Dir)); // Hold until a button is pressed