STM32——编码器测速原理及STM32编码器模式
1. 編碼器概述
編碼器是一種將角位移或者角速度轉換成一連串電數字脈沖的旋轉式傳感 器,我們可以通過編碼器測量到底位移或者速度信息。編碼器從輸出數據類型上 分,可以分為增量式編碼器和絕對式編碼器。
從編碼器檢測原理上來分,還可以分為光學式、磁式、感應式、電容式。常 見的是光電編碼器(光學式)和霍爾編碼器(磁式)。
2. 編碼器原理
光電編碼器是一種通過光電轉換將輸出軸上的機械幾何位移量轉換成脈沖或數字量的傳感器。光電編碼器是由光碼盤和光電檢測裝置組成。光碼盤是在一 定直徑的圓板上等分地開通若干個長方形孔。由于光電碼盤與電動機同軸,電動機旋轉時,檢測裝置檢測輸出若干脈沖信號,為判斷轉向,一般輸出兩組存在一 定相位差的方波信號。
霍爾編碼器是一種通過磁電轉換將輸出軸上的機械幾何位移量轉換成脈沖或數字量的傳感器。霍爾編碼器是由霍爾碼盤和霍爾元件組成。霍爾碼盤是在一 定直徑的圓板上等分地布置有不同的磁極。霍爾碼盤與電動機同軸,電動機旋轉時,霍爾元件檢測輸出若干脈沖信號,為判斷轉向,一般輸出兩組存在一定相位差的方波信號。
可以看到兩種原理的編碼器目的都是獲取 AB 相輸出的方波信號,其使用方法也是一樣,下面是一個簡單的示意圖。
3. 編碼器接線說明
具體到我們的編碼器電機,我們可以看看電機編碼器的實物。
4. 編碼器軟件四倍頻技術
下面我們說一下編碼器倍頻的原理。為了提高大家下面學習的興趣,我們先明確,這是一項實用的技術,可以真正地把編碼器的精度提升 4 倍。作用可類比 于單反相機的光學變焦,而并非犧牲清晰度來放大圖像的數碼變焦。OK,先看看下面編碼器輸出的波形圖。
這里,我們是通過軟件的方法實現四倍頻。首先可以看到上圖編碼器輸出的AB 相波形,正常情況下我們使用 M 法測速的時候,會通過測量單位時間內 A 相輸出的脈沖數來得到速度信息。常規的方法,我們只測量 A 相(或 B 相)的上升 沿或者下降沿,也就是上圖中對應的數字 1234 中的某一個,這樣就只能計數 3次。而四倍頻的方法是測量 A 相和 B 相編碼器的上升沿和下降沿。這樣在同樣的 時間內,可以計數 12 次(3 個 1234 的循環)。這就是軟件四倍頻的原理。
5. STM32編碼器模式
在STM32中,編碼器使用的是定時器接口,通過數據手冊可知,定時器1,2,3,4,5和8有編碼器的功能,而其他沒有。編碼器輸入信號TI1,TI2經過輸入濾波,邊沿檢測產生TI1FP1,TI2FP2接到編碼器模塊,通過配置編碼器的工作模式,即可以對編碼器進行正向/反向計數。
STM32編碼器有三種工作模式,其中模式三即為上文中提到的四倍頻模式。
在使用編碼器模式時需要注意以下幾點:
- 編碼器有個轉速上限,超過這個上限是不能正常工作的,這個是硬件的限制,原則上線數越多轉速就越低,這點在選型時要注意。
- 定時器初始化好以后,任何時候CNT寄存器的值就是編碼器的位置信息,正轉他會加反轉他會減這部分是不需要軟件干預的,初始化時給的TIM_Period 值應該是碼盤整圈的刻度值,在減溢出會自動修正為這個數.加超過此數值就回0.
- 計數值偶爾也會有出錯誤的情況,一圈多計一個或少計一個數都是很正常的特別是轉速比較高的時候尤其明顯,有個絕對位置信號做修正是很有必要的.絕對位置信號不需要一定在零位置點,收到這個信號就將CNT修正為一個固定的數值即可.
6. STM32編碼器模式例程
此例程用于初始化定時器2和定時器3為編碼器模式,得到小車底盤上兩個直流電機的運轉速度。
#.c文件 #include "encoder.h"/************************************************************************** * 函數功能:把TIM2初始化為編碼器接口模式 * * 入口參數:無 * * 返 回 值:無 **************************************************************************/ void Encoder_Init_TIM2(void) {TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定時器2的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);//使能PA PB端口時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //端口配置 PA15GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入GPIO_Init(GPIOA, &GPIO_InitStructure); //根據設定參數初始化GPIOAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //端口配置 PB3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入GPIO_Init(GPIOB, &GPIO_InitStructure); //根據設定參數初始化GPIOBTIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 預分頻器 TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //設定計數器自動重裝值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//選擇時鐘分頻:不分頻TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//邊沿計數模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定時器2TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式3TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一個參數按缺省值填入TIM_ICInitStructure.TIM_ICFilter = 10; //設置濾波器長度TIM_ICInit(TIM2, &TIM_ICInitStructure);//根據 TIM_ICInitStruct 的參數初始化外設 TIMxTIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新標志位TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//使能定時器中斷TIM_SetCounter(TIM2,0);TIM_Cmd(TIM2, ENABLE); //使能定時器2 }/************************************************************************** 函數功能:把TIM3初始化為編碼器接口模式 入口參數:無 返回 值:無 **************************************************************************/ void Encoder_Init_TIM3(void) {TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定時器3的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //端口配置 PA6 PA7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入GPIO_Init(GPIOA, &GPIO_InitStructure); //根據設定參數初始化GPIOATIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 預分頻器 TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //設定計數器自動重裝值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//選擇時鐘分頻:不分頻TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//邊沿計數模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化定時器3TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式3(TIM_ICPolarity_Rising或者TIM_ICPolarity_Falling效果相同,都是4倍頻)TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一個參數按缺省值填入TIM_ICInitStructure.TIM_ICFilter = 10; //設置濾波器長度TIM_ICInit(TIM3, &TIM_ICInitStructure);//根據 TIM_ICInitStruct 的參數初始化外設 TIMxTIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新標志位TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//使能定時器中斷TIM_SetCounter(TIM3,0);TIM_Cmd(TIM3, ENABLE); //使能定時器 }/************************************************************************** 函數功能:單位時間讀取編碼器A計數 入口參數:無 返回 值:計數值 **************************************************************************/ float Read_EncoderA(void) {int Encoder_TIM = 0; float Speed = 0.0; Encoder_TIM= (short)TIM2 -> CNT; TIM2 -> CNT=0;return -Encoder_TIM; } /************************************************************************** 函數功能:單位時間讀取編碼器B計數 入口參數:無 返回 值:計數值 **************************************************************************/ float Read_EncoderB(void) {int Encoder_TIM = 0; float Speed = 0.0; Encoder_TIM= (short)TIM3 -> CNT; TIM3 -> CNT=0;return Encoder_TIM; }/************************************************************************** * 函數功能:TIM2中斷服務函數 * * 入口參數:無 * * 返 回 值:無 **************************************************************************/ void TIM2_IRQHandler(void) { if(TIM2->SR&0X0001)//溢出中斷{ } TIM2->SR&=~(1<<0);//清除中斷標志位 }/************************************************************************** * 函數功能:TIM3中斷服務函數 * * 入口參數:無 * * 返 回 值:無 **************************************************************************/ void TIM3_IRQHandler(void) { if(TIM3->SR&0X0001)//溢出中斷{ } TIM3->SR&=~(1<<0);//清除中斷標志位 } #.h文件 #define __ENCODER_H #include <sys.h> #include "init.h" //include了所有需要的頭文件 #define ENCODER_TIM_PERIOD (u16)(65535) //不可大于65535 因為F103的定時器是16位的。void Encoder_Init_TIM2(void); void Encoder_Init_TIM3(void);float Read_EncoderA(void); float Read_EncoderB(void);void TIM2_IRQHandler(void); void TIM3_IRQHandler(void);#endif總結
以上是生活随笔為你收集整理的STM32——编码器测速原理及STM32编码器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快解析结合海典医药
- 下一篇: 使用screen在云服务器上部署项目使其