• 18f4431; driving a stepper IN HARDWARE mode

    hi everyone,
    i have the pic18fxx31 datasheet all printed out and bound into a book, and i read it every spare time i can get.
    so the other day, i was looking at the power control module (page 181) and started thinking about how to drive a stepper with it. i looked closely at the pwm output override section, (page 202), and an idea hit me. use the OVDCOND register to determine which pwm output pins turn on, irrespective of the duty cycle. in short, on/off control of any pwm pin, AND 14-bit duty cycle control of any pwm output pin AT THE SAME TIME.
    i tried it with this simple code and it works on a stepper and leds, in my QL200 dev board
    Code:
    main
         ADCIN 0, DUTY_ADJ            ;read value on pot
         DUTY = DUTY_ADJ*64           ;bring up 8 bit adc value to 14 bit duty value
         PDC0L = Duty.LowByte         ;load duty value into duty registers
         PDC0H = Duty.HighByte        ;
         PDC1L = DUTY.LOWBYTE         ;
         PDC1H = DUTY.HIGHBYTE        ;
         PDC2L = Duty.LowByte         ;
         PDC2H = Duty.HighByte        ;
         PDC3L = DUTY.LOWBYTE         ;
         PDC3H = DUTY.HIGHBYTE        ;
         OVDCOND = %10000000          ;use override control to switch pwm pins
         PAUSE 10                     ;pause
         OVDCOND = %00100000          ;
         PAUSE 10                     ;
         OVDCOND = %00001000          ;
         PAUSE 10                     ;
         OVDCOND = %00000010          ;
         pause 10                     ;
         goto main                    ;loop
    stepper power is controlled by the value of the duty cycle. in this example, all the duty registers have the same value (from the adcin 0),but its possible to have different duty cycles.

    For the 18f4431, you get four individual duty cycle control, thus perfect compatibility with a stepper motor. im highly interested in motor control for cnc applications. i would really appreciate all the help i can get, to implement into this idea:
    • ramping up/down ideas
    • current limiting by varying the duty cycle
    • current feedback
    • any other stepper optimization technology/ideas
    Reply from Bruce:Wow - nice catch on that one. It does appear to work. Cool idea, and thanks for the tip. I wish I had a stepper motor board to test this on, but it does look good compared to theUCN5804B datasheet for 2-phase & half-step drive sequences in MPSIM logic analyzer.. when simulated for an 18F2431. I already had a project in MPLAB using C18 for an 18F2431, so I tossed these values inusing your OVDCOND approach, and it looks good. Do these waveforms look good for both
    2-phase & half-step?

    If they do, and it's worthwhile .. I'll work up an example in PBP. I'm a total newbie when it
    comes to steppers - so let me know if the control signals look OK.

    Here's the C18 example I used to test & simulate, which should be super easy to translate
    to PBP.
    Code:
    #include  p18f2431.h
    #include  delays.h 
    #pragma   config OSC=HS,LVP=OFF,WDTEN=OFF,MCLRE=OFF
     
    union DutyCycle
    {
      unsigned int Cycle;
      unsigned char wByte[2];
    } Duty;
     
     
    void main(void) 
    { 
       // Port init
       PORTB = 0;                  // clear port
       TRISB = 0;                // all outputs 
     
       // PCPWM init
       PTCON0 = 0;               // Free Running mode.
       PTPERL = 0;               //
       PTPERH = 1;               // PTPER = $0100 or 256d for ~19.45kHz
       PWMCON0 = 0b01011111;     // PWM[5:0] outputs enabled    
       PWMCON1 = 1;              // OVDCON synched to PWM time base
       DTCON = 0;                // zero dead-time
       PTCON1 = 0b10000000;      // PWM time base is ON
     
       Duty.Cycle = 1023;        // 19.5kHz has a 10-bit resolution.
     
       PDC0L=Duty.wByte[0];
       PDC0H=Duty.wByte[1];
       PDC1L=Duty.wByte[0];
       PDC1H=Duty.wByte[1];
       PDC2L=Duty.wByte[0];
       PDC2H=Duty.wByte[1];
     
       while(1)
        {
        /* // half step mode
        OVDCOND = 0b00000001;    // use override control to switch pwm pins
        Delay10TCYx(250);        // 500uS @ 20MHz
        OVDCOND = 0b00000011;
        Delay10TCYx(250);
        OVDCOND = 0b00000010;
        Delay10TCYx(250);
        OVDCOND = 0b00000110;
        Delay10TCYx(250);
        OVDCOND = 0b00000100;
        Delay10TCYx(250);
        OVDCOND = 0b00001100;
        Delay10TCYx(250);
        OVDCOND = 0b00001000;
        Delay10TCYx(250);
        OVDCOND = 0b00001001;
        Delay10TCYx(250); */
     
        // 2 phase mode
        OVDCOND = 0b00001001;
        Delay10TCYx(250);
        OVDCOND = 0b00000011;
        Delay10TCYx(250);
        OVDCOND = 0b00000110;
        Delay10TCYx(250);
        OVDCOND = 0b00001100;
        Delay10TCYx(250);
     
      } // End while(1) 
     
     } // End main
    Half-step is 1st graphic, 2-phase is 2nd.



    This article was originally published in forum thread: 18f4431; driving a stepper IN HARDWARE mode started by DDDvvv View original post