找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 11653|回復(fù): 1
收起左側(cè)

單片機(jī)+DRV8833直流電機(jī)驅(qū)動(dòng)程序,霍爾傳感器精確測(cè)速

[復(fù)制鏈接]
ID:254979 發(fā)表于 2017-11-28 23:55 | 顯示全部樓層 |閱讀模式
直流電機(jī)驅(qū)動(dòng)程序,采用DRV8833驅(qū)動(dòng),并用霍爾傳感器測(cè)量轉(zhuǎn)速,測(cè)量精確
0.png


所有資料51hei提供下載:
直流電機(jī)驅(qū)動(dòng)程序,采用DRV8833驅(qū)動(dòng),并用霍爾傳感器測(cè)量轉(zhuǎn)速,測(cè)量精確.zip (655.84 KB, 下載次數(shù): 163)

msp430單片機(jī)源程序如下:
  1. /*
  2. * DC_Motor.c
  3. *
  4. *  Created on: 8-31
  5. *      Author: zdl
  6. */

  7. #include "global.h"

  8. //---------------------相關(guān)宏定義-------------------------
  9. #define ENCODE_NUM                4                                //測(cè)速碼盤(pán)齒輪數(shù)目
  10. #define MAX_SPEED       340                                //最大轉(zhuǎn)速(r/s)

  11. #define P_Coefficient   11                                //PID反饋中的比例系數(shù)
  12. #define I_Coefficient        2                                //PID反饋中的微分系數(shù)
  13. #define D_Coefficient        1                                //PID反饋中的積分系數(shù)

  14. //---------------------相關(guān)變量定義-----------------------
  15. static uint16_t         ui16Speed_Preset = 0;                //預(yù)設(shè)速度
  16. static uint16_t                ui16Speed_True = 0;                        //實(shí)測(cè)速度,單位XX轉(zhuǎn)/分
  17.            uint16_t                ui16Speed_Measure = 0;                        //實(shí)測(cè)速度,單位XX轉(zhuǎn)/分
  18. static uint16_t         ui16Speed_Pecent = 0;                //速度百分比,用于更新速度曲線(xiàn)
  19. uint16_t         ui16TA0_Overflow_Cnt = 0;        //定時(shí)器溢出計(jì)數(shù)
  20. uint16_t         ui16TA1_Overflow_Cnt = 0;        //定時(shí)器溢出計(jì)數(shù)
  21. static uint8_t         ui8FirstFlag = 1;                        //PID算法中微分項(xiàng)需要判斷首次上電

  22. //---------------------局部函數(shù)聲明---------------------
  23. static void Speed_Disp();
  24. static uint16_t PID_PWM(int16_t i16Error);
  25. static void Get_Fre();

  26. void DC_Motor_Graph()
  27. {
  28.         //-----Draw Title-----
  29.         GrClearDisplay(&g_sContext);
  30.         GrTaskRectDraw();

  31.         //-----繪制轉(zhuǎn)速單位-----
  32.         GrStringDrawCentered(&g_sContext, "(r/s)", AUTO_STRING_LENGTH, 52, 20, OPAQUE_TEXT);

  33.         //-----繪制波形坐標(biāo)軸-----

  34.         GrAxisDraw();
  35.         GrFlush(&g_sContext);
  36. }

  37. void DC_Motor_Begin()
  38. {
  39.         //--------GPIO Init--------
  40.         P2DIR &= ~BIT7;                                //-----測(cè)速中斷IO初始化-----
  41.         P2IES |= BIT7;
  42.         P2IE  |= BIT7;

  43.         P1DIR |= BIT3 +BIT4;                //-----配置P1.3和P1.4電機(jī)PWM控制IO參數(shù)-----
  44.         P1OUT |= BIT3;
  45.         P1SEL |= BIT4;

  46.         //-----TA1 ContinuousMode Init-----
  47.         TIMER_A_configureContinuousMode(__MSP430_BASEADDRESS_T1A3__,//選擇TA1定時(shí)器
  48.                                                                         TIMER_A_CLOCKSOURCE_SMCLK,
  49.                                                                         TIMER_A_CLOCKSOURCE_DIVIDER_1,
  50.                                                                         TIMER_A_TAIE_INTERRUPT_ENABLE,
  51.                                                                         TIMER_A_DO_CLEAR);
  52.         TA1CTL = TASSEL_2 + MC_2 + TACLR + TAIE; //啟動(dòng)測(cè)速
  53.         //-----TA0.3 PWM Init------
  54.         TIMER_A_generatePWM(  __MSP430_BASEADDRESS_T0A5__,//選擇TA0定時(shí)器
  55.                                                                 TIMER_A_CLOCKSOURCE_SMCLK,
  56.                                                                 TIMER_A_CLOCKSOURCE_DIVIDER_1,
  57.                                                                 SYSMCLK/10000-1,                                                        //PWM 10K
  58.                                                            TIMER_A_CAPTURECOMPARE_REGISTER_3,
  59.                                                            TIMER_A_OUTPUTMODE_SET_RESET ,
  60.                                                            SYSMCLK/10000-1
  61.                                                                    );

  62.         //-----首次PID算法置標(biāo)志位-----
  63.         ui8FirstFlag = 1;                                //PID算法中用于判斷第一次的標(biāo)志位
  64. }

  65. void DC_Motor_Main()
  66. {
  67.         Draw_Histogram(0);                                        //更新柱狀圖
  68.         Get_Fre();
  69.         Speed_Disp();                                                //更新預(yù)設(shè)與實(shí)測(cè)速度值
  70.         Draw_Waveform(&ui16Speed_Pecent,1); //更新速度曲線(xiàn)
  71.         GrFlush(&g_sContext);                                //刷新屏幕
  72.         LPM3;                                                                //執(zhí)行函數(shù)由WDT定時(shí)喚醒
  73. }

  74. void DC_Motor_Quit()
  75. {
  76.         //-----GPIO Quit-----
  77.         P2DIR |= BIT7;
  78.         P2IE  &= ~BIT7;
  79.         P1SEL &= ~BIT4;
  80.         P1OUT &= ~(BIT3+BIT4);
  81.         ui8FirstFlag=1;

  82.         //-----TA0 Quit-----
  83.         TIMER_A_disableInterrupt(__MSP430_BASEADDRESS_T0A5__);

  84.         //-----TA1 Quit-----
  85.         TIMER_A_disableInterrupt(__MSP430_BASEADDRESS_T1A3__);
  86. }

  87. //-------------速度顯示-------------
  88. static void Speed_Disp()
  89. {
  90.         //-----更新變量值-----
  91.         ui16Speed_Preset=MAX_SPEED*ui8Wheel_Pecent/100;
  92.         ui16Speed_Pecent=ui16Speed_True*100/MAX_SPEED;

  93.         //-----刷新顯示-----
  94.         GrStringDrawCentered(&g_sContext, "     ",
  95.                         AUTO_STRING_LENGTH,20,20, OPAQUE_TEXT);                //清除前一次顯示
  96.         GrStringNumberCentered(&g_sContext,
  97.                         ui16Speed_True,0,20,20);

  98.         GrStringDrawCentered(&g_sContext, "     ",
  99.                         AUTO_STRING_LENGTH,113,20, OPAQUE_TEXT);        //清除前一次顯示
  100.         GrStringNumberCentered(&g_sContext,
  101.                         ui16Speed_Preset,0,113,20);
  102.         ui16Speed_True=0;
  103.         ui16Speed_Preset=0;
  104. }

  105. //----PID算法,計(jì)算出PWM占空比,8192等同100%占空比------
  106. static uint16_t PID_PWM(int16_t i16Error)
  107. {
  108.         static int16_t        i16Error_Prev = 0;
  109.         static int16_t        i16Integral = 0;
  110.         int16_t i16P_Component ,i16I_Component ,i16D_Component ;
  111.         int16_t i16Result;

  112.         if(ui8FirstFlag)                        //首次上電缺乏前次誤差,補(bǔ)上。
  113.         {
  114.                 ui8FirstFlag = 0;
  115.                 i16Error_Prev = i16Error;
  116.                 i16Integral=0;
  117.         }

  118.         i16P_Component = P_Coefficient*i16Error;
  119.         i16I_Component = I_Coefficient*i16Integral;
  120.         i16D_Component = D_Coefficient*(i16Error-i16Error_Prev);
  121.         //-----誤差積分-----
  122.         i16Integral += i16Error;
  123.         i16Result = i16P_Component + i16I_Component + i16D_Component;

  124.         //-----輸出限幅----
  125.         if(i16Result > 8192)
  126.                 i16Result = 8192;
  127.         if(i16Result < 0)
  128.                 i16Result = 0;
  129.         return(i16Result);
  130. }

  131. /********************************************************
  132. *
  133. *                         以下函數(shù)需要放置在中斷服務(wù)子函數(shù)中調(diào)用
  134. *
  135. ********************************************************/

  136. //-----WDT中斷定時(shí)更新占空比-----
  137. void Change_PWM_Duty()
  138. {
  139.         int16_t i16Error = ui16Speed_Preset - ui16Speed_True;
  140.         uint32_t ui16PWM_Duty = PID_PWM(i16Error);
  141.         TA0CCR3 = (uint16_t)((ui16PWM_Duty)*TA0CCR0/8192);                //改變PWM占空比
  142. }

  143. //-----測(cè)量實(shí)際轉(zhuǎn)速,此函數(shù)在P2中斷中被調(diào)用-----
  144. static uint16_t ui16PreTemp=0;
  145. void Measure_Freq()
  146. {
  147.         uint32_t Speed_Sum;
  148.         uint16_t ui16Temp;

  149.         ui16Temp=TA1R;
  150.         Speed_Sum = (uint32_t)ui16Temp + (uint32_t)65536*ui16TA1_Overflow_Cnt-ui16PreTemp;//測(cè)速前的值減去測(cè)速后的計(jì)數(shù)值,那么就是在一段時(shí)間內(nèi)計(jì)數(shù)的次數(shù)
  151.         ui16PreTemp = ui16Temp;
  152.         ui16TA1_Overflow_Cnt = 0;
  153.         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è)量光敏元件輸出的脈沖頻率
  154. }

  155. //獲取測(cè)量的速度,應(yīng)該是獲取轉(zhuǎn)速
  156. static void Get_Fre()
  157. {
  158.         ui16Speed_True = ui16Speed_Measure/ENCODE_NUM; //返回實(shí)測(cè)轉(zhuǎn)速值,除以齒輪數(shù)目
  159. }

復(fù)制代碼




回復(fù)

使用道具 舉報(bào)

ID:135635 發(fā)表于 2020-3-26 13:45 | 顯示全部樓層
謝謝分享!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表