Reversing direction of BLDC motor with PIC18f2431 help

Hello,

I’m working on a project in which I control a BLDC motor with PIC18f2431. I managed to run it forward and control it’s speed via PWM. All good so far. Now I’m trying to get it to spin backwards. And while this should be an easy thing to do I just can’t get it to run backwards.

This is the schematic(I’m simulating the whole thing in proteus):

http://i63.tinypic.com/2iuro1e.png

The sequence I used for driving it CW was: CB-AB-AC-BC-BA-CA for Hallsensor state: 101-001-011-010-110-100

This is the code that I wrote for driving the motor CW and it works just fine:

#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int HALL;
int HALLvalue[6] = { 0b00000101, 0b00000001, 0b00000011, 0b00000010, 0b00000110, 0b00000100 };
int direction;
unsigned int dch;
unsigned int dcl;
// Capture Interrupt Service Routine

void interrupt CheckHallValue()
{
 
IC1IF = 0; IC2QEIF = 0; IC3DRIF = 0;
HALL = (PORTA >> 2) & 0x7; // read the capture pins to get hall directionor state
if(HALL == HALLvalue[0]) { OVDCOND = 0b00100100; PDC2H = 0xFF; PDC2L = 0xFF; PDC1H = 0xFF; PDC1L = 0xFF; }
else if(HALL == HALLvalue[1]) { OVDCOND = 0b00000110; PDC1H = 0xFF; PDC1L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
else if(HALL == HALLvalue[2]) { OVDCOND = 0b00010010; PDC2H = 0xFF; PDC2L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
else if(HALL == HALLvalue[3]) { OVDCOND = 0b00011000; PDC2H = 0xFF; PDC2L = 0xFF; PDC1H = 0xFF; PDC1L = 0xFF; } //
else if(HALL == HALLvalue[4]) { OVDCOND = 0b00001001; PDC1H = 0xFF; PDC1L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
else if(HALL == HALLvalue[5]) { OVDCOND = 0b00100001; PDC2H = 0xFF; PDC2L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
}
void ConfigureADC()
{
ADCON0 = 0b00000000; // single shot mode, single channel mode
VCFG1 = 0; // VDD and VSS as ref
VCFG0 = 0;
ADCON2 = 0b00001000; // left justified, 2TAD, conversion clock: Fosc/2
ADCON3 = 0b11000100; // input capture 1 starts the a/d sequence!!(check here the first two bits)
GASEL1 = 0; // select AN0
GASEL0 = 0;
ANSEL0 = 0b00000001;
}
void main()
{
//OSCCON = 0b01001111; // frequency is 1Mhz
ConfigureADC();
SCS1 = 0; // use primary
SCS0 = 0; // oscillator
TRISA = 0b11111111; // PORTA is input(CAP's + POT)
TRISB = 0b11000000;
TRISC = 0b10000000;
GIE = 1; // enable global interrupts
GIEH = 1;
PEIE = 1;
// Initialize the Input Capture Module
CAP1CON = 0b00000000; // disable input capture 1 module
CAP1CON = 0b00001000; // enable input capture 1 module; interrupt on every state change
CAP2CON = 0b00000000; // disable input capture 2 module
CAP2CON = 0b00001000; // enable input capture 2 module; interrupt on every state change
CAP3CON = 0b00000000; // disable input capture 3 module
CAP3CON = 0b00001000; // enable input capture 3 module; interrupt on every state change
// Enable Capture Interrupt and configure TMR5
IC1IE = 1; // enable IC1 interrupt
IC1IP = 1; // IC1 interrupt on high priority
IC1IF = 0; // clear IC1 interrupt status flag
IC2QEIE = 1; // enable IC2 interrupt
IC2QEIP = 1; // IC2 interrupt on high priority
IC2QEIF = 0; // clear IC2 interrupt status flag
IC3DRIE = 1; // enable IC3 interrupt
IC3DRIP = 1; // IC3 interrupt on high priority
IC3DRIF = 0; // clear IC3 interrupt status flag
PTCON0 = 0b00000000; // 1:1 postscale, 1:1 prescale, PWM in free-running mode
PTCON1 = 0b10000000; // pwm time base is on, the time base counts up
PWMCON0 = 0b01001111; // pwm0-5 configured as pwm output in independent mode
SEVOPS3 = 0; // 1:1 postscale
SEVOPS2 = 0;
SEVOPS1 = 0;
SEVOPS0 = 0;
OSYNC = 1; //Output overrides via the OVDCON register are synchronized to the PWM time base(NOT SURE HERE)
PTPERH = 0x0F; // frequency is 1.5Khz
PTPERL = 0xFF; // 0xFF here

//T5SYNC = 0;
//T5CON = 0b01011001;
//TMR5CS = 0;
T5CON = 0b00000101;
//LATB = 0b00100100; // in order to start input capture must see a change
 
OVDCOND = 0b00100100; // start sequence
PDC2H = 0x0F; PDC2L = 0x0F; PDC1H = 0x0F; PDC1L = 0x0F;
OVDCONS = 0;
while(1)
{
ADON = 1; // keep getting ADC value
}
}

Now I want it to spin CCW. So my sequence should be BC-BA-CA-CB-AB-AC for hallsensor state: 101-001-011-010-110-100

So I wrote this code:

#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int HALL;
int HALLvalue[6] = { 0b00000010, 0b00000110, 0b00000100, 0b00000101, 0b00000001, 0b00000011 };;
int direction;
unsigned int dch;
unsigned int dcl;
// Capture Interrupt Service Routine

void interrupt CheckHallValue()
{
 
IC1IF = 0; IC2QEIF = 0; IC3DRIF = 0;
HALL = (PORTA >> 2) & 0x7; // read the capture pins to get hall directionor state
if(HALL == HALLvalue[0]) { OVDCOND = 0b00011000; PDC2H = 0xFF; PDC2L = 0xFF; PDC1H = 0xFF; PDC1L = 0xFF; }
else if(HALL == HALLvalue[1]) { OVDCOND = 0b00001001; PDC1H = 0xFF; PDC1L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
else if(HALL == HALLvalue[2]) { OVDCOND = 0b00100001; PDC2H = 0xFF; PDC2L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
else if(HALL == HALLvalue[3]) { OVDCOND = 0b00100100; PDC2H = 0xFF; PDC2L = 0xFF; PDC1H = 0xFF; PDC1L = 0xFF; } //
else if(HALL == HALLvalue[4]) { OVDCOND = 0b00000110; PDC1H = 0xFF; PDC1L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
else if(HALL == HALLvalue[5]) { OVDCOND = 0b00010010; PDC2H = 0xFF; PDC2L = 0xFF; PDC0H = 0xFF; PDC0L = 0xFF; } //
}
void ConfigureADC()
{
ADCON0 = 0b00000000; // single shot mode, single channel mode
VCFG1 = 0; // VDD and VSS as ref
VCFG0 = 0;
ADCON2 = 0b00001000; // left justified, 2TAD, conversion clock: Fosc/2
ADCON3 = 0b11000100; // input capture 1 starts the a/d sequence!!(check here the first two bits)
GASEL1 = 0; // select AN0
GASEL0 = 0;
ANSEL0 = 0b00000001;
}
void main()
{
//OSCCON = 0b01001111; // frequency is 1Mhz
ConfigureADC();
SCS1 = 0; // use primary
SCS0 = 0; // oscillator
TRISA = 0b11111111; // PORTA is input(CAP's + POT)
TRISB = 0b11000000;
TRISC = 0b10000000;
GIE = 1; // enable global interrupts
GIEH = 1;
PEIE = 1;
// Initialize the Input Capture Module
CAP1CON = 0b00000000; // disable input capture 1 module
CAP1CON = 0b00001000; // enable input capture 1 module; interrupt on every state change
CAP2CON = 0b00000000; // disable input capture 2 module
CAP2CON = 0b00001000; // enable input capture 2 module; interrupt on every state change
CAP3CON = 0b00000000; // disable input capture 3 module
CAP3CON = 0b00001000; // enable input capture 3 module; interrupt on every state change
// Enable Capture Interrupt and configure TMR5
IC1IE = 1; // enable IC1 interrupt
IC1IP = 1; // IC1 interrupt on high priority
IC1IF = 0; // clear IC1 interrupt status flag
IC2QEIE = 1; // enable IC2 interrupt
IC2QEIP = 1; // IC2 interrupt on high priority
IC2QEIF = 0; // clear IC2 interrupt status flag
IC3DRIE = 1; // enable IC3 interrupt
IC3DRIP = 1; // IC3 interrupt on high priority
IC3DRIF = 0; // clear IC3 interrupt status flag
PTCON0 = 0b00000000; // 1:1 postscale, 1:1 prescale, PWM in free-running mode
PTCON1 = 0b10000000; // pwm time base is on, the time base counts up
PWMCON0 = 0b01001111; // pwm0-5 configured as pwm output in independent mode
SEVOPS3 = 0; // 1:1 postscale
SEVOPS2 = 0;
SEVOPS1 = 0;
SEVOPS0 = 0;
OSYNC = 1; //Output overrides via the OVDCON register are synchronized to the PWM time base(NOT SURE HERE)
PTPERH = 0x0F; // frequency is 1.5Khz
PTPERL = 0xFF; // 0xFF here

//T5SYNC = 0;
//T5CON = 0b01011001;
//TMR5CS = 0;
T5CON = 0b00000101;
//LATB = 0b00100100; // in order to start input capture must see a change
 
OVDCOND = 0b00011000;
PDC2H = 0xFF; PDC2L = 0xFF; PDC1H = 0xFF; PDC1L = 0xFF;
OVDCONS = 0;
while(1)
{
ADON = 1; // keep getting ADC value
}
}

The motor still goes CW as before it won’t go CCW :frowning:

Please explain what am I doing wrong and help me get it to spin CC

I moved your post to the projects forum because your issue isn’t specific to PIC microcontrollers and there are more people actively participating here. I’ll try and take a look later but I’m swamped with tons of drywall work to finish over the next few days.

-Bill

Any luck with this? I still couldn’t figure it out :((