《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 解決方案 > STM8 MCKIT1.0 BLDC無(wú)感控制中的采集實(shí)現(xiàn)分析

STM8 MCKIT1.0 BLDC無(wú)感控制中的采集實(shí)現(xiàn)分析

2016-05-19
關(guān)鍵詞: BLDC

       ST寫(xiě)的STM8電機(jī)庫(kù)中,,可以用無(wú)感方式驅(qū)動(dòng)BLDC,。STM8芯片只有一個(gè)AD轉(zhuǎn)換器,,而且是8位機(jī)。庫(kù)中要對(duì)反

電勢(shì)采集,,比較處理,,還要進(jìn)行母線電壓,母線電流,、散熱片溫度,、電位器等模擬信號(hào)進(jìn)行采集、運(yùn)算和處理,。

這優(yōu)先級(jí)處理說(shuō)起來(lái)是很重要的,。不過(guò),ST把程序?qū)懙暮芎?,至少我這樣認(rèn)為,。它把不同的任務(wù)放到準(zhǔn)確的時(shí)間段里進(jìn)行采集處理。
先把它核心AD采集處理帖出來(lái)再分析 ,。

#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)
      {
       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;
       }
      }
     }
    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

 

上面的代碼我改了一點(diǎn)點(diǎn),,就是多采集了一路平均電流。

AD采集分兩種,,一個(gè)是同步,,一個(gè)是異步。同步中有三個(gè)采集通道,,異步中有三個(gè)采集通道,。同步中的通道為反電勢(shì)通道、瞬時(shí)電流,、平均電流,。異步采集中通道為母線電壓、溫度值,、電位器。

異步采集是在同步完成后進(jìn)行的,。同步采集是通過(guò)TIM1的通道4觸發(fā)采集,。

所以每個(gè)PWM周期采集2路模擬信號(hào)。異步采集的通道與PWM的ON與OFF狀態(tài)無(wú)關(guān),,所以安排在異步采集中,。同步采集中的反電勢(shì)需要在PWM固定 時(shí)刻采集,或ON或OFF,,看BEMF的過(guò)零比較方案,。瞬時(shí)電流一般在TON時(shí)刻采集,。因?yàn)樵瓉?lái)ST有PWM特殊時(shí)刻做了一路用戶通道中,所以我就把平均 電流加到這一通道上了,。其實(shí)平均電流采集也可以放到異步中,。無(wú)所謂了,功能實(shí)現(xiàn)是沒(méi)問(wèn)題的,。

另外,,異步采集中的反電勢(shì)通道一直是設(shè)為浮空相的通道的。而且反電勢(shì)的采集在D與Z之間,,即退磁結(jié)束與過(guò)零點(diǎn)之間進(jìn)行的異步采集均為反電勢(shì),,而瞬時(shí) 電流的采集是在Z與C之間,即過(guò)零與換相之間進(jìn)行的異步采集均為瞬時(shí)瞬時(shí)電流,。所以用戶的通道(平均電流)就是在換相與退磁之間了,。

ST的無(wú)感方案,啟動(dòng)方案感覺(jué)只能針對(duì)工業(yè)用電機(jī),,像在4極對(duì)下4K轉(zhuǎn)速的電機(jī),,那啟動(dòng)參數(shù)不用怎么改。但如果改為航模電機(jī),,無(wú)論啟動(dòng) PWM改為多少,,總是不能啟動(dòng)成功??赡苁俏疫€找到巧門(mén),,也可能沒(méi)設(shè)對(duì)參數(shù),對(duì)于高速電機(jī),,像這種無(wú)感啟動(dòng)可能是升頻升壓法啟動(dòng)才可靠,。我早期寫(xiě)的例程, 無(wú)論什么電機(jī),,用的是升頻升壓法,,無(wú)論什么電機(jī),都可以正常啟動(dòng),,只是啟動(dòng)過(guò)程(大約1S)電流從大到小,,,至少正常運(yùn)行至最小電流值,。

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn),。轉(zhuǎn)載的所有的文章,、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有,。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者,。如涉及作品內(nèi)容,、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,,以便迅速采取適當(dāng)措施,,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118,;郵箱:[email protected],。