C Example: Bi-Directional PWM Motor Control

From Mech
Revision as of 15:56, 25 June 2007 by LIMS (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Code

Program to run a motor bidirectionally at varying speeds depending on the position of a potentiometer.

First include header file with definitions for specific PIC. Set fuses. HS is type of external clock, low voltage protection (LVP) is off, and the watchdog timer (WDT) is off. External clock frequency of 20 MHz is specified.

  #include <18F4520.h>
  #fuses HS,NOWDT,NOPROTECT,NOLVP
  #use delay(clock=20000000)

Introduce the variables to be used in the main program.

  int read;
  int readlow;
  int readhigh;

Begin main body of program.

  void main() {

Setup the CCP1 and CCP2 to be PWM outputs. Also set the timer to be used for PWM.

     setup_ccp1(CCP_PWM);
     setup_ccp2(CCP_PWM);
     setup_timer_2(T2_DIV_BY_1, 255, 1);

Setup analog input, and which analog channel is active.

     setup_adc_ports(AN0_ANALOG);
     setup_adc(ADC_CLOCK_INTERNAL);
     set_adc_channel(0);

Setup an infinite loop, using a while statement.

     while(TRUE) {

Read the analog input and define "readhigh" and "readlow" as functions of "read". Note that the value of "readhigh" varies from 0 to 255 when the potentiometer is between 140 and 255, and "readlow" behaves similarly.

        read = read_adc();
        readlow = (120-read)*2.125;
        readhigh = (read-140)*2.217;

Check the value of "read", and set the duty cycle of each PWM output signal accordingly. The H-bridge circuit used requires two inputs (the two PWM outputs of the 18F4520) to control the direction and speed of the driven motor.

        if (read<120){
           set_pwm1_duty(readlow);
           set_pwm2_duty(0);}
        else if (read>140){
           set_pwm1_duty(0);
           set_pwm2_duty(readhigh);}
        else {
           set_pwm1_duty(0);
           set_pwm2_duty(0);}
    }
  }

Associated Circuitry