基于CW32F030C8T6的無刷直流電機(jī)
本項目設(shè)計三塊板子,(為什么我會這么設(shè)計:首先,當(dāng)時主要是不想把芯片集成上去了!希望主控一塊板子,以后也可以玩一些外設(shè)什么的,不至于焊接到電機(jī)板子上去;其次,我最初是打算做CW32F030C8T6的FOC控制的,我的驅(qū)動板也做了FOC的一款,還在測試,需要一段時間再分享,最近學(xué)校也比較忙,所以一直耽擱著了,后期會努力做完,這次還是先把基本的BLDC六步換向驅(qū)動先完成;最后,我的設(shè)計思路大家可以參考,也可以將其全部繼承上一塊板子,都可以的,完全沒問題!)
1、主控板:首先主要是USB供電、經(jīng)過LDO降壓成3.3V,為芯片供電,值得注意的是:該芯片是一個寬電壓范圍的芯片,可以直接供電5V!其次,通過芯片引腳引出了SWD接口和UART接口,方便下載程序和上位機(jī)打印數(shù)據(jù);最后,板載按鍵復(fù)位電路,添加硬件消抖,保證按鍵穩(wěn)定。
2、承接板:該電路主要包括:蜂鳴器電路、LED燈電路、OLED顯示電路、按鍵電路、旋鈕電位器電路以及2×17P牛頭排母座;起到承接主控板和驅(qū)動板的作用。
3、驅(qū)動板:該電路主要包括:電源電路、驅(qū)動電路、電流采樣電路、霍爾信號電路、反電動勢電路、電機(jī)接口層電路以及測溫層電路;主要起到大功率驅(qū)動的作用。
接下來我介紹一下我的硬件部分,軟件部分會粘貼部分關(guān)鍵信息,其他請參考UET李芳老師分享的例程!在此,感謝李芳姐姐!!!
硬件部分
選型
電源部分
24VBuck部分
問題1:主電源最低電壓是多少?負(fù)載電流需要多大?
答:本項目采用57直流無刷電機(jī),其額定電壓為:24V(DC);額定電流為:5.9A;空載電流為:0.8A;額定轉(zhuǎn)速為2500RPM;因此,主電源供電部分需大于等于24V,負(fù)載電流要大于0.8×3=2.4A以上,留有閾值,選擇負(fù)載輸出電流3A,降壓型電路。

經(jīng)過上述篩選,我們可以看到,符合條件的有19款,我們按價格升序、選擇現(xiàn)貨商品。進(jìn)一步觀看IC的相關(guān)描述,在考慮價格的基礎(chǔ)上,還要考慮是否符合我們的要求。

我這邊看到了一款芯龍的Buck芯片,價格也能接受,庫存也特別豐富,最主要的是:芯龍是國產(chǎn)芯片!!!不用考慮了,就這款了。
OK,選擇好芯片后,進(jìn)入數(shù)據(jù)手冊讀取相關(guān)參數(shù)。

我們可以知道的是:
輸入電壓范圍是:4.5V-40V。 我們輸入是24V,完全滿足裕量和要求。
輸出電壓范圍是:1.23V-37V。 我們輸出是10V-20V,也完全滿足裕量和要求。
輸出電流是:3A。 我們需要的也是2.4A以上的電路,3A完全滿足要求。
開關(guān)頻率:150KHz。 還可以,這個速度。

我們從描述中可以知道:
1、輸入引腳,需要放置一個合適的大容量電容,去消除輸入噪聲。
2、GND引腳在布局的時候需要考慮到:GND引腳需要放置在肖特基二極管到輸出電容地路徑的外部,以防止開關(guān)電流尖峰感應(yīng)產(chǎn)生電壓噪聲。
3、反饋電壓是:1.23V.
4、ON/OFF引腳如果懸空,默認(rèn)低電平。該引腳低電平則芯片工作,若高電平則芯片不工作。

我們從描述中可以知道:
1、R1采用接近1K歐姆的電阻,使用1%的精度。
2、C1和CFF是可選擇的,為了提高穩(wěn)定性、降低供電噪聲。CIN和C1必須靠近放置在引腳1和引腳3。
3、對于輸出電壓高于10V的情況,CFF電容是需要的,此時的CFF是作為補(bǔ)償電容使用,與R2并聯(lián)使用,其值在100pf到33nf之間。CFF的電容值等于(1/(31×1000×R2))。

綜上所述,我們選型參數(shù)為:
CIN:容值為180uf,耐壓為大于(24×2=48)V;
C1:容值為10×10^5pf=1uf,耐壓為50V;
CFF:容值為1nf,耐壓為50V;
R1:阻值為1K歐姆,精度為1%;
R2:阻值為:(1+R2/R1)*1.23=Vout--->R2等于8.76K歐姆。
COUT:容值為180uf,耐壓為大于(12×2)=24V;
L1:感值為68uH;
D1:肖特基二極管采用DSK34。
因此24V將壓成12V的整體方案為:

12VBuck部分
考慮到霍爾傳感器的工作電壓是5V,因此需要將12V再Buck變換成5V。本項目采用首鼎的SD8942,至于為什么選擇它,因為我買了好多這個物料,庫存很多,不能浪費(fèi)錢。。。而且這個12V將壓成5V的方案我也驗證過,沒什么問題,最主要的是:肖特基二極管都不需要,外圍電路很簡單。

我們從描述中可以知道:
1、輸入電壓范圍為:4.5V-16V 我們輸入電壓是12V,滿足要求。
2、開關(guān)頻率600KHz 開關(guān)頻率速度快。
3、輸出電流:2A 電機(jī)空載電流0.8A,2倍裕量,滿足要求。
4、不需要肖特基二極管,內(nèi)部集成 節(jié)省成本。
5、芯片效率:96% 效率高。
6、參考電壓:0.6V 方便計算回饋電阻阻值。
典型應(yīng)用中就給出了一個輸出5V/2A的基本電路,我們可以直接采用。沒什么比較特殊的,主要是電容耐壓高點(diǎn)就好,其他的沒什么考慮的。因此,最終電路圖如下所示:

因此電源部分已經(jīng)整體解決完畢。
驅(qū)動硬件部分
我們想開環(huán)驅(qū)動無刷直流電機(jī)的話,需要使用到什么功能?
1、供電電源部分:24V供電機(jī);12V供MOS驅(qū)動電路;5V供霍爾驅(qū)動電路;以及主控芯片的供電
2、主控芯片:發(fā)送6路PWM信號以及3路霍爾傳感器的檢測信號;
3、MOS驅(qū)動電路+三相全橋電路;
4、電位器電路,通過旋鈕控制速度;
5、OLED顯示功能電路
6、電流采樣部分
因此我們不妨從這幾個電路進(jìn)行入手分析,值得注意的是:主控芯片以及供電電源部分我們不再分析,電源在上面已經(jīng)分析過了,主控芯片則是采用武漢芯源半導(dǎo)體研發(fā)的CW32F030C8T6;
MOS驅(qū)動電路

我們采用的MOS驅(qū)動芯片是EG3013,為什么選擇它?你自己看吧:(上次實(shí)驗室做實(shí)驗,需要柵極驅(qū)動IC,就買了好多個,最后板子做出來焊接完畢后我才發(fā)現(xiàn),李芳姐用的柵極驅(qū)動IC竟然也是這顆物料!)

該芯片的LIN是一個低電平有效的引腳!在程序中,有一個關(guān)于AL、BL、CL打開或關(guān)閉的GPIO配置,這里就是相反的邏輯!!!所以各位使用的時候根據(jù)自己的IC進(jìn)行修改即可!
FR107是為了加快開通效率的,用肖特基二極管也可以!但是官方用的FR107,這顆物料我在做動量倫的時候也買了的,所以我就按照官方的做就行了。10uF是升壓電容,這個阻值是我問屹晶微電子有限公司的一個技術(shù)人員,他告訴我,一般用10uf就足夠了!這里建議使用封裝為1206的,保證功率!我電路中用的0805,我的物料只有0805了....使用起來沒什么問題,我驗證過了!最后就是上下MOS的驅(qū)動信號了,加上電阻和二極管是為了防止寄生電容和回路電感!!!減小振鈴現(xiàn)象。加上一個R組成RLC電路,可以吸收寄生參數(shù);而二極管主要是提供一個續(xù)流通道。具體可參考視頻:https://b23.tv/9a7pe1Q
三相全橋電路

此處的NMOS選用的是:

我主要是考慮電壓和電流要大一點(diǎn),RDS小一點(diǎn),防止發(fā)熱嚴(yán)重。最后就是考慮價格問題。
電流采樣電路

型號為:

價格便宜!!!其次其最大能過的電流為:2/0.01=20A!我們平常哪有這么高電壓喲,有個5A、6A的對我這種小白而言,就要關(guān)閘了!!!哈哈
霍爾接口電路

其中:C14、C15、C16是濾波作用;R3、R4、R5是為了拉高三個霍爾信號引腳,因為120°的霍爾傳感器不存在111的情況,也是一種保護(hù)作用吧!我這里沒選擇5Pin的接口端子是因為我只有3P和2P的物料,不想再買了....
以上的電路,足以跑起開環(huán),下面就是閉環(huán)的一些保護(hù)功能,比如:電流檢測、電壓保護(hù)、溫度保護(hù)等等。我就不一一解釋其工作原理了,這個電路圖是李芳老師的書本里面的,書里面描述的更詳細(xì),需要的可以在附件進(jìn)行下載!我就不在這獻(xiàn)丑了!我這里就簡單展示一下原理圖即可,具體如何工作的書中有所描述。
運(yùn)放電路

這個運(yùn)放書中一摸一樣,具體的放大倍數(shù)以及工作原理請參考書籍:無刷直流電機(jī)控制應(yīng)用 基于STM8S系列單片機(jī)
值得注意的是:這里面關(guān)乎到程序的采樣問題,一定要弄明白!我在程序中有寫那些數(shù)值是如何算出來的!

這都是一些閉環(huán)時加的保護(hù)電路,很簡單,相信你可以自己分析。
反電動勢檢測電路

這個電路關(guān)乎到無感驅(qū)動電機(jī)的時候使用。這個數(shù)值也是有講究的,請將這個電路對比檢測母線電壓電路,你會發(fā)現(xiàn)系數(shù)的關(guān)系,這個關(guān)系需要應(yīng)用到無感電路中去!
整個電路都沒改動,都是參考:立創(chuàng)開源硬件平臺:Beauty_Light,在此感謝大佬的硬件電路參考設(shè)計!!!
軟件部分
有感開環(huán)
在開環(huán)測試中,最主要的就是需要根據(jù)霍爾換向表進(jìn)行換向操作,只要換向無誤,其他就是改變占空比加減速的問題,因此最為重要的就是真值表,比如李芳姐姐官方的真值表如下所示:

你就需要根據(jù)你電機(jī)廠商給你的真值表進(jìn)行相應(yīng)的改變,這里貼出我電機(jī)的真值表:

代表什么意思呢?
比如HC HB HA = 100時,表示需要導(dǎo)通V相的上橋臂和W相的下橋臂,U相處于關(guān)閉狀態(tài)!其他類比如此,因此只需要改改程序的換向順序即可讓電機(jī)完美的跑起來,代碼如下所示:
//steP,為當(dāng)前換相序號,OutPwmValue 輸出PWM值,PWM_ON_flag=1時啟動PWM輸出
void Commutation(unsigned int step,unsigned int OutPwmValue,unsigned int PWM_ON_flag)
{
if(PWM_ON_flag==0) //不啟動則關(guān)閉輸出
{
CW_ATIM->CH1CCRA=0;CW_ATIM->CH2CCRA=0;CW_ATIM->CH3CCRA=0;
ATIM_CtrlPWMOutputs(DISABLE);
PWM_AL_OFF; PWM_BL_OFF; PWM_CL_OFF;
return;
}
//關(guān)閉所有下橋臂,防止誤觸發(fā)
PWM_AL_OFF; PWM_BL_OFF; PWM_CL_OFF;
//輸出上橋
if(step==0||step==1){ CW_ATIM->CH1CCRA=OutPwmValue;CW_ATIM->CH2CCRA=0;CW_ATIM->CH3CCRA=0; } //0:AB; 1:AC
if(step==2||step==3){ CW_ATIM->CH1CCRA=0;CW_ATIM->CH2CCRA=OutPwmValue;CW_ATIM->CH3CCRA=0; } //2:BC; 3:BA
if(step==4||step==5){ CW_ATIM->CH1CCRA=0;CW_ATIM->CH2CCRA=0;CW_ATIM->CH3CCRA=OutPwmValue; } //3:CA; 4:CB
//輸出下橋
if(step==0||step==5){PWM_AL_OFF; PWM_CL_OFF;PWM_BL_ON;} //AB CB ; B下橋?qū)?/p>
else if(step==1||step==2){ PWM_AL_OFF; PWM_BL_OFF; PWM_CL_ON;}//AC BC; C下橋?qū)?/p>
else if(step==3||step==4){ PWM_BL_OFF; PWM_CL_OFF; PWM_AL_ON;}//BA CA; A下橋?qū)?/p>
ATIM_CtrlPWMOutputs(ENABLE); //輸出有效
}
值得注意的是,不同電機(jī)使用時還需要改這個換向順序,根據(jù)你自身電機(jī)導(dǎo)通的順序而定!
//const unsigned char STEP_TAB[6]={1,3,2,5,0,4};//{4,0,5,2,3,1};//
//自己電機(jī)順序
const unsigned char STEP_TAB[6]={4,0,5,2,3,1};//{4,0,5,2,3,1};//
有感閉環(huán)
閉環(huán)例程相對而言,復(fù)雜一點(diǎn)點(diǎn),不過李芳老師講的很仔細(xì),相信大家理解起來也不是很困難!該例程主要用到了狀態(tài)機(jī)進(jìn)行電機(jī)的控制作用,主要分為:電機(jī)起步檢測狀態(tài)、開始PID狀態(tài)、運(yùn)行PID狀態(tài)、停止?fàn)顟B(tài)、錯誤狀態(tài)、錯誤溢出狀態(tài)。代碼如下:
/******************** 核心函數(shù):狀態(tài)機(jī) *********************/
switch(MOTORSTATE)//狀態(tài)機(jī)
{
case STATESTARTCHECK: //起步檢查階段,判斷按鍵PB5是否按下,按下啟動,進(jìn)入這個函數(shù),否則不進(jìn)入無法啟動電機(jī)
EnDirCheck(); //判斷PB5是否按下
MotorStartCheck();//是否成功啟動電機(jī),是的話進(jìn)入下一個狀態(tài)MOTORSTATE=STATESTARTPID;
break;
case STATESTARTPID:
MotorStartPID();//電機(jī)啟動成功,初始化PID并計算PID,再進(jìn)入下一個狀態(tài)MOTORSTATE=STATERUNPID;
break;
case STATERUNPID:
MotorRunPID();//運(yùn)行PID計算
EnDirCheck();
break;
case STATESTOP:
MotorStop();//停止電機(jī)函數(shù)
break;
case STATEERROR:
sprintf(temp_buff," ERROR Happen! "); //輸出顯示故障發(fā)生
sprintf(temp_buff1," CODE is: %d ",ErrorCode); //顯示故障發(fā)生錯誤代碼
OLED_ShowStr(0,0,temp_buff,2);
OLED_ShowStr(0,4,temp_buff1,2);
MotorError();//停止電機(jī)運(yùn)行,并進(jìn)入錯誤溢出MotorErrorOver狀態(tài)機(jī)
break;
case STATEERROROVER:
MotorErrorOver();
break;
}
值得注意的是:該例程代碼還用了切換界面的函數(shù),又學(xué)到了一點(diǎn),哈哈!也就是通過按鍵PB4進(jìn)行OLED的菜單切換,確實(shí)很棒!
想要理解該例程,就需要將control.c文件讀懂!這樣理解起來沒什么問題。
#include "control.h"
extern unsigned char save_flag;
extern void Flash_Save(void);
void MotorStartCheck(void)
{
if(MOTORSTATE==STATEERROR)return;
if(SetSpeed>0&&startflag==1)
{
MOTORSTATE=STATESTARTPID;
Dir=dirflag;
}
}
void MotorStartPID(void)
{
if(MOTORSTATE==STATEERROR)
return;
PID_init();
PIDcompute(MINSPEED,0);
HALL_MOTOR_START();
TargS1=SetSpeed;
MOTORSTATE=STATERUNPID;
}
void MotorRunPID(void)
{
if(MOTORSTATE==STATEERROR)return;
if(SetSpeed==0||startflag==0) //給出停止信號
{
MOTORSTATE=STATESTOP;
}
TargS1=SetSpeed;
if(TimeCountPID>=20)//計算實(shí)時速度并時行PID運(yùn)算
{
TimeCountPID=0;
RealS1=HALLcountTemp*500/MPolePairs;//HALLcount*100*60/6/POLEPAIRS;
PIDcompute(TargS1,RealS1);
}
}
void MotorStop(void)
{
if(MOTORSTATE==STATEERROR)return;
Motor_Start_F=0;
MOTOR_STOP0();
if(RealS==0)
{
MOTORSTATE=STATESTARTCHECK; //停下來后才切換流程
}
}
void MotorError(void)
{
MOTOR_STOP0();//停止電機(jī)
Motor_Start_F=0;//電機(jī)啟停標(biāo)志位至0
MOTORSTATE=STATEERROROVER;//進(jìn)入錯誤溢出狀態(tài)機(jī)中
}
void MotorErrorOver(void)
{
unsigned char times=0;
times=0;
LEDOFF();
TimeCountTemp=0;
while(TimeCountTemp<200);//延時200ms
while(1) //發(fā)生故障,則故障指示燈閃爍。需重啟
{
if(times
{
if(TimeCountTemp<200)
{
LEDON();
}
else if(TimeCountTemp<=400)//LED flashing
{
LEDOFF();
}
else if(TimeCountTemp>400)
{
if(times
{
times++;
TimeCountTemp=0;
if(times>=ErrorCode);
else LEDOFF();
}
}
}
else if(TimeCountTemp<500);
else {times=0;TimeCountTemp=0;}
}
}
void WaitStart(void)
{
if(SetSpeed==0)MOTORSTATE=STATESTARTCHECK;
}
void EnDirCheck(void)
{
unsigned int dd;
static unsigned char key_dir=0,key_en=0;
if(MOTORSTATE==STATEERROR)return;
if(GPIO_ReadPin(EN_GPIO_PORT,EN_GPIO_PIN)==GPIO_Pin_SET)key_en=0; //使能判斷
else if(key_en==0)
{
for(dd=0;dd<500;dd++); //消抖
if(GPIO_ReadPin(EN_GPIO_PORT,EN_GPIO_PIN)==GPIO_Pin_RESET)
{
startflag=1-startflag;
if(startflag==0)
GPIO_WritePin(LEDSTSTO_GPIO_PORT,LEDSTSTO_GPIO_PIN,GPIO_Pin_SET); //啟停指示燈滅
else
GPIO_WritePin(LEDSTSTO_GPIO_PORT,LEDSTSTO_GPIO_PIN,GPIO_Pin_RESET); //啟停指示燈滅
key_en=1;
}
}
// if(GPIO_ReadPin(DR_GPIO_PORT,DR_GPIO_PIN)==GPIO_Pin_SET)key_dir=0; //方向判斷
// else if(key_dir==0)
// {
// for(dd=0;dd<500;dd++); //消抖
// if(GPIO_ReadPin(DR_GPIO_PORT,DR_GPIO_PIN)==GPIO_Pin_RESET)
// {
// dirflag=1-dirflag;
// if(dirflag==0)
// GPIO_WritePin(LEDDIR_GPIO_PORT,LEDDIR_GPIO_PIN,GPIO_Pin_RESET); //方向指示燈亮
// else
// GPIO_WritePin(LEDDIR_GPIO_PORT,LEDDIR_GPIO_PIN,GPIO_Pin_SET); //方向指示燈亮
// if(dirflag!=Dir)
// MOTORSTATE=STATESTOP;
// key_dir=1;
// }
// }
}
該函數(shù)主要是一些變量的賦值,狀態(tài)機(jī)的切換,以及PID的運(yùn)算功能函數(shù)!
我這里對于采樣部分、過流、過壓保護(hù)部分進(jìn)行了詳細(xì)的注釋,大家可以看看。
#include "compu.h"
/******************** 對電機(jī)速度進(jìn)行獲取 *********************/
void SampleSpeed(void)
{
//根據(jù)電位器的值,計算設(shè)定速度,注意最大速度和最小速度的定義
unsigned int tem=0;
unsigned int st=0;
/******************** 讀取ADC采取到的旋鈕開關(guān)值 *********************/
st=SampleData[3];
/******************** 如果讀取到的旋鈕值小于旋鈕最小值-10的話,則停止電機(jī)運(yùn)行,給定目標(biāo)速度為0 *********************/
if(st
SetSpeed=0;
/******************** 如果小于等于最小值,啥也不做 *********************/
else if(st<=NMINVD);
/******************** 如果小于最大值的話,那就代表希望電機(jī)運(yùn)行起來 *********************/
else if(st<=NMAXVD)
{
tem=MINSPEED+KKN*(st-NMINVD);//根據(jù)旋鈕值,給定目標(biāo)值!
SetSpeed=tem;
}
/******************** 如果旋鈕值大于最大的旋鈕值,那速度給定最大速度 *********************/
else SetSpeed=MAXSPEED;
}
/******************** 對電壓電流進(jìn)行采集 *********************/
void SampleVI(void)
{
float t;
//定義電流故障計數(shù)周期變量、電流故障計數(shù)周期變量
static unsigned char IErCount=0,VErCount=0;
/******************** 下面是對采樣電流進(jìn)行措施分析 *********************/
if(SampleData[2]<=DIin)//如果采樣到的電流值小于偏置值,將母線平均電流賦值給0
CanshuI=0;
else //否則是采樣到的電流值大于偏置值
{
t=(SampleData[2]-DIin); //采樣量減去偏置量,求取變化量
//t表示ADC采樣的原始值,最大為4096;
//相對應(yīng)的ADC=t時,電壓量為x,而ADC=4096時對應(yīng)的電壓量為3.3V(這里因為是單位原因,電流是ma,所以電壓*1000了的)
//因此x=t/4096*3300,這個是電壓值,要求電流,根據(jù)歐姆定律,U/R即可,4.3是運(yùn)放的放大倍數(shù)!
t=t*1.61;// /t=t/4096*3300/4.3/0.1; //0.1歐
CanshuI=t;
}
/******************** 過流保護(hù),如果電流大于8A,則啟動保護(hù),停止電機(jī)運(yùn)行! *********************/
if(CanshuI>=ISH*1000&&ErrorCode==0) //過流保護(hù)
{
IErCount++;//電流過流錯誤計數(shù)變量遞增,如果大于設(shè)定的最大誤差變量,則給定錯誤代碼,停止電機(jī)
if(IErCount>=NumErr)
{ErrorCode=4;}//過流保護(hù)的故障代碼是:4
}
else IErCount=0;
/******************** 下面是對采樣母線電壓進(jìn)行措施分析 *********************/
t =SampleData[0];//讀取采樣到的母線電壓
//t表示ADC采樣的原始值,最大為4096;
//相對應(yīng)的ADC=t時,電壓量為x,而ADC=4096時對應(yīng)的電壓量為3.3V
//因此x=t/4096*3.3,這個是電壓值
t=t/4096*3.3/RV1*(RV1+RV2);
CanshuV=t*10; //采集母線電壓放大10倍
/******************** 過壓保護(hù),如果電壓大于40V,則啟動保護(hù),停止電機(jī)運(yùn)行! *********************/
if(CanshuV>=VSH*10&&ErrorCode==0) //過壓判斷
{
VErCount++;
if(VErCount>=NumErr)
{ErrorCode=6;}//過壓保護(hù)的故障代碼是:6
}
else VErCount=0;
}
其他.c文件這里就不再分析,相信大家能夠看懂。
無感開環(huán)
該例程去除了霍爾換向的繁瑣操作,采用反電動勢過零點(diǎn)進(jìn)行位置檢測。
該例程中ADC的功能較為復(fù)雜,需要大家多花時間分析,無感控制是大趨勢,非常建議大家多研究研究
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStruct;
DMA_InitTypeDef DMA_InitStruct = {0};
__RCC_GPIOA_CLK_ENABLE();
__RCC_GPIOB_CLK_ENABLE();
__RCC_ADC_CLK_ENABLE();
//配置ADC測試IO口
PA00_ANALOG_ENABLE() ; //PA00 (AIN0) U相反電動勢
PA01_ANALOG_ENABLE() ; //PA01 (AIN1) V相反電動勢
PA03_ANALOG_ENABLE() ; //PA03 (AIN3) 母線電壓
PA05_ANALOG_ENABLE() ; //PA05 (AIN5) W相反電動勢
PA06_ANALOG_ENABLE() ; //PA06 (AIN6) 電流
PB00_ANALOG_ENABLE() ; //PB00 (AIN8) 電位器
ADC_InitStruct.ADC_AccEn = ADC_AccDisable;//不需要累加器
ADC_InitStruct.ADC_Align = ADC_AlignRight;//右對齊
ADC_InitStruct.ADC_ClkDiv = ADC_Clk_Div8; // ADCCLK=16MHz
ADC_InitStruct.ADC_DMAEn = ADC_DmaEnable;//使能DMA
ADC_InitStruct.ADC_InBufEn = ADC_BufDisable;//失能緩沖
ADC_InitStruct.ADC_OpMode = ADC_SingleChOneMode;//單次轉(zhuǎn)換模式
ADC_InitStruct.ADC_SampleTime = ADC_SampTime10Clk;//采樣頻率
ADC_InitStruct.ADC_TsEn = ADC_TsDisable;//內(nèi)置溫度傳感器失能
ADC_InitStruct.ADC_VrefSel = ADC_Vref_VDDA;//參考電壓 選用VDDA
ADC_Init(&ADC_InitStruct);
CW_ADC->CR1_f.CHMUX = 0; // AN0
ADC_Enable();
// 使用4路DMA通道:CH1、CH2、CH3、 CH4
// CH1 將ADC單次單通道的采樣結(jié)果傳入RAM(ADC_ResultBuff[6])
// CH2 將ADC的CR1寄存器的配置值從RAM(ADC_CR1Array)傳入寄存器
// CH3 將ADC的START寄存器的配置值從RAM(ADC_Start)傳入寄存器
// CH1、CH2、CH3由ADC硬件觸發(fā)
// CH4由ATIM硬件觸發(fā),啟動ADC
//開啟DMA時鐘
__RCC_DMA_CLK_ENABLE();
DMA_InitStruct.DMA_DstAddress = (uint32_t)&SampleData[0]; // 目標(biāo)地址
DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Increase; // 目標(biāo)地址遞增
DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK; // BLOCK傳輸模式
DMA_InitStruct.DMA_SrcAddress = (uint32_t)&CW_ADC->RESULT0; // 源地址: ADC的結(jié)果寄存器
DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix; // 源地址固定
DMA_InitStruct.DMA_TransferCnt = 0x6; // DMA傳輸次數(shù)
DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_16BIT; // 數(shù)據(jù)位寬16bit
DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_TRANSCOMPLETE; // ADC轉(zhuǎn)換完成硬觸發(fā)
DMA_InitStruct.TrigMode = DMA_HardTrig; // 硬觸發(fā)模式
DMA_Init(CW_DMACHANNEL1, &DMA_InitStruct);
DMA_Cmd(CW_DMACHANNEL1, ENABLE);
DMA_InitStruct.DMA_DstAddress = (uint32_t)&CW_ADC->CR1; // 目標(biāo)地址
DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix; // 目標(biāo)地址固定
DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK; // BLOCK傳輸模式
DMA_InitStruct.DMA_SrcAddress = (uint32_t)&ADC_CR1Array[0]; // 源地址
DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Increase; // 源地址遞增
DMA_InitStruct.DMA_TransferCnt = 0x5; // DMA傳輸次數(shù)
DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT; // 數(shù)據(jù)位寬8bit
DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_TRANSCOMPLETE; // ADC轉(zhuǎn)換完成硬觸發(fā)
DMA_InitStruct.TrigMode = DMA_HardTrig; // 硬觸發(fā)模式
DMA_Init(CW_DMACHANNEL2, &DMA_InitStruct);
DMA_Cmd(CW_DMACHANNEL2, ENABLE);
DMA_InitStruct.DMA_DstAddress = (uint32_t)&CW_ADC->START; // 目標(biāo)地址
DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix; // 目標(biāo)地址固定
DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK; // BLOCK傳輸模式
DMA_InitStruct.DMA_SrcAddress = (uint32_t)&ADC_Start; // 源地址
DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix; // 源地址固定
DMA_InitStruct.DMA_TransferCnt = 0x5; // DMA傳輸次數(shù)
DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT; // 數(shù)據(jù)位寬8bit
DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_TRANSCOMPLETE; // ADC轉(zhuǎn)換完成硬觸發(fā)
DMA_InitStruct.TrigMode = DMA_HardTrig; // 硬觸發(fā)模式
DMA_Init(CW_DMACHANNEL3, &DMA_InitStruct);
DMA_Cmd(CW_DMACHANNEL3, ENABLE);
DMA_InitStruct.DMA_DstAddress = (uint32_t)&CW_ADC->START; // 目標(biāo)地址
DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix; // 目標(biāo)地址固定
DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK; // BLOCK傳輸模式
DMA_InitStruct.DMA_SrcAddress = (uint32_t)&ADC_Start; // 源地址
DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix; // 源地址固定
DMA_InitStruct.DMA_TransferCnt = 0x1; // DMA傳輸次數(shù)
DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT; // 數(shù)據(jù)位寬8bit
DMA_InitStruct.HardTrigSource = DMA_HardTrig_ATIM_CH1A2A3A4; // ATIM硬件觸發(fā)
DMA_InitStruct.TrigMode = DMA_HardTrig; // 硬觸發(fā)模式
DMA_Init(CW_DMACHANNEL4, &DMA_InitStruct);
DMA_Cmd(CW_DMACHANNEL4, ENABLE);
//開啟DMA中斷,也就是ADC檢測完畢后通過DMA傳輸后,會產(chǎn)生一個中斷,在中斷中再重新配置ADC
DMA_ITConfig(CW_DMACHANNEL1, DMA_IT_TC, ENABLE);
//失能中斷后配置好中斷在使能!
__disable_irq();
NVIC_EnableIRQ(DMACH1_IRQn);
__enable_irq();
}
該例程中需要詳細(xì)分析MOTORCONTROL.c文件內(nèi)容,這個是無感換向的核心部分!
無感閉環(huán)
該例程中主要在無感開環(huán)的基礎(chǔ)上增加了PID和過流過壓保護(hù)功能!也是在MOTORCONTROL.c文件中!
如果大家電機(jī)跑不起來,可以修改:QDPwm的值、也可以配置sensorlessP.c文件的參數(shù)量,這些參數(shù)量是經(jīng)驗值,需要自己多測試才能找到符合自己電機(jī)的參數(shù),我也還在研究中,就不獻(xiàn)丑了。。。這個無感部分的軟件部分,我還在學(xué)習(xí)中,未來有機(jī)會再和大家一起分享吧。
整體設(shè)計框圖

-
驅(qū)動系統(tǒng)
+關(guān)注
關(guān)注
3文章
385瀏覽量
27761 -
無刷直流電機(jī)
+關(guān)注
關(guān)注
61文章
699瀏覽量
47211 -
CW32
+關(guān)注
關(guān)注
1文章
242瀏覽量
1093 -
武漢芯源
+關(guān)注
關(guān)注
1文章
67瀏覽量
427
發(fā)布評論請先 登錄
基于武漢芯源CW32F030C8T6直流無刷電機(jī)評估開發(fā)板的介紹
基于C8051F005的無刷直流電機(jī)控制系統(tǒng)
無刷直流電機(jī)的原理與驅(qū)動
無刷直流電機(jī)原理

基于C8051F005的無刷直流電機(jī)控制系統(tǒng)

STM32驅(qū)動無刷直流電機(jī)

STM32 HAL驅(qū)動有刷直流電機(jī)和無刷直流電機(jī)

無刷直流電機(jī)與有刷直流電機(jī)的區(qū)別

基于武漢芯源CW32F030C8T6直流無刷電機(jī)評估開發(fā)板的介紹

無刷直流電機(jī)驅(qū)動單元

評論