STM8 MCKIT1.0 BLDC sensorless control acquisition implementation analysis

Publisher:温馨时光Latest update time:2015-08-24 Source: eefocusKeywords:STM8 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
The STM8 motor library written by ST can drive BLDC in a sensorless way. The STM8 chip has only one AD converter, and it is an 8-bit machine.

In addition to collecting and comparing electric potential, it is also necessary to collect, calculate and process analog signals such as bus voltage, bus current, heat sink temperature, potentiometer, etc.

This priority processing is very important. However, ST wrote the program very well, at least I think so. It puts different tasks into accurate time periods for collection and processing.
First post its core AD collection and processing and then analyze it.

 

#ifdef SENSORLESS 
 @near @interrupt @svlreg void ADC2_IRQHandler (void)
 {
  if (ADC_State == ADC_SYNC)
  {
   // Syncronous sampling
   
   u16 data;
   u8 delay;
   u16 bemf_threshold;

   // Reset bit
   bComHanderEnable = 0;
    
   //clear interrupt flag
   ADC2->CSR &= (u8)(~BIT7);
     
   //left align - read DRH first
   data = ADC2->DRH;
   data <<= 2;
   data | = (ADC2->DRL & 0x03);   
   
   switch( ADC_Sync_State )
   {
    case ADC_BEMF_INIT:
     ADC2->CSR = (u8)((Current_BEMF_Channel|BIT5));
     BEMF_Sample_Debounce = 0;
     Zero_Sample_Count = 0;
     ADC_Sync_State = ADC_BEMF_SAMPLE;
     SetSamplingPoint_BEMF();
    break;

    case ADC_BEMF_SAMPLE:
     //detect zero crossing
     if( Current_BEMF == BEMF_FALLING )
     {
      if( Z_Detection_Type == Z_DETECT_PWM_OFF )
      {
       bemf_threshold = BEMF_FALLING_THRESHOLD;
      }
      else
      {
       bemf_threshold = hNeutralPoint;
      }

      if (Ramp_Step > FORCED_STATUP_STEPS)
      {
       if( data <   bemf_threshold   )
       {
        Zero_Sample_Count++;
        BEMF_Sample_Debounce++;
        if( BEMF_Sample_Debounce >= BEMF_SAMPLE_COUNT )
        {
         hTim3Th -= hTim3Cnt;
         GetStepTime();
 
         SpeedMeasurement();

         bComHanderEnable = 1;

         BEMF_Sample_Debounce = 0;
        }
       }
       else
       {
        BEMF_Sample_Debounce = 0;
       }
      }
     }
     else
     {
      if( Z_Detection_Type == Z_DETECT_PWM_OFF )
      {
       bemf_threshold = BEMF_RISING_THRESHOLD;
      }
      else
      {
       bemf_threshold = hNeutralPoint;
      }
  
      if (Ramp_Step > FORCED_STATUP_STEPS)
      {
       (data>bemf_threshold)
       {
        Zero_Sample_Count++;
        BEMF_Sample_Debounce++;
        if( BEMF_Sample_Debounce >= BEMF_SAMPLE_COUNT )
        {
         hTim3Th -= hTim3Cnt;
         GetStepTime();
  
         SpeedMeasurement();

         bComHanderEnable = 1;

         BEMF_Sample_Debounce = 0;
        }
       }
       else
       {
        BEMF_Sample_Debounce = 0;
       }
      }
     }
    break;

    case ADC_CURRENT_INIT:
     ADC2->CSR = (ADC_CURRENT_CHANNEL|BIT5);
     ADC_Sync_State = ADC_CURRENT_SAMPLE;
     SetSamplingPoint_Current();
    break;

    default:
    case ADC_AVCURRENT_INIT:
     ADC2->CSR = (ADC_AVCURRENT_CHANNEL|BIT5);
     ADC_Sync_State = ADC_AVCURRENT_CHANNEL;// ADC_USER_SYNC_SAMPLE;
     SetSamplingPoint_AVCURRENT();
    break;

  
    case ADC_CURRENT_SAMPLE:
     ADC_Buffer[ ADC_CURRENT_INDEX ] = data;
     break;

    case ADC_AVCURRENT_SAMPLE:
     ADC_Buffer[ ADC_AVCURRENT_INDEX] = data;
     break;
   }

   // Store the current channel selected
   bCSR_Tmp = ADC2->CSR;

   // Set the Async sampling channel
   switch (ADC_Async_State)
   {
    default:
    case ADC_BUS_INIT:
     ADC2->CSR = (ADC_BUS_CHANNEL|BIT5);
     ADC_Async_State = ADC_BUS_SAMPLE;
    break;
    
    case ADC_TEMP_INIT:
     ADC2->CSR = (ADC_TEMP_CHANNEL|BIT5);
     ADC_Async_State = ADC_TEMP_SAMPLE;
    break;
   
    case ADC_USER_ASYNC_INIT:
     ADC2->CSR = (ADC_USER_ASYNC_CHANNEL|BIT5);
     ADC_Async_State = ADC_USER_ASYNC_SAMPLE;
    break;
   }

    // Disable ext. trigger
    ADC2->CR2 &= (u8)(~BIT6);
    //Start ADC sample
    ADC2->CR1 |= BIT0;


   ADC_State = ADC_ASYNC;
   
   if (bComHanderEnable == 1)
   {
    ComHandler();
   }
  }
  else
  {
   // Syncronous sampling
   u16 data;
   
   data = ADC2->DRH;
   data <<= 2;
   data |= (ADC2->DRL & 0x03 );

   //clear interrupt flag
   ADC2->CSR &= (u8)(~BIT7);

   // Restore the sync ADC channel
   ADC2->CSR = bCSR_Tmp;
 

    // Enable ext. trigger
    ADC2->CR2 |= BIT6;


   // Manage async sampling
   switch (ADC_Async_State)
   {
    default:
    case ADC_BUS_SAMPLE:
     ADC_Buffer[ ADC_BUS_INDEX ] = data;
     ADC_Async_State = ADC_TEMP_INIT;
    break;

    case ADC_TEMP_SAMPLE:
     ADC_Buffer[ ADC_TEMP_INDEX ] = data;
     ADC_Async_State = ADC_USER_ASYNC_INIT;
    break;

    case ADC_USER_ASYNC_SAMPLE:
     ADC_Buffer[ ADC_USER_ASYNC_INDEX ] = data;
     ADC_Async_State = ADC_BUS_INIT;
    break;
   }
   
   ADC_State = ADC_SYNC;    
  }
 }
#endif

 

I changed the above code a little bit, that is, to collect one more average current.

There are two types of AD acquisition, one is synchronous and the other is asynchronous. There are three acquisition channels in synchronous and three acquisition channels in asynchronous. The channels in synchronous are back EMF channel, instantaneous current, and average current. The channels in asynchronous acquisition are bus voltage, temperature value, and potentiometer.

Asynchronous acquisition is performed after synchronization is completed. Synchronous acquisition is triggered by channel 4 of TIM1.

Therefore, two analog signals are collected in each PWM cycle. The asynchronous collection channel has nothing to do with the ON and OFF states of PWM, so it is arranged in asynchronous collection. The back electromotive force in synchronous collection needs to be collected at a fixed time of PWM, either ON or OFF, depending on the zero-crossing comparison scheme of BEMF. The instantaneous current is generally collected at the TON moment. Because ST originally had a user channel for special PWM moments, I added the average current to this channel. In fact, the average current collection can also be put into asynchronous. It doesn't matter, the function is implemented without any problem.

 

In addition, the back-EMF channel in asynchronous acquisition is always set as the floating phase channel. Moreover, the back-EMF acquisition is between D and Z, that is, the asynchronous acquisition between the end of demagnetization and the zero crossing point is all back-EMF, while the instantaneous current acquisition is between Z and C, that is, the asynchronous acquisition between zero crossing and phase change is all instantaneous current. Therefore, the user's channel (average current) is between phase change and demagnetization.

 

 The sensorless solution of ST seems to be only applicable to industrial motors, such as motors with 4K speed under 4 pole pairs, so the starting parameters do not need to be changed. But if it is changed to a model aircraft motor, no matter how much the starting PWM is changed, it will never start successfully. Maybe I have found a trick, or maybe I have not set the right parameters. For high-speed motors, this kind of sensorless start may be reliable only by the frequency-boosting method. In the routines I wrote earlier, no matter what motor, the frequency-boosting method was used. No matter what motor, it can start normally, but the current in the starting process (about 1S) goes from large to small, at least it runs normally to the minimum current value.

Keywords:STM8 Reference address:STM8 MCKIT1.0 BLDC sensorless control acquisition implementation analysis

Previous article:How to use IIC bus
Next article:Active brake in stm8-MC KIT library

Recommended ReadingLatest update time:2024-11-23 01:39

STM8 PIN setting(output)
When setting the pin output, I wanted to set it to open-drain output and then output high and low. However, I found that it could not output high (initialized to open-drain low level), and it was always low. Later, I changed it to push-pull output, and it could output high and low. It's really interesting. I went to S
[Microcontroller]
STM8 PIN setting(output)
Code implementation of using STM8 to drive temperature and humidity sensor DHT11
Recently, I want to learn more about STM8, so I chose to write the temperature and humidity sensor DHT11 driver code from scratch. I encountered some problems and also gained some experience. I hope it will help friends who encounter similar problems, and I also hope to get your guidance on the shortcomings.   First,
[Microcontroller]
Code implementation of using STM8 to drive temperature and humidity sensor DHT11
STM8 IAR new register project
. 2. 3. 4. Add header file directory Convert to relative directory 5. Set the output file directory 6. Set up simulation tools
[Microcontroller]
STM8 IAR new register project
IAR for STM8 Errors
An IAR for STM8 v1.3 project has the following error after switching to version 1.4 unable to allocate space for sections/blocks with a total estimated minimum size of 0x2341 bytes in (total uncommitted space 0x1f80). Found the following article on the Internet, and in the project options, change the "Printf formatt
[Microcontroller]
IAR for STM8 Errors
Five working modes of STM8 ADC
Five working modes of STM8 ADC The ADC of STM8 is a 10-bit successive approximation analog-to-digital converter with up to 16 multifunctional input channels. It has 5 conversion modes and can generate an interrupt when the conversion is completed. The initialization sequence of the STM8 ADC is as follows: 1. The
[Microcontroller]
STM8 learning summary three: TIM1 timer usage
This article mainly summarizes the meaning of each statement when developing library functions of STM8. (1) TIM1 initialization configuration function The main function of the function is to set the parameters and working mode of the counter and enable it; void Tim1_Init(void) {   TIM1_TimeBaseInit(16,TIM1_COUNTER
[Microcontroller]
STM8 pulse width measurement - infrared routine
Example description: 1. This example uses the PWM input capture mode of the STM8 microcontroller timer TIM1 to measure the infrared remote control code. 2. The infrared remote control code format is NEC infrared coding. 3. The infrared receiving signal input is connected to PC1 (TIM1 input channel 1). 4. Use an extern
[Microcontroller]
STM8_TIM4 overflow interrupt
C language:  Code#11307 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Experimental platform: ST official three-in-one kit  + Hardware: STM8S105S6T6C + Development platform: IAR For STM8 1.10 + Emulator: ST-Link +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号