標(biāo)題:
單片機(jī)+DRV8833直流電機(jī)驅(qū)動(dòng)程序,霍爾傳感器精確測(cè)速
[打印本頁(yè)]
作者:
D_omino
時(shí)間:
2017-11-28 23:55
標(biāo)題:
單片機(jī)+DRV8833直流電機(jī)驅(qū)動(dòng)程序,霍爾傳感器精確測(cè)速
直流電機(jī)驅(qū)動(dòng)程序,采用DRV8833驅(qū)動(dòng),并用霍爾傳感器測(cè)量轉(zhuǎn)速,測(cè)量精確
0.png
(8.92 KB, 下載次數(shù): 125)
下載附件
2017-11-29 03:48 上傳
所有資料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)擊文件名下載附件
下載積分: 黑幣 -5
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; //速度百分比,用于更新速度曲線
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); //更新速度曲線
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ù)制代碼
作者:
popo321
時(shí)間:
2020-3-26 13:45
謝謝分享!
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1