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: Gathering chip temperature from PIC18F26K83
Thanks again for that Richard. I'm discovering the only assembly instruction I really need as an assembly call is the table read command. Everything else (reading & writing to registers) can be done...
rocket_troy Today, 00:40