一、編碼器接口簡介
- Encoder Interface 編碼器接口
- 編碼器接口可接收增量(正交)編碼器的信號,根據(jù)編碼器旋轉(zhuǎn)產(chǎn)生的正交信號脈沖,
自動控制CNT自增或自減
,從而指示編碼器的位置、旋轉(zhuǎn)方向和旋轉(zhuǎn)速度 - 每個高級定時器和通用定時器都擁有
1個編碼器接口
,C8T6擁有4個編碼器接口 兩個輸入引腳借用了輸入捕獲的通道1和通道2(CH1和CH2引腳)
- 編碼器接口可以看做是帶有方向控制的外部時鐘
- 實際上是測頻法測正交脈沖的頻率,可以根據(jù)旋轉(zhuǎn)方向,實現(xiàn)自增計次,自減計次,然后每隔一段時間取一次CNT的值,再把CNT清零,每次取出來的就是
編碼器的速度
。如果只是取出CNT的值不清零,則表示編碼器當前的位置
- 外部中斷實現(xiàn)的效果和編碼器接口實現(xiàn)的效果相同,區(qū)別是后者使用硬件資源取代軟件資源開銷
二、正交編碼器
- 可以測量位置(返回CNT的值),或帶方向的速度值(返回CNT的變化值)
- 旋轉(zhuǎn)越快,頻率越高,頻率代表速度
- 設計正交信號可以抗噪聲
- 由右側(cè)的圖可知,A相上升沿的時候,B相在正傳和反轉(zhuǎn)時是不同的電平。所以,將A相和B相的所以邊沿作為計數(shù)器的時鐘,出現(xiàn)邊沿變化時,計數(shù)器就自增或自減
三、通用定時器框圖
- 編碼器接口的兩個輸入引腳借用了輸入捕獲的通道的CH1和CH2引腳
- 編碼器接口是從模式控制器,通路連接到CNT計數(shù)器
- 72MHZ的內(nèi)部時鐘和時基單元初始化設置的計數(shù)方向并不會使用,而是受到編碼器控制
四、編碼器接口基本結(jié)構(gòu)
- ARR自動重裝器設置為65535。利用補碼特性得到負數(shù),將16位的無符號數(shù)轉(zhuǎn)化為16位的有符號數(shù),65535為-1,65534為-2。
- 函數(shù)
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//配置編碼器接口,第二個參數(shù)為編碼器模式,參數(shù)三四為通道的極性
- 邊沿檢測:上升沿有效表示的是高低電平不翻轉(zhuǎn),下降沿有效表示翻轉(zhuǎn)高低電平
五、工作模式
- 四倍頻技術(shù)
- 左側(cè)的有效邊沿為3種工作模式:由于在判斷為正轉(zhuǎn)時可以有四種狀態(tài),也就是AB相都可以用來判斷,僅僅采用一個通道進行判斷也可以只是計次精度會下降
六、實例(均不反相)
- 一個引腳不變,另一個引腳多次變化的毛刺信號,計數(shù)值還是原來那個數(shù)
七、實例(TI1反相)
- TI1反相,在分析前先將TI1的時序圖翻轉(zhuǎn)
- TI1反相,
是修改將CH1或2通道內(nèi)的極性選擇,在編碼器模式下是高低電平的極性翻轉(zhuǎn),而不是輸入捕獲模式下的邊沿翻轉(zhuǎn)
- 用途:當計數(shù)相反的時候可以修改極性
八、編碼器接口測速
本質(zhì):編碼器計次,計次可以使用外部中斷方式,方波信號來自編碼器,在中斷函數(shù)里面手動計次,占用軟件資源,CPU會頻繁進入中斷,可以采用硬件自動化計次,也就是定時器的編碼器接口模式。
使用場景:使用PWM驅(qū)動電機,再使用編碼器(無接觸式的霍爾傳感器或光柵)測量電機速度,再用PID算法實現(xiàn)閉環(huán)控制
電路設計
旋轉(zhuǎn)編碼器的AB相分別接PA6和PA7
關(guān)鍵代碼
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
int16_t Speed;
int main(void)
{
OLED_Init();
Timer_Init();
Encoder_Init();
OLED_ShowString(1, 1, "Speed:");
while (1)
{
OLED_ShowSignedNum(1, 7, Speed, 5);//OLED_ShowSignedNum()可以顯示負數(shù)
//Delay_ms(1000);為了避免在主循環(huán)中造成阻塞,可以用定時中斷的方式讀取CNT的變化值,如TIM2_IRQHandler()函數(shù)
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
Speed = Encoder_Get();//每隔一秒讀取一次速度
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
Encoder.c文章來源:http://www.zghlxwxcb.cn/news/detail-804117.html
#include "stm32f10x.h" // Device header
void Encoder_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//因為編碼器接口是一個帶有方向控制的外部時鐘,所以不需要配置時鐘
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//計數(shù)模式也是無效,由編碼器接口控制
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1; //PSC,不分頻,編碼器時鐘直接驅(qū)動計數(shù)器
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//通道1
TIM_ICInitStructure.TIM_ICFilter = 0xF;//濾波器
TIM_ICInit(TIM3, &TIM_ICInitStructure);
//無須定義新的結(jié)構(gòu)體配置成員,因為調(diào)用TIM_ICInit()函數(shù)后就寫入到硬件寄存器中
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;//通道2
TIM_ICInitStructure.TIM_ICFilter = 0xF;//濾波器
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//配置編碼器接口,第二個參數(shù)為編碼器工作模式,參數(shù)三四為通道的極性,F(xiàn)alling表示通道反向,Rising表示通道不反向
TIM_Cmd(TIM3, ENABLE);
}
//返回有符號位的16位計數(shù)器的值
int16_t Encoder_Get(void)
{
int16_t Temp;
Temp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
return Temp;
}
參考視頻:江科大自化協(xié)文章來源地址http://www.zghlxwxcb.cn/news/detail-804117.html
到了這里,關(guān)于STM32——TIM編碼器接口的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!