????????本次選用的編碼器電機(jī)為13線的霍爾編碼器電機(jī),電機(jī)減速比為30:1,轉(zhuǎn)動一圈輸出13*30=390個脈沖。輪胎直徑為75mm,輪胎周長為pi*d=3*75=225mm.定時器采用四倍頻計(jì)數(shù),則一圈輸出390*4=1560個脈沖。具體編碼器知識這里就不多說了。
?????????根據(jù)測速原理:假設(shè)編碼器輸出的脈沖數(shù)為N,而電機(jī)轉(zhuǎn)動一圈輸出1569個脈沖,轉(zhuǎn)動一圈輪子將前進(jìn)225mm。那輸出脈沖數(shù)為N時前進(jìn)的距離就應(yīng)該為225*(N/1560)mm,再除以時間及可得速度。
下面為具體代碼:
encoder.c文件
#include "encoder.h"
void Encoder_TIM2_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct; //配置IO口
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOA, &GPIO_InitStruct);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //定時器初始化
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 65535;
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
//定時器編碼器模式初始化
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICInitTypeDef TIM_ICInitStruct; //輸入捕獲單元配置
TIM_ICStructInit(&TIM_ICInitStruct);
TIM_ICInitStruct.TIM_ICFilter = 10;
TIM_ICInit(TIM2, &TIM_ICInitStruct);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_SetCounter(TIM2, 0);
TIM_Cmd(TIM2, ENABLE);
}
void Encoder_TIM4_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStruct);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 65535;
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICStructInit(&TIM_ICInitStruct);
TIM_ICInitStruct.TIM_ICFilter = 10;
TIM_ICInit(TIM4, &TIM_ICInitStruct);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_SetCounter(TIM4, 0);
TIM_Cmd(TIM4, ENABLE);
}
int Read_Spead(int TIMx) //讀取編碼器輸出脈沖數(shù)
{
int value_1;
switch(TIMx)
{
case 2:value_1 = (short)TIM_GetCounter(TIM2);TIM_SetCounter(TIM2, 0);break;
case 4:value_1 = (short)TIM_GetCounter(TIM4);TIM_SetCounter(TIM4, 0);break;
default:value_1 = 0;
}
return value_1;
}
void TIM2_IRQHander(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) == 1)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
void TIM4_IRQHander(void)
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) == 1)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
}
? ? ? ? 我使用的是簡單的delay一下來采集定時器捕獲的編碼器脈沖數(shù),不過我建議使用定時器中斷來處理編碼器采集。此函數(shù)只采集右輪脈沖進(jìn)行計(jì)算文章來源:http://www.zghlxwxcb.cn/news/detail-609358.html
主函數(shù)循環(huán)體內(nèi)函數(shù):文章來源地址http://www.zghlxwxcb.cn/news/detail-609358.html
while(1)
{
delay_s(1);
{
uint16_t right = Read_Spead(2);//采集右輪脈沖數(shù)
displacement = 0.225 * (right / 1560);//計(jì)算位移
speed = displacement;//由于我設(shè)置的為延時一秒就不用除時間
OLED_Float(0, 0, speed, 4);//通過OLED顯示速度
set_PWM(999);//設(shè)置電機(jī)PWM
TIM_SetCounter(TIM2, 0);//下一次一秒計(jì)數(shù)前再一次將計(jì)數(shù)清零
}
}
到了這里,關(guān)于stm32霍爾編碼器電機(jī)測速原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!