1. 程式人生 > >stm32通過電調帶動電機(可按鍵調速)

stm32通過電調帶動電機(可按鍵調速)

這幾天在做32通過電調帶動電機的實驗,上網一查,發現這方面的資料很少,經過自己的親自實踐,總結出以下經驗,供大家參考。

論壇上也有很多人說自己在做,但是都遇到了同樣的瓶頸。我想他們大多是pwm的頻率和佔空比沒有調到合適的值吧。

首先,我在網上只找到一片很好的文章,是瑞生大神寫的:http://www.rationmcu.com/lpc1114/1126.html

我的電機是銀燕2212/1400kv經典電機 ,電調也是銀燕40A無刷電調。

通過它知道,當pwm設定為500hz的 時候電調才能正常的工作,剛開始時高電平時間要控制在0.7-1.9左右,讓電機帶電自檢。

通過按鍵控制佔空比可以很好地 實現這一點。

好了,下面上我的程式碼。

先來標頭檔案吧

  1. #ifndef _Motor_H_  
  2. #define _Motor_H_  
  3. #include "stm32f10x.h"  
  4. /******************************************************************************  
  5.                             全域性函式宣告  
  6. *******************************************************************************/   
  7. void Motor_Init(void);  
  8. //void Motor_Out(int16_t duty1,int16_t duty2,int16_t duty3,int16_t duty4);  
  9. #endif  

主菜:

  1. /***************************************************************************************  
  2.   1/給微控制器寫程式:使得某引腳輸出500Hz的PWM訊號,初始化時高電平時間設定為1.9ms,  
  3.   然後在while迴圈裡面加入檢測按鍵的程式,當按鍵按下,把高電平設定為0.7ms。  
  4.     2/1.給微控制器寫程式,把剛才的PWM初始化的高電平設定為0.7ms,保證剛上電,電調不會讓電機轉動。  
  5.     然後給修改按鍵按下的程式,修改為,按一次按鍵,高電平時間增加一點點,最大增加到1.9ms。  
  6.     我的按鍵再c13(k2)和e0(k1)  
  7.     日期:2016.3.4  
  8. ***************************************************************************************/  
  9. #include "dianji.h"  
  10.   uint8_t indexWave[] = {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};  //佔空比表  
  11. //宣告函式  
  12. void Tim2_init(void);  
  13. void Motor_Init(void);  
  14. void Init_NVIC(void);  
  15. void Delay_Ms(uint16_t time);    
  16. void Delay_Us(uint16_t time);   
  17. void Init_TI_KEY(void);  
  18. int main(void)  
  19. {  
  20.     SystemInit();                //系統時鐘配置  
  21.     Motor_Init();  
  22.     Tim2_init();  
  23.     Init_NVIC();                //中斷向量表註冊函式  
  24.     Init_TI_KEY();                //按鍵引腳中斷初始化  
  25.     while(1);  
  26. }  
  27. void Tim2_init(void)  
  28. {      
  29.     TIM_TimeBaseInitTypeDef        TIM_TimeBaseStructure;  
  30.     TIM_OCInitTypeDef              TIM_OCInitStructure;  
  31.      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  
  32.     TIM_TimeBaseStructure.TIM_Period = 20-1;    //設定ARR的值為19,從0計數到19,剛好是2ms ,500hz  
  33.     TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;//設定PSC的值為7199,這樣的話每計數一次為0.1ms   
  34.     TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim
  35.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMx向上計數模式  
  36.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據TIM_TimeBaseStructure中指定的引數初始化外設TIM2  
  37.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //選擇定時器模式  
  38.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能  
  39.     TIM_OCInitStructure.TIM_Pulse = 0; //設定待裝入捕獲比較暫存器的脈衝值,剛開始可以設定為0.  
  40.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高  
  41.     TIM_OC1Init(TIM2, &TIM_OCInitStructure);   
  42.     TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR1上的預裝載暫存器  
  43.     TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIM2在ARR上的預裝載暫存器  
  44.     TIM_Cmd(TIM2, ENABLE);  //使能TIM2外設  
  45. }  
  46. /******************************************************************************  
  47. 函式原型:    void Motor_Init(void)  
  48. 功    能:    PWM初始化  
  49. *******************************************************************************/   
  50. void Motor_Init(void)  
  51. {  
  52.     GPIO_InitTypeDef GPIO_InitStructure;  
  53.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);   //使能電機用的時鐘  
  54.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;     //設定電機使用到得管腳  
  55.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  56.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
  57.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  58. }  
  59. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  
  60. ** 函式名稱: KEY_TI_Init  
  61. ** 功能描述: 按鍵 中斷配置   
  62. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/  
  63. void Init_TI_KEY(void)  
  64. {  
  65.     EXTI_InitTypeDef  EXTI_InitStructure;                    //定義一個EXTI結構體變數  
  66.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能IO複用功能,使用中斷功能重要!!!  
  67.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);//配置埠C的13引腳為中斷源      重要!! 板上標號INT2  
  68.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0); //配置埠E的0引腳為中斷源      重要!! 板上標號INT1  
  69.     EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line13;//  
  70.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        //中斷模式為中斷模式  
  71.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;    //下降沿出發  
  72.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                //使能中斷線  
  73.     EXTI_Init(&EXTI_InitStructure);                            //根據引數初始化中斷暫存器  
  74. }  
  75. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  
  76. ** 函式名稱: Init_NVIC  
  77. ** 功能描述: 系統中斷配置  
  78. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/  
  79. void Init_NVIC(void)  
  80. {   
  81.     NVIC_InitTypeDef  NVIC_InitStructure;  
  82.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                  //設定中斷優先順序分組2  
  83.     NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;        //設定中斷源為PC13  
  84.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;    //中斷佔優先級為2  
  85.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            //副優先順序為0  
  86.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能中斷  
  87.     NVIC_Init(&NVIC_InitStructure);                                   //根據引數初始化中斷暫存器  
  88.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;            //設定中斷源為PE0  
  89.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;    //中斷佔優先級為1  
  90.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            //副優先順序為0  
  91.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能中斷  
  92.     NVIC_Init(&NVIC_InitStructure);                                   //根據引數初始化中斷暫存器  
  93. }  
  94. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  
  95. ** 函式名稱: EXTI15_10_IRQHandler  
  96. ** 功能描述: 中斷15_10入口函式              
  97. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/  
  98. void EXTI15_10_IRQHandler(void)   //佔空比減小  
  99. {  
  100.     static uint8_t pwm_index = 0;            //用於PWM查表  
  101.     static uint8_t period_cnt = 0;        //用於計算週期數  
  102.     //就是上面兩個靜態變數沒有設定 ,導致一開始按鍵只能按一次,在往下按他的pwm表就不往下查表了,我想了一晚上啊。  
  103.     //今天早晨我突然發現可能是這兩個靜態變數沒有設定,一試,果然。開心至極。2016.3.5  
  104.     if(EXTI_GetITStatus(EXTI_Line13)!= RESET)      //判斷是否發生中斷,發生則中斷標誌置1  
  105.     {  
  106.            Delay_Ms(5);  //消抖  
  107.              period_cnt++;              
  108.                 TIM2->CCR1 = indexWave[pwm_index];    //根據PWM表修改定時器的比較暫存器值  
  109.                 pwm_index++;                                                //標誌PWM表的下一個元素  
  110.                 if( pwm_index >=  15)                                //若PWM脈衝表已經輸出完成一遍,重置PWM查表標誌  
  111.                 {  
  112.                     pwm_index=0;                                  
  113.                 }  
  114.     //TIM_ClearITPendingBit (TIM2, TIM_IT_Update);    //必須要清除中斷標誌位  
  115.     EXTI_ClearITPendingBit(EXTI_Line13);        //清楚中斷掛起位,重要!!              
  116. }  
  117. }  
  118. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  
  119. ** 函式名稱: EXTI0_IRQHandler  
  120. ** 功能描述: 中斷0入口函式              
  121. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/  
  122. void EXTI0_IRQHandler(void)    //佔空比增大  
  123. {  
  124.     if(EXTI_GetITStatus(EXTI_Line0)!= RESET)     //判斷是否發生中斷,發生則中斷標誌置1  
  125.     {  
  126.       Delay_Ms(5);  
  127.         //暫時不用  
  128.     }  
  129.     EXTI_ClearITPendingBit(EXTI_Line0);             //清楚中斷掛起位,重要!!              
  130. }  
  131. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  
  132. ** 函式名稱: Delay_Ms_Ms  
  133. ** 功能描述: 延時1MS (可通過模擬來判斷他的準確度)              
  134. ** 引數描述:time (ms) 注意time<65535
  135. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/  
  136. void Delay_Ms(uint16_t time)  //延時函式  
  137. {   
  138.     uint16_t i,j;  
  139.     for(i=0;i<time;i++)  
  140.           for(j=0;j<10260;j++);  
  141. }  
  142. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  
  143. ** 函式名稱: Delay_Ms_Us  
  144. ** 功能描述: 延時1us (可通過模擬來判斷他的準確度)  
  145. ** 引數描述:time (us) 注意time<65535
  146. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/  
  147. 相關推薦

    stm32通過調帶動電機按鍵調

    這幾天在做32通過電調帶動電機的實驗,上網一查,發現這方面的資料很少,經過自己的親自實踐,總結出以下經驗,供大家參考。 論壇上也有很多人說自己在做,但是都遇到了同樣的瓶頸。我想他們大多是pwm的頻率和佔空比沒有調到合適的值吧。 首先,我在網上只找到一片很好的文章,是瑞

    stm32簡說步進電機有程式碼!!!

    步進電機(也稱脈衝電機)(將電脈衝轉換為相應的角位移或線位移的電磁機械裝置,具有快速啟動,停能力,在電機的負荷不超過它能提供的動態轉矩時,可以通過輸入脈衝來控制它在一瞬間的啟動或者停止。在非超載的情

    【轉】Entity Framework6 with Oracle實現code first

    ocs driver 版本 nag model oracl 新的 vid req Oracle 已在2014年底提供對EF6的支持。以前只支持到EF5。EF6有很多有用的功能 值得升級。這裏介紹下如何支持Oracle 一.Oracle 對.net支持的一些基礎知識了解

    setTimeout()和setInterval() 何時被調用執行非多線程.RP

    date() htm 並且 logs argument tle 有時 call line 定義 setTimeout()和setInterval()經常被用來處理延時和定時任務。setTimeout() 方法用於在指定的毫秒數後調用函數或計算表達式,而setInterval

    AndroidManifest.xml裏加入不同package的component Activity、Service裏android:name裏指定的值一般為句號加類名,可以通過指定完全類名包名+類名來解決

    代碼 gui 目的 tools 註冊 不同 res 收藏 small 我們都知道對於多個Activity如果在同一個包中,在Mainfest中可以這樣註冊 Xml代碼 <span style="font-size: small;"><?xml

    iOS UITableView ExpandableHeader形變的Header

    tar gpo span top tableview target rto off 自己實現 最常見的header就是在tableView下拉時header裏的圖片會放大的那種, 最近研究了一下,自己實現了這種header。 1.設置

    超簡單的VUE在線調試網站不需搭建環境

    http html編輯器 手工 html todo src 2.0 .com 直觀 jsbin.com提供簡單、直觀、易用的vue調試功能,最大的好處不需要自己搭建環境就可以學習VUE1、打開http://jsbin.com/joxinumota/edit?html,js,

    bzoj 2588 Spoj 10628. Count on a tree 持久化線段樹

    change lca 權值線段樹 mat sin urn problem sample des Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 7669 Solv

    SQLSERVER復制數據庫某一個表到另一個數據庫中跨服務器

    led 數據 rom msdb pan 錯誤 ons 數據庫 ble 一、復制數據庫某一個表到另一個數據庫中(同一服務器) SELECT * INTO 表1 FROM 表2 --復制表2如果只復制結構而不復制內容或只復制某一列只要加WHERE條件就好了 例子:SELECT

    微信小程式中使用Echarts非同步請求資料

    在微信小程式中使用Echarts,主要分為以下幾步: 1.首先要下載ecomfe/echarts-for-weixin專案,下載後將ec-canvas資料夾複製到小程式專案中,假設放在根目錄下utils資料夾中。 2.在要實現echarts圖的頁面引入echarts.js檔案,例如要在i

    基於jquery的查詢多級select控制元件記錄歷史選擇

    ;(function($,window,document){ var pluginName = 'multiSelect', defaults = { type: '1',//select層級onetwo data:[], field:[],//資料欄位名

    C++工作筆記-3種方法對資料型別進行拆分用於各種協議

    比如用Long Long存3個數據的內容。 這裡要知道大小端的知識點。 方法一是用位運算; 方法二是用指標; 方法三是結構體(本質上也是指標); 執行截圖如下: 原始碼如下: main.cpp #include <iostream> using

    deformable convolution變形卷積演算法解析及程式碼分析

    可變形卷積是指卷積核在每一個元素上額外增加了一個引數方向引數,這樣卷積核就能在訓練過程中擴充套件到很大的範圍。 可變形卷積的論文為:Deformable Convolutional Networks【1】 而之前google一篇論文對這篇論文有指導意義:Spatial

    bzoj3261: 最大異或和持久化字典樹

    Problem 給定一個非負整數序列 a{a}a,初始長度為 nnn。 有M個操作,有以下兩種操作型別: 1、A1、A1、A $ x$:新增操作,表示在序列末尾新增一個數 xxx ,序列的長度 n+1n

    一種高效的android雙擊退出擴充套件多擊

    參考Google,安卓手機中在檢視安卓系統版本的地方,三擊或者多擊會出現彩蛋,可以借鑑其原始碼進行實現。 //利用陣列來儲存時間     long[] mHits = new long[3];     @Override     pub

    HDU 5956 ICPC-2016 瀋陽 I題 樹上斜率優化持久化”單調佇列

    題目 題解: 斜率優化在樹上,直接暴力刪線段再用棧維護複雜度顯然是錯的。 然後以為要用可持久化線段樹維護, 後來發現我sb了 只需要在查詢和修改的時候二分一下修改位置,直接在原陣列上修改和記錄就好了 因為我們每次只修改一個點,並且只會查詢上一個版本(父親)的單調

    Diango + uwsgi + nginx 專案部署外網訪問 Diango + uwsgi + nginx 專案部署外網訪問

    轉載文章----Copyright ©2018 不懂得小白---連結:不懂得小白   Diango + uwsgi + nginx 專案部署(可外網訪問)  

    VRF驗證隨機函式快速理解

    理解VRF之前,需要先理解帶祕鑰的雜湊函式,和傳統的雜湊函式不同,帶祕鑰的雜湊函式在計算HASH數值的時候引入了一個不公開的祕鑰,這樣為從明文到HASH數值計算之間添加了一定的難度,這個難度就是由祕鑰引入的。我們簡單的定義一個帶祕鑰的HASH函式為如下的形式: hash_v

    IDEA永久破解系列到2099年

    最近小熙的idea快要到期了,所以想搜下永久的解決辦法。最終分享如下: 特別提醒:這些操作同樣適用於idea系列的其他產品,如webstorm、pyCharm等。 1. 下載破解外掛 破解idea連結,版本為2018.1.5的外掛(2.8-enc) 密碼:pxb1 破解idea連

    bzoj3261: 最大異或和 持久化trie樹

    多少 ace 經典 經典的 bzoj3261 個數 math 應該 sum 題目鏈接 題解 看到異或和最大就應該想到01 trie樹 我們記\(S_i\)為前i項的異或和 那麽我們的目的是最大化\(S_n\)^\(x\)^\(S_{j-1}\) \((l <= j &