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
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
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


Menu
Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
one last update:
jackberg1 - 1st November 2025, 17:11added an PGM Sw on RA3
to edit the baud rate:
turn off the LCD display, press & hold the PGM sw, turn on the LCD
line 1 will show "Press to Select" , line 2 : "Baud Rate:"...