ST寫的STM8電機庫中,,可以用無感方式驅動BLDC。STM8芯片只有一個AD轉換器,而且是8位機,。庫中要對反
電勢采集,,比較處理,,還要進行母線電壓,,母線電流,、散熱片溫度,、電位器等模擬信號進行采集,、運算和處理,。
這優(yōu)先級處理說起來是很重要的。不過,,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觸發(fā)采集,。
所以每個PWM周期采集2路模擬信號。異步采集的通道與PWM的ON與OFF狀態(tài)無關,,所以安排在異步采集中,。同步采集中的反電勢需要在PWM固定 時刻采集,或ON或OFF,,看BEMF的過零比較方案,。瞬時電流一般在TON時刻采集。因為原來ST有PWM特殊時刻做了一路用戶通道中,,所以我就把平均 電流加到這一通道上了,。其實平均電流采集也可以放到異步中。無所謂了,,功能實現(xiàn)是沒問題的,。
另外,異步采集中的反電勢通道一直是設為浮空相的通道的,。而且反電勢的采集在D與Z之間,,即退磁結束與過零點之間進行的異步采集均為反電勢,而瞬時 電流的采集是在Z與C之間,,即過零與換相之間進行的異步采集均為瞬時瞬時電流,。所以用戶的通道(平均電流)就是在換相與退磁之間了,。
ST的無感方案,啟動方案感覺只能針對工業(yè)用電機,,像在4極對下4K轉速的電機,,那啟動參數(shù)不用怎么改。但如果改為航模電機,,無論啟動 PWM改為多少,,總是不能啟動成功??赡苁俏疫€找到巧門,,也可能沒設對參數(shù),對于高速電機,,像這種無感啟動可能是升頻升壓法啟動才可靠,。我早期寫的例程, 無論什么電機,,用的是升頻升壓法,,無論什么電機,都可以正常啟動,,只是啟動過程(大約1S)電流從大到小,,,至少正常運行至最小電流值,。