標(biāo)題第七章-編碼器測速
7.1-認(rèn)識編碼器
編碼器:一般按照電機(jī)尾部、用于測量電機(jī)轉(zhuǎn)速、方向、位置。
那么編碼器的輸出信號具體是什么?我們?nèi)绾胃鶕?jù)輸出信號測量轉(zhuǎn)速 和方向?
轉(zhuǎn)速: 單位時(shí)間測量到的脈沖數(shù)量(比如根據(jù)每秒測量到多少個(gè)脈沖來計(jì)算轉(zhuǎn)速)
旋轉(zhuǎn)方向: 兩通道信號的相對電平關(guān)系
7.2單片機(jī)定時(shí)器的編碼器功能
那么我們已經(jīng)知道編碼器輸出的波形,我們?nèi)绾瓮ㄟ^單片機(jī)讀取波形,然后計(jì)算出速度那?
這里STM32單片機(jī)的定時(shí)器和通用定時(shí)器具有編碼器接口模式、在STM32中文參考手冊13章中有詳細(xì)介紹
STM32中文參考手冊-第200頁
STM32中文參考手冊-第267頁
STM32中文參考手冊-第226頁
這個(gè)是計(jì)數(shù)方向與編碼器信號的關(guān)系、我們拆開來看
僅在TI1計(jì)數(shù)、電機(jī)正轉(zhuǎn)、對原始數(shù)據(jù)二倍頻
僅在TI1計(jì)數(shù)、電機(jī)反轉(zhuǎn)、對原始數(shù)據(jù)二倍頻
在TI1和TI2都計(jì)數(shù)
可以看到這樣就對原始數(shù)據(jù)四倍頻了
計(jì)數(shù)方向
7.3-獲得單位時(shí)間計(jì)數(shù)器值變化量
上一次說的方法:
這次編碼器計(jì)數(shù)值 = 計(jì)數(shù)器值+計(jì)數(shù)溢出次數(shù) * 計(jì)數(shù)最大器計(jì)數(shù)最大值
計(jì)數(shù)器兩次變化值 = 這次編碼器計(jì)數(shù)值 - 上次編碼器計(jì)數(shù)值
然后根據(jù)這個(gè)單位變化量計(jì)算速度
還有一種方法:
計(jì)數(shù)器變化量 = 當(dāng)前計(jì)數(shù)器值
每次計(jì)數(shù)值清空
然后根據(jù)這個(gè)變化量 計(jì)算速度
然后我們再看具體到哪一款電機(jī)和編碼器上如何測速
在STM32中文參考手冊-第119頁
設(shè)置TIM2
設(shè)置ITM2濾波器
同理設(shè)置TIM4
設(shè)置TIM4濾波器
設(shè)置引腳上拉
生成代碼
開啟定時(shí)器和定時(shí)中斷
HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);//開啟定時(shí)器2
HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);//開啟定時(shí)器4
HAL_TIM_Base_Start_IT(&htim2); //開啟定時(shí)器2 中斷
HAL_TIM_Base_Start_IT(&htim4); //開啟定時(shí)器4 中斷
在定義兩個(gè)變量保存計(jì)數(shù)器值
short Encoder1Count = 0;//編碼器計(jì)數(shù)器值
short Encoder2Count = 0;
每2ms讀取計(jì)數(shù)器值->清零計(jì)數(shù)器
Motor_Set(0,0);
//1.保存計(jì)數(shù)器值
Encoder1Count =(short)__HAL_TIM_GET_COUNTER(&htim4);
Encoder2Count =(short)__HAL_TIM_GET_COUNTER(&htim2);
//2.清零計(jì)數(shù)器值
__HAL_TIM_SET_COUNTER(&htim4,0);
__HAL_TIM_SET_COUNTER(&htim2,0);
printf("Encoder1Count:%drn",Encoder1Count);
printf("Encoder2Count:%drn",Encoder2Count);
HAL_Delay(2);
接好電池、燒錄代碼、串口一連接電腦
用手轉(zhuǎn)動(dòng)電機(jī)1或者電機(jī)2 、串口助手可以看到輸出信息了
7.4-主函數(shù)周期測量轉(zhuǎn)速
上面我們測量出來了溢出值,我們再根據(jù)當(dāng)前計(jì)數(shù)器值就可以測量出計(jì)數(shù)器變化量,我們通過單位時(shí)間變量就可以計(jì)算出轉(zhuǎn)速
下面是電機(jī)和編碼器的參數(shù)
我們先測試的結(jié)論是否有問題?
- 編碼器計(jì)數(shù)器會不會在計(jì)數(shù)時(shí)間內(nèi)溢出?
- 車輪旋轉(zhuǎn)一周,單片機(jī)編碼器計(jì)數(shù)器計(jì)數(shù)多少?9.6乘11乘4
- 根據(jù)計(jì)算方法計(jì)算電機(jī)轉(zhuǎn)速
定義兩個(gè)float變量
float Motor1Speed = 0.00;
float Motor2Speed = 0.00;
下面是代碼(一定要把主函數(shù)沒有用的刪除掉)
//計(jì)算速度
Motor1Speed = (float)Encode1Count*100/9.6/11/4;
Motor2Speed = (float)Encode2Count*100/9.6/11/4;
printf("Motor1Speed:%.2frn",Motor1Speed);
printf("Motor2Speed:%.2frn",Motor2Speed);
編譯燒錄代碼就會輸出結(jié)果
7.5-定時(shí)器中斷定時(shí)測量速度
上面我們實(shí)現(xiàn):在主函數(shù)周期,讀取計(jì)數(shù)器值然后計(jì)算速度,但是如果函數(shù)加入其他內(nèi)容這個(gè)周期時(shí)間就很難保證。
所以這節(jié)我們通過定時(shí)器,周期讀取計(jì)數(shù)器,計(jì)算速度。復(fù)制一份工程開始搞!
我們先開啟定時(shí)器、2ms進(jìn)入一次定時(shí)器中斷,中斷回調(diào)函數(shù)執(zhí)行咱們的代碼即可。
為什么充分利用單片機(jī) 我們使用TIM1
- 設(shè)置內(nèi)部時(shí)鐘源
- 使能自動(dòng)重裝載
開啟定義更新中斷
代碼開啟定時(shí)器1 中斷
HAL_TIM_Base_Start_IT(&htim1); //開啟定時(shí)器1 中斷
定時(shí)器回調(diào)函數(shù)中添加 速度計(jì)算內(nèi)容
/*******************
* @brief 定時(shí)器回調(diào)函數(shù)
* @param
* @return
*
*******************/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim1)//htim1 500HZ 2ms 中斷一次
{
TimerCount++;
if(TimerCount %5 == 0)//每10ms執(zhí)行一次
{
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;
主函數(shù)就輸出速度大小就可以了
printf("Motor1Speed:%.2frn",Motor1Speed);
printf("Motor2Speed:%.2frn",Motor2Speed);
把變量需要聲明一下
extern float Motor1Speed ;
extern float Motor2Speed ;
然后打開串口助手
注:
根據(jù)電機(jī)和實(shí)際小車調(diào)整速度測量與占空比設(shè)置函數(shù)
我們第七章這樣就完成了 ,把程序燒錄電機(jī)就可以完成測速了。
下篇第八章我們講解 PID速度控制
聯(lián)系:Q,1930299709