打印
[STM8]

STM8 MCKIT1.0 BLDC无感控制中的采集实现分析

[复制链接]
3885|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Fannymini|  楼主 | 2015-1-15 16:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ST写的STM8电机库中,可以用无感方式驱动BLDC。STM8芯片只有一个AD转换器,而且是8位机。库中要对反
电势采集,比较处理,还要进行母线电压,母线电流、散热片温度、电位器等模拟信号进行采集、运算和处理。
这优先级处理说起来是很重要的。不过,ST把程序写的很好,至少我这样认为。它把不同的任务放到准确的时间段里进行采集处理。
先把它核心AD采集处理帖出来再分析 。

#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

上面的代码我改了一点点,就是多采集了一路平均电流。
AD采集分两种,一个是同步,一个是异步。同步中有三个采集通道,异步中有三个采集通道。同步中的通道为反电势通道、瞬时电流、平均电流。异步采集中通道为母线电压、温度值、电位器。
异步采集是在同步完成后进行的。同步采集是通过TIM1的通道4触发采集。
所以每个PWM周期采集2路模拟信号。异步采集的通道与PWM的ON与OFF状态无关,所以安排在异步采集中。同步采集中的反电势需要在PWM固定时刻采集,或ON或OFF,看BEMF的过零比较方案。瞬时电流一般在TON时刻采集。因为原来ST有PWM特殊时刻做了一路用户通道中,所以我就把平均电流加到这一通道上了。其实平均电流采集也可以放到异步中。无所谓了,功能实现是没问题的。

另外,异步采集中的反电势通道一直是设为浮空相的通道的。而且反电势的采集在D与Z之间,即退磁结束与过零点之间进行的异步采集均为反电势,而瞬时电流的采集是在Z与C之间,即过零与换相之间进行的异步采集均为瞬时瞬时电流。所以用户的通道(平均电流)就是在换相与退磁之间了。

ST的无感方案,启动方案感觉只能针对工业用电机,像在4极对下4K转速的电机,那启动参数不用怎么改。但如果改为航模电机,无论启动PWM改为多少,总是不能启动成功。可能是我还找到巧门,也可能没设对参数,对于高速电机,像这种无感启动可能是升频升压法启动才可靠。我早期写的例程,无论什么电机,用的是升频升压法,无论什么电机,都可以正常启动,只是启动过程(大约1S)电流从大到小,,至少正常运行至最小电流值。
沙发
搞IT的| | 2015-1-15 21:48 | 只看该作者
没有硬件电路图吗?、?

使用特权

评论回复
板凳
Fannymini|  楼主 | 2015-1-16 14:41 | 只看该作者
搞IT的 发表于 2015-1-15 21:48
没有硬件电路图吗?、?

没有

使用特权

评论回复
地板
luoge2003| | 2015-1-17 22:16 | 只看该作者
这个代码在库文件的那个文件下?

使用特权

评论回复
5
Fannymini|  楼主 | 2015-1-19 18:11 | 只看该作者
luoge2003 发表于 2015-1-17 22:16
这个代码在库文件的那个文件下?

在《无刷直流电机控制应用——基于STM8S系列单片机》这本书上有代码的下载连接及原理图

使用特权

评论回复
6
Fannymini|  楼主 | 2015-1-19 18:14 | 只看该作者
Fannymini 发表于 2015-1-16 14:41
没有

如果有《无刷直流电机控制应用——基于STM8S系列单片机》这本书,您可以在书中第七章讲找到原理图及代码

使用特权

评论回复
7
搞IT的| | 2015-1-30 16:16 | 只看该作者
Fannymini 发表于 2015-1-16 14:41
没有

呵呵,好吧

使用特权

评论回复
8
Fannymini|  楼主 | 2015-1-31 11:04 | 只看该作者
搞IT的 发表于 2015-1-30 16:16
呵呵,好吧

有兴趣的话可以在当当网上购买这本书:)

使用特权

评论回复
9
搞IT的| | 2015-2-14 19:06 | 只看该作者
Fannymini 发表于 2015-1-31 11:04
有兴趣的话可以在当当网上购买这本书

好的

使用特权

评论回复
10
wolff_dg| | 2016-7-7 15:36 | 只看该作者
请教楼主,使用该库,我的硬盘电机 只能在PWM OFF 情况下采样反电动势工作。 在PWM ON 的情况下无**常工作,启动失败。不知道是什么原因。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:从事STM32/STM8开发板、电机套件、手机周边产品开发,技术交流群:19043725。https://fretech.taobao.com

53

主题

162

帖子

7

粉丝