這是全網最詳細、性價比最高的STM32實戰項目入門教程,通過合理的硬件設計和詳細的視頻筆記介紹,硬件使用STM32F103主控資料多方便學習,通過3萬字筆記、12多個小時視頻、20多章節代碼手把手教會你如何開發和調試。讓你更快掌握嵌入式系統開發。
V3.3.0-STM32智能小車
視頻:
https://www.bilibili.com/video/BV16x4y1M7EN/?spm_id_from=333.337.search-card.all.click
V3:HAL庫開發、功能:PID速度控制、PID循跡、PID跟隨、遙控、避障、PID角度控制、視覺控制、電磁循跡、RTOS等功能。
標題第七章-編碼器測速
7.1-認識編碼器
編碼器:一般按照電機尾部、用于測量電機轉速、方向、位置。
那么編碼器的輸出信號具體是什么?我們如何根據輸出信號測量轉速 和方向?
轉速: 單位時間測量到的脈沖數量(比如根據每秒測量到多少個脈沖來計算轉速)
旋轉方向: 兩通道信號的相對電平關系
7.2單片機定時器的編碼器功能
那么我們已經知道編碼器輸出的波形,我們如何通過單片機讀取波形,然后計算出速度那?
這里STM32單片機的定時器和通用定時器具有****編碼器接口模式 、在STM32中文參考手冊13章中有詳細介紹
STM32中文參考手冊-第200頁
STM32中文參考手冊-第267頁
STM32中文參考手冊-第226頁
這個是計數方向與編碼器信號的關系、我們拆開來看
僅在TI1計數、電機正轉、對原始數據二倍頻
僅在TI1計數、電機反轉、對原始數據二倍頻
在TI1和TI2都計數
可以看到這樣就對原始數據四倍頻了
計數方向
7.3-獲得單位時間計數器值變化量
上一次說的方法:
這次編碼器計數值 = 計數器值+計數溢出次數 * 計數最大器計數最大值
計數器兩次變化值 = 這次編碼器計數值 - 上次編碼器計數值
然后根據這個單位變化量計算速度
還有一種方法:
計數器變化量 = 當前計數器值
每次計數值清空
然后根據這個變化量 計算速度
然后我們再看具體到哪一款電機和編碼器上如何測速
在STM32中文參考手冊-第119頁
設置TIM2
設置ITM2濾波器
同理設置TIM4
設置TIM4濾波器
設置引腳上拉
生成代碼
開啟定時器和定時中斷
HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);//開啟定時器2
HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);//開啟定時器4
HAL_TIM_Base_Start_IT(&htim2);//開啟定時器2 中斷
HAL_TIM_Base_Start_IT(&htim4); //開啟定時器4 中斷
在定義兩個變量保存計數器值
short Encoder1Count = 0;//編碼器計數器值
short Encoder2Count = 0;
每2ms讀取計數器值->清零計數器
Motor_Set(0,0);
//1.保存計數器值
Encoder1Count =(short)__HAL_TIM_GET_COUNTER(&htim4);
Encoder2Count =(short)__HAL_TIM_GET_COUNTER(&htim2);
//2.清零計數器值
__HAL_TIM_SET_COUNTER(&htim4,0);
__HAL_TIM_SET_COUNTER(&htim2,0);
printf("Encoder1Count:%drn",Encoder1Count);
printf("Encoder2Count:%drn",Encoder2Count);
HAL_Delay(2);
接好電池、燒錄代碼、串口一連接電腦
用手轉動電機1或者電機2 、串口助手可以看到輸出信息了
7.4-主函數周期測量轉速
上面我們測量出來了溢出值,我們再根據當前計數器值就可以測量出計數器變化量,我們通過單位時間變量就可以計算出轉速
下面是電機和編碼器的參數
我們先測試的結論是否有問題?
- 編碼器計數器會不會在計數時間內溢出?
- 車輪旋轉一周,單片機編碼器計數器計數多少?9.6乘11乘4
- 根據計算方法計算電機轉速
定義兩個float變量
float Motor1Speed = 0.00;
float Motor2Speed = 0.00;
下面是代碼(一定要把主函數沒有用的刪除掉)
//計算速度
Motor1Speed = (float)Encode1Count*100/9.6/11/4;
Motor2Speed = (float)Encode2Count*100/9.6/11/4;
printf("Motor1Speed:%.2frn",Motor1Speed);
printf("Motor2Speed:%.2frn",Motor2Speed);
編譯燒錄代碼就會輸出結果
7.5-定時器中斷定時測量速度
上面我們實現:在主函數周期,讀取計數器值然后計算速度,但是如果函數加入其他內容這個周期時間就很難保證。
所以這節我們通過定時器,周期讀取計數器,計算速度。復制一份工程開始搞!
我們先開啟定時器、2ms進入一次定時器中斷,中斷回調函數執行咱們的代碼即可。
為什么充分利用單片機 我們使用TIM1
- 設置內部時鐘源
- 使能自動重裝載
開啟定義更新中斷
代碼開啟定時器1 中斷
HAL_TIM_Base_Start_IT(&htim1); //開啟定時器1 中斷
定時器回調函數中添加 速度計算內容
/*******************
* @brief 定時器回調函數
* @param
* @return
*
*******************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim1)//htim1 500HZ 2ms 中斷一次
{
TimerCount++;
if(TimerCount %5 == 0)//每10ms執行一次
{
Encode1Count = (short)__HAL_TIM_GET_COUNTER(&htim4);
Encode2Count = (short)__HAL_TIM_GET_COUNTER(&htim2);
__HAL_TIM_SET_COUNTER(&htim4,0);
__HAL_TIM_SET_COUNTER(&htim2,0);
Motor1Speed = (float)Encode1Count*100/9.6/11/4;
Motor2Speed = (float)Encode2Count*100/9.6/11/4;
?
TimerCount=0;
}
}
}
把之前的變量定義放這里
short Encode1Count = 0;
short Encode2Count = 0;
float Motor1Speed = 0.00;
float Motor2Speed = 0.00;
uint16_t TimerCount=0;
主函數就輸出速度大小就可以了
printf("Motor1Speed:%.2frn",Motor1Speed);
printf("Motor2Speed:%.2frn",Motor2Speed);
把變量需要聲明一下
extern float Motor1Speed ;
extern float Motor2Speed ;
然后打開串口助手
注:
根據電機和實際小車調整速度測量與占空比設置函數
我們第七章這樣就完成了 ,把程序燒錄電機就可以完成測速了。
下篇第八章我們講解 PID速度控制
審核編輯 黃宇
-
編碼器
+關注
關注
45文章
3592瀏覽量
134144 -
測速
+關注
關注
0文章
37瀏覽量
14112 -
STM32F103C8T6
+關注
關注
107文章
160瀏覽量
83223
發布評論請先 登錄
相關推薦
評論