接線
編碼器電機、電機驅(qū)動(這里用的L298n)、STM32、電源(可以是12V電池)的接線如下

3.3 代碼編寫
encoder.h中的內(nèi)容
#ifndef _ENCODER_H_
#define _ENCODER_H_
#include "stm32f1xx.h"
//電機1的編碼器輸入引腳
#define MOTO1_ENCODER1_PORT GPIOA
#define MOTO1_ENCODER1_PIN GPIO_PIN_0
#define MOTO1_ENCODER2_PORT GPIOA
#define MOTO1_ENCODER2_PIN GPIO_PIN_1
//定時器號
#define ENCODER_TIM htim2
#define PWM_TIM htim3
#define GAP_TIM htim4
#define MOTOR_SPEED_RERATIO 45u //電機減速比
#define PULSE_PRE_ROUND 11 //一圈多少個脈沖
#define RADIUS_OF_TYRE 34 //輪胎半徑,單位毫米
#define LINE_SPEED_C RADIUS_OF_TYRE * 2 * 3.14
#define RELOADVALUE __HAL_TIM_GetAutoreload(&ENCODER_TIM) //獲取自動裝載值,本例中為20000
#define COUNTERNUM __HAL_TIM_GetCounter(&ENCODER_TIM) //獲取編碼器定時器中的計數(shù)值
typedef struct _Motor
{
int32_t lastCount; //上一次計數(shù)值
int32_t totalCount; //總計數(shù)值
int16_t overflowNum; //溢出次數(shù)
float speed; //電機轉(zhuǎn)速
uint8_t direct; //旋轉(zhuǎn)方向
}Motor;
#endif
encoder.c中的內(nèi)容
#include "encoder.h"
Motor motor1;
void Motor_Init(void)
{
HAL_TIM_Encoder_Start(&ENCODER_TIM, TIM_CHANNEL_ALL); //開啟編碼器定時器
__HAL_TIM_ENABLE_IT(&ENCODER_TIM,TIM_IT_UPDATE); //開啟編碼器定時器更新中斷,防溢出處理
HAL_TIM_Base_Start_IT(&GAP_TIM); //開啟100ms定時器中斷
HAL_TIM_PWM_Start(&PWM_TIM, TIM_CHANNEL_2); //開啟PWM
HAL_TIM_PWM_Start(&PWM_TIM, TIM_CHANNEL_1); //開啟PWM
__HAL_TIM_SET_COUNTER(&ENCODER_TIM, 10000); //編碼器定時器初始值設(shè)定為10000
motor1.lastCount = 0; //結(jié)構(gòu)體內(nèi)容初始化
motor1.totalCount = 0;
motor1.overflowNum = 0;
motor1.speed = 0;
motor1.direct = 0;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定時器回調(diào)函數(shù),用于計算速度
{
if(htim- >Instance==ENCODER_TIM.Instance)//編碼器輸入定時器溢出中斷,用于防溢出
{
if(COUNTERNUM < 10000) motor1.overflowNum++; //如果是向上溢出
else if(COUNTERNUM >= 10000) motor1.overflowNum--; //如果是向下溢出
__HAL_TIM_SetCounter(&ENCODER_TIM, 10000); //重新設(shè)定初始值
}
else if(htim- >Instance==GAP_TIM.Instance)//間隔定時器中斷,是時候計算速度了
{
motor1.direct = __HAL_TIM_IS_TIM_COUNTING_DOWN(&ENCODER_TIM);//如果向上計數(shù)(正轉(zhuǎn)),返回值為0,否則返回值為1
motor1.totalCount = COUNTERNUM + motor1.overflowNum * RELOADVALUE;//一個周期內(nèi)的總計數(shù)值等于目前計數(shù)值加上溢出的計數(shù)值
motor1.speed = (float)(motor1.totalCount - motor1.totalCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 10;//算得每秒多少轉(zhuǎn)
//motor1.speed = (float)(motor1.totalCount - motor1.totalCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 10 * LINE_SPEED_C//算得車輪線速度每秒多少毫米
motor1.lastCount = motor1.totalCount; //記錄這一次的計數(shù)值
}
}
使用時需要在main.c的循環(huán)之前調(diào)用Motor_Init函數(shù)進行初始化。
如果發(fā)現(xiàn)無法進入編碼器中斷導(dǎo)致totalCount經(jīng)常溢出歸零,可以嘗試換一種防溢出的方法,代碼如下
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定時器回調(diào)函數(shù),用于計算速度
{
if(htim- >Instance==GAP_TIM.Instance)//間隔定時器中斷,是時候計算速度了
{
motor1.direct = __HAL_TIM_IS_TIM_COUNTING_DOWN(&ENCODER_TIM);//如果向上計數(shù)(正轉(zhuǎn)),返回值為0,否則返回值為1
motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個周期內(nèi)的總計數(shù)值等于目前計數(shù)值加上溢出的計數(shù)值
if(motor1.lastCount - motor1.totalCount > 19000) // 在計數(shù)值溢出時進行防溢出處理
{
motor1.overflowNum++;
motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個周期內(nèi)的總計數(shù)值等于目前計數(shù)值加上溢出的計數(shù)值
}
else if(motor1.totalCount - motor1.lastCount > 19000) // 在計數(shù)值溢出時進行防溢出處理
{
motor1.overflowNum--;
motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個周期內(nèi)的總計數(shù)值等于目前計數(shù)值加上溢出的計數(shù)值
}
motor1.speed = (float)(motor1.totalCount - motor1.lastCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 3000;//算得每秒多少轉(zhuǎn),除以4是因為4倍頻
motor1.lastCount = motor1.totalCount; //記錄這一次的計數(shù)值
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
編碼器
+關(guān)注
關(guān)注
45文章
3957瀏覽量
142733 -
驅(qū)動
+關(guān)注
關(guān)注
12文章
1957瀏覽量
88568 -
電機
+關(guān)注
關(guān)注
143文章
9603瀏覽量
154179 -
STM32
+關(guān)注
關(guān)注
2310文章
11164瀏覽量
373559
發(fā)布評論請先 登錄
相關(guān)推薦
熱點推薦
AB相編碼器-變M/T法測速,10ms定時,測6000轉(zhuǎn)伺服電機!
本帖最后由 SXST_T 于 2017-9-13 12:11 編輯
適用所有線數(shù)編碼器,此方法主要解決M法測低速分辨率不足,T法測高速分辨率高,
發(fā)表于 09-13 12:07
編碼器計數(shù)原理與電機測速原理之多圖解析
,此時編碼器能夠分辨的最小角度為0.15°?! ?.2 M法測速 又叫做頻率測量法。該方法是在一個固定的時間內(nèi)(以秒為單位),統(tǒng)計這段時間
發(fā)表于 03-30 14:57
編碼器常用測速方法
2.1 倍頻技術(shù) 編碼器會輸出兩路方波信號,如果只在通道A的上升沿計數(shù),那就是1倍頻;通道A的上升、下降沿計數(shù),那就是2倍頻;如果在通道A、B的上升、下降沿計數(shù),那就是4倍頻。 使用倍頻可以最大程度
STM32實現(xiàn)編碼器M法測速接線
評論