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

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