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


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

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

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

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

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

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

好了,下面上我的代碼。

先來頭文件吧

#ifndef _Motor_H_
#define _Motor_H_
#include "stm32f10x.h"

/******************************************************************************
                            全局函數聲明
*******************************************************************************/ 
void Motor_Init(void);
//void Motor_Out(int16_t duty1,int16_t duty2,int16_t duty3,int16_t duty4);

#endif

 

 

主菜:

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

 

 

本人也是新手,最近在做四旋翼,有什么問題歡迎交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM