簡(jiǎn)要描述下STM32 定時(shí)器對(duì)正交編碼器進(jìn)行計(jì)數(shù)控制的方法
掃描二維碼
隨時(shí)隨地手機(jī)看文章
如圖,STM32的每個(gè)TIMER都有正交編碼器輸入接口,TI1,TI2經(jīng)過輸入濾波,邊沿檢測(cè)產(chǎn)生TI1FP1,TI2FP2接到編碼器模塊,通過配置編碼器的工作模式,即可以對(duì)編碼器進(jìn)行正向/反向計(jì)數(shù)。
如下圖,編碼器使用了A,B兩相信號(hào),但是我只需要對(duì)TI1信號(hào)進(jìn)行計(jì)數(shù)(第一行),我也是剛發(fā)現(xiàn)了這個(gè)錯(cuò)誤,原來(lái)對(duì)兩個(gè)信號(hào)都計(jì)數(shù),導(dǎo)致碼盤轉(zhuǎn)一周得到不止100個(gè)脈沖(100線的光電碼盤)。通過STM32的編碼器模塊比較兩想的電平信號(hào)就可以很容易地計(jì)算出編碼器的運(yùn)行情況了。
下面是我調(diào)試OK的代碼:
void Encoder_Configration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
//PC6 A相 PC7 B相
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling
TIM_TimeBaseStructure.TIM_Period = 10000;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM8, TIM_EncoderMode_TI12,
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 6;//ICx_FILTER;
TIM_ICInit(TIM8, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(TIM8, TIM_FLAG_Update);
TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);
//Reset counter
TIM2->CNT = 0;
TIM_Cmd(TIM8, ENABLE);
}
n_Counter = TIM_GetCounter(TIM8);
Diled_Disp_Num((float)n_Counter);
另外一個(gè)值得注意的問題是,STM32 的定時(shí)器是16位的,意思是只能計(jì)數(shù)到65535,有兩種方法,一是采用鏈?zhǔn)降姆绞接脙蓚€(gè)定時(shí)器將16位擴(kuò)展為32位,還有一種簡(jiǎn)單的方法就是開啟定時(shí)器的溢出中斷,每中斷一次就代表編碼器運(yùn)轉(zhuǎn)了特定的角度。
比如編碼器是400線的,將ARR寄存器設(shè)置為400,每溢出中斷一次就代表電機(jī)轉(zhuǎn)了一圈,以此類推。
另外,關(guān)于輸入脈沖的檢測(cè),其實(shí)是類似的,只不過在STM32內(nèi)部是專門用了一個(gè)外部觸發(fā)模塊來(lái)實(shí)現(xiàn)的,如圖一中紫色框的標(biāo)注,編碼器模塊應(yīng)該是在這個(gè)模塊上的升級(jí),下面是配置代碼:
void TIM3_ETR_GetDropCounts_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//test PA0 TIM8_ETR
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x00;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Time base configuration
TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE);
}