Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Cannot get the code of Sensorless BLDC ESC

Status
Not open for further replies.

swapan

Full Member level 4
Joined
Feb 20, 2009
Messages
199
Helped
27
Reputation
54
Reaction score
24
Trophy points
1,298
Location
Kolkata
Activity points
2,806
Hi guys,
I am interested to make one Electronic Speed Controller to drive a small Sensorless BLDC motor. After thorough study of some application note, tutorial and article on the web, I got one code which is given as under. In the code, the variable 'j' is defined as global as well as local.In the ISR the variable 'j' is incremented in for loop and decremented in the following 'if' condition. Here I am getting confused. Please see the code and help a bit.

Code:
Sensorless brushless DC ( BLDC ) motor control with PIC16F887 microcontroller
  C Code for mikroC PRO for PIC compiler
  Crystal oscillator used @ 20MHz
  Configuration words: CONFIG1 = 0x2CD2
                       CONFIG2 = 0x0700
  This is a free software with NO WARRANTY.
  https://simple-circuit.com/
 
***************************************************************************************/
 
 
#define PWM_MIN_DUTY      80
#define PWM_START_DUTY    200
 
#include <stdint.h>
 
void AH_BL();
void AH_CL();
void BH_CL();
void BH_AL();
void CH_AL();
void CH_BL();
void bldc_move();
 
uint8_t bldc_step = 0;
uint16_t motor_speed, i, j;
 
void Interrupt()
{
  // BEMF debounce
  int8_t j;
  [COLOR="#FF0000"]for(j = 0; j < 10; j++) {
    if(bldc_step & 1) {
      if(!C1OUT_bit)    j -= 1;
    }
    else {
      if(C1OUT_bit)     j -= 1;
    }[/COLOR]
  }
  bldc_move();
  C1ON_bit = 1;      // clear the mismatch condition
  C1IF_bit = 0;      // Clear comparator 1 interrupt flag bit
}
 
void bldc_move()        // BLDC motor commutation function
{
  switch(bldc_step){
    case 0:
      AH_BL();
      CM1CON0 = 0xA2;   // Sense BEMF C (pin RA3 positive, RB3 negative)
      break;
    case 1:
      AH_CL();
      CM1CON0 = 0xA1;   // Sense BEMF B (pin RA3 positive, RA1 negative)
      break;
    case 2:
      BH_CL();
      CM1CON0 = 0xA0;   // Sense BEMF A (pin RA3 positive, RA0 negative)
      break;
    case 3:
      BH_AL();
      CM1CON0 = 0xA2;   // Sense BEMF C (pin RA3 positive, RB3 negative)
      break;
    case 4:
      CH_AL();
      CM1CON0 = 0xA1;   // Sense BEMF B (pin RA3 positive, RA1 negative)
      break;
    case 5:
      CH_BL();
      CM1CON0 = 0xA0;   // Sense BEMF A (pin RA3 positive, RA0 negative)
      break;
  }
  bldc_step++;
  if(bldc_step >= 6)
    bldc_step = 0;
}
 
// set PWM1 duty cycle function
void set_pwm_duty(uint16_t pwm_duty)
{
  CCP1CON = ((pwm_duty << 4) & 0x30) | 0x0C;
  CCPR1L  = pwm_duty >> 2;
}
 
// main function
void main()
{
 
  ANSEL = 0x10;     // configure AN4 (RA5) pin as analog
  PORTD = 0;
  TRISD = 0;
  // ADC module configuration
  ADCON0 = 0xD0;    // select analog channel 4 (AN4)
  ADFM_bit = 0;
 
  INTCON = 0xC0;   // enable global and peripheral interrupts
  C1IF_bit = 0;    // clear analog coparator interrupt flag bit
 
  // PWM
  CCP1CON = 0x0C;  // configure CCP1 module as PWM with single output & clear duty cycle 2 LSBs
  CCPR1L  = 0;     // clear duty cycle 8 MSBs
  // Timer2 module configuration for PWM frequency of 19.53kHz & 10-bit resolution
  TMR2IF_bit = 0;  // clear Timer2 interrupt flag bit
  T2CON = 0x04;    // enable Timer2 module with presacler = 1
  PR2   = 0xFF;    // Timer2 preload value = 255
 
  // Motor start
  set_pwm_duty(PWM_START_DUTY);                 // Set PWM duty cycle
  i = 5000;
  while(i > 100)
  {
    j = i;
    while(j--) ;
    bldc_move();
    i = i - 50;
  }
  
  ADON_bit = 1;
  C1IE_bit = 1;   // enable analog coparator interrupt
 
  while(1)
  {
    GO_DONE_bit = 1;  // start analog-to-digital conversion
    delay_ms(50);     // wait 50 ms
    
    motor_speed = (ADRESH << 2) | (ADRESL >> 6); // read ADC registers
    
    if(motor_speed < PWM_MIN_DUTY)
      motor_speed = PWM_MIN_DUTY;
    set_pwm_duty(motor_speed);             // set PWM duty cycle
    
  }
  
}
 
void AH_BL()
{
  CCP1CON = 0;        // PWM off
  PORTD   = 0x08;
  PSTRCON = 0x08;     // PWM output on pin P1D (RD7), others OFF
  CCP1CON = 0x0C;     // PWM on
}
 
void AH_CL()
{
  PORTD = 0x04;
}
 
void BH_CL()
{
  CCP1CON = 0;        // PWM off
  PORTD   = 0x04;
  PSTRCON = 0x04;     // PWM output on pin P1C (RD6), others OFF
  CCP1CON = 0x0C;     // PWM on
}
 
void BH_AL()
{
  PORTD = 0x10;
}
 
void CH_AL()
{
  CCP1CON = 0;        // PWM off
  PORTD   = 0x10;
  PSTRCON = 0x02;     // PWM output on pin P1B (RD5), others OFF
  CCP1CON = 0x0C;     // PWM on
}
 
void CH_BL()
{
  PORTD = 0x08;
}
 
// End of code.
 

OK. Then the local variable j is once incremented in for loop and in the following if condition it is decremented. I get stuck here. Please elaborate a little.
 

In the for() loop local variable j goes from 0 to 9 and when it becomes 10 the loop breaks.
 

In the for() loop local variable j goes from 0 to 9 and when it becomes 10 the loop breaks.

But what about the if/else if condition inside the for loop where the variable is decremented?
 

The instruction j -= 1 is effectively pausing the loop to wait for a certain event.

Can cause an endless loop in case of unexpected hardware behavior. That's really bad coding style, I'm not motivated to discuss it in detail.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top