|
直流電機(jī)驅(qū)動(dòng)程序,采用DRV8833驅(qū)動(dòng),并用霍爾傳感器測(cè)量轉(zhuǎn)速,測(cè)量精確
所有資料51hei提供下載:
直流電機(jī)驅(qū)動(dòng)程序,采用DRV8833驅(qū)動(dòng),并用霍爾傳感器測(cè)量轉(zhuǎn)速,測(cè)量精確.zip
(655.84 KB, 下載次數(shù): 163)
2017-11-28 23:54 上傳
點(diǎn)擊文件名下載附件
msp430單片機(jī)源程序如下:
- /*
- * DC_Motor.c
- *
- * Created on: 8-31
- * Author: zdl
- */
- #include "global.h"
- //---------------------相關(guān)宏定義-------------------------
- #define ENCODE_NUM 4 //測(cè)速碼盤(pán)齒輪數(shù)目
- #define MAX_SPEED 340 //最大轉(zhuǎn)速(r/s)
- #define P_Coefficient 11 //PID反饋中的比例系數(shù)
- #define I_Coefficient 2 //PID反饋中的微分系數(shù)
- #define D_Coefficient 1 //PID反饋中的積分系數(shù)
- //---------------------相關(guān)變量定義-----------------------
- static uint16_t ui16Speed_Preset = 0; //預(yù)設(shè)速度
- static uint16_t ui16Speed_True = 0; //實(shí)測(cè)速度,單位XX轉(zhuǎn)/分
- uint16_t ui16Speed_Measure = 0; //實(shí)測(cè)速度,單位XX轉(zhuǎn)/分
- static uint16_t ui16Speed_Pecent = 0; //速度百分比,用于更新速度曲線(xiàn)
- uint16_t ui16TA0_Overflow_Cnt = 0; //定時(shí)器溢出計(jì)數(shù)
- uint16_t ui16TA1_Overflow_Cnt = 0; //定時(shí)器溢出計(jì)數(shù)
- static uint8_t ui8FirstFlag = 1; //PID算法中微分項(xiàng)需要判斷首次上電
- //---------------------局部函數(shù)聲明---------------------
- static void Speed_Disp();
- static uint16_t PID_PWM(int16_t i16Error);
- static void Get_Fre();
- void DC_Motor_Graph()
- {
- //-----Draw Title-----
- GrClearDisplay(&g_sContext);
- GrTaskRectDraw();
- //-----繪制轉(zhuǎn)速單位-----
- GrStringDrawCentered(&g_sContext, "(r/s)", AUTO_STRING_LENGTH, 52, 20, OPAQUE_TEXT);
- //-----繪制波形坐標(biāo)軸-----
- GrAxisDraw();
- GrFlush(&g_sContext);
- }
- void DC_Motor_Begin()
- {
- //--------GPIO Init--------
- P2DIR &= ~BIT7; //-----測(cè)速中斷IO初始化-----
- P2IES |= BIT7;
- P2IE |= BIT7;
- P1DIR |= BIT3 +BIT4; //-----配置P1.3和P1.4電機(jī)PWM控制IO參數(shù)-----
- P1OUT |= BIT3;
- P1SEL |= BIT4;
- //-----TA1 ContinuousMode Init-----
- TIMER_A_configureContinuousMode(__MSP430_BASEADDRESS_T1A3__,//選擇TA1定時(shí)器
- TIMER_A_CLOCKSOURCE_SMCLK,
- TIMER_A_CLOCKSOURCE_DIVIDER_1,
- TIMER_A_TAIE_INTERRUPT_ENABLE,
- TIMER_A_DO_CLEAR);
- TA1CTL = TASSEL_2 + MC_2 + TACLR + TAIE; //啟動(dòng)測(cè)速
- //-----TA0.3 PWM Init------
- TIMER_A_generatePWM( __MSP430_BASEADDRESS_T0A5__,//選擇TA0定時(shí)器
- TIMER_A_CLOCKSOURCE_SMCLK,
- TIMER_A_CLOCKSOURCE_DIVIDER_1,
- SYSMCLK/10000-1, //PWM 10K
- TIMER_A_CAPTURECOMPARE_REGISTER_3,
- TIMER_A_OUTPUTMODE_SET_RESET ,
- SYSMCLK/10000-1
- );
- //-----首次PID算法置標(biāo)志位-----
- ui8FirstFlag = 1; //PID算法中用于判斷第一次的標(biāo)志位
- }
- void DC_Motor_Main()
- {
- Draw_Histogram(0); //更新柱狀圖
- Get_Fre();
- Speed_Disp(); //更新預(yù)設(shè)與實(shí)測(cè)速度值
- Draw_Waveform(&ui16Speed_Pecent,1); //更新速度曲線(xiàn)
- GrFlush(&g_sContext); //刷新屏幕
- LPM3; //執(zhí)行函數(shù)由WDT定時(shí)喚醒
- }
- void DC_Motor_Quit()
- {
- //-----GPIO Quit-----
- P2DIR |= BIT7;
- P2IE &= ~BIT7;
- P1SEL &= ~BIT4;
- P1OUT &= ~(BIT3+BIT4);
- ui8FirstFlag=1;
- //-----TA0 Quit-----
- TIMER_A_disableInterrupt(__MSP430_BASEADDRESS_T0A5__);
- //-----TA1 Quit-----
- TIMER_A_disableInterrupt(__MSP430_BASEADDRESS_T1A3__);
- }
- //-------------速度顯示-------------
- static void Speed_Disp()
- {
- //-----更新變量值-----
- ui16Speed_Preset=MAX_SPEED*ui8Wheel_Pecent/100;
- ui16Speed_Pecent=ui16Speed_True*100/MAX_SPEED;
- //-----刷新顯示-----
- GrStringDrawCentered(&g_sContext, " ",
- AUTO_STRING_LENGTH,20,20, OPAQUE_TEXT); //清除前一次顯示
- GrStringNumberCentered(&g_sContext,
- ui16Speed_True,0,20,20);
- GrStringDrawCentered(&g_sContext, " ",
- AUTO_STRING_LENGTH,113,20, OPAQUE_TEXT); //清除前一次顯示
- GrStringNumberCentered(&g_sContext,
- ui16Speed_Preset,0,113,20);
- ui16Speed_True=0;
- ui16Speed_Preset=0;
- }
- //----PID算法,計(jì)算出PWM占空比,8192等同100%占空比------
- static uint16_t PID_PWM(int16_t i16Error)
- {
- static int16_t i16Error_Prev = 0;
- static int16_t i16Integral = 0;
- int16_t i16P_Component ,i16I_Component ,i16D_Component ;
- int16_t i16Result;
- if(ui8FirstFlag) //首次上電缺乏前次誤差,補(bǔ)上。
- {
- ui8FirstFlag = 0;
- i16Error_Prev = i16Error;
- i16Integral=0;
- }
- i16P_Component = P_Coefficient*i16Error;
- i16I_Component = I_Coefficient*i16Integral;
- i16D_Component = D_Coefficient*(i16Error-i16Error_Prev);
- //-----誤差積分-----
- i16Integral += i16Error;
- i16Result = i16P_Component + i16I_Component + i16D_Component;
- //-----輸出限幅----
- if(i16Result > 8192)
- i16Result = 8192;
- if(i16Result < 0)
- i16Result = 0;
- return(i16Result);
- }
- /********************************************************
- *
- * 以下函數(shù)需要放置在中斷服務(wù)子函數(shù)中調(diào)用
- *
- ********************************************************/
- //-----WDT中斷定時(shí)更新占空比-----
- void Change_PWM_Duty()
- {
- int16_t i16Error = ui16Speed_Preset - ui16Speed_True;
- uint32_t ui16PWM_Duty = PID_PWM(i16Error);
- TA0CCR3 = (uint16_t)((ui16PWM_Duty)*TA0CCR0/8192); //改變PWM占空比
- }
- //-----測(cè)量實(shí)際轉(zhuǎn)速,此函數(shù)在P2中斷中被調(diào)用-----
- static uint16_t ui16PreTemp=0;
- void Measure_Freq()
- {
- uint32_t Speed_Sum;
- uint16_t ui16Temp;
- ui16Temp=TA1R;
- Speed_Sum = (uint32_t)ui16Temp + (uint32_t)65536*ui16TA1_Overflow_Cnt-ui16PreTemp;//測(cè)速前的值減去測(cè)速后的計(jì)數(shù)值,那么就是在一段時(shí)間內(nèi)計(jì)數(shù)的次數(shù)
- ui16PreTemp = ui16Temp;
- ui16TA1_Overflow_Cnt = 0;
- ui16Speed_Measure = (uint16_t)( SYSMCLK / Speed_Sum); //計(jì)算頻率 , 開(kāi)孔圓盤(pán)上有許多小孔,開(kāi)孔圓盤(pán)旋轉(zhuǎn)一周,光敏元件輸出的電脈沖個(gè)數(shù)等于圓盤(pán)的開(kāi)孔數(shù),因此,可通過(guò)測(cè)量光敏元件輸出的脈沖頻率
- }
- //獲取測(cè)量的速度,應(yīng)該是獲取轉(zhuǎn)速
- static void Get_Fre()
- {
- ui16Speed_True = ui16Speed_Measure/ENCODE_NUM; //返回實(shí)測(cè)轉(zhuǎn)速值,除以齒輪數(shù)目
- }
復(fù)制代碼
|
|