免費網(wǎng)站建設ydwzjsseo培訓中心
一、概述
1、Encoder Interface 編碼器接口概念
- 編碼器接口可接收增量(正交)編碼器的信號,根據(jù)編碼器旋轉(zhuǎn)產(chǎn)生的正交信號脈沖,自動控制CNT自增或自減,從而指示編碼器的位置、旋轉(zhuǎn)方向和旋轉(zhuǎn)速度
- 每個高級定時器和通用定時器都擁有1個編碼器接口
- 兩個輸入引腳借用了輸入捕獲的通道1和通道2(只能是通道1)
正交編碼器:
其實只測其中一相就能測出速度,兩相可以知道編碼器正傳還是反轉(zhuǎn)。
編碼器接口基本結(jié)構(gòu):
2、工作模式
TI1指的是通道1,?TI2指的是通道2。
TI1和TI2均不反相(反相就是電平翻轉(zhuǎn)):
TI或TI2反相:
雖然TI1的波形在圖里沒有翻轉(zhuǎn),但是你會發(fā)現(xiàn),TI1上升沿,TI2為低電平,應該為向上計數(shù),而圖中是向下計數(shù),所以TI1或TI2反相為反相計數(shù)器才會向下計數(shù),可以對著表格測試一下。CNT向上計數(shù)表示編碼器正轉(zhuǎn),CNT向下計數(shù)表示編碼器反轉(zhuǎn)。
二、用旋轉(zhuǎn)編碼器進行手動模擬?
完整代碼如下:
- 定時器定時1s
Timer.c:
#include "stm32f10x.h" // Device headerextern uint16_t Num;
void Timer_Init(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;NVIC_InitTypeDef NVIC_InitStructure;//1.配置時鐘,用那個外設RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//2.內(nèi)部時鐘配置TIM_InternalClockConfig(TIM2);//3.配置時基單元TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //濾波頻率TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //計數(shù)方式TIM_TimeBaseInitStruct.TIM_Period=10000-1; //自動重裝載寄存器ARRTIM_TimeBaseInitStruct.TIM_Prescaler=7200-1; //預分頻器TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0; //這個是高級定時器才用的,這里不用,給0TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清除中斷標志位//4.配置中斷輸出控制,打開中斷TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//5.NVIC配置NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);//6.啟動定時器TIM_Cmd(TIM2,ENABLE);
}
Timer.h:
#ifndef _TIMER_H
#define _TIMER_Hvoid Timer_Init(void);#endif
- 編碼器接口
Encoder.c:
這里沒有考慮定時器溢出情況。
#include "stm32f10x.h" // Device headervoid Encoder_Init(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_ICInitTypeDef TIM_ICInitStruct;GPIO_InitTypeDef GPIO_InitStructure;//1.配置時鐘,用那個外設RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_Init(GPIOA, &GPIO_InitStructure);//2.配置時基單元TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; //濾波頻率TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //計數(shù)方式,向上TIM_TimeBaseInitStruct.TIM_Period=65535-1; //自動重裝載寄存器ARR,讓CNT達到最大量程TIM_TimeBaseInitStruct.TIM_Prescaler=1-1; //預分頻器TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);//3.初始化捕獲單元TIM_ICStructInit(&TIM_ICInitStruct); //對結(jié)構(gòu)體進行初始化,防止產(chǎn)生其他影響TIM_ICInitStruct.TIM_Channel=TIM_Channel_1; //選擇輸入通道TIM_ICInitStruct.TIM_ICFilter=0xF; //濾波//TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising; //選擇極性,上升沿TIM_ICInit(TIM3,&TIM_ICInitStruct);TIM_ICInitStruct.TIM_Channel=TIM_Channel_2; //選擇輸入通道TIM_ICInitStruct.TIM_ICFilter=0xF; //濾波//TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising; /選擇極性,上升沿,表示電平不反相TIM_ICInit(TIM3,&TIM_ICInitStruct);//4.配置編碼器接口TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12, TIM_ICPolarity_Falling,TIM_ICPolarity_Rising);//5.啟動定時器TIM_Cmd(TIM3,ENABLE);}int16_t Encoder_Get(void)
{int16_t Temp;Temp=TIM_GetCounter(TIM3);TIM_SetCounter(TIM3,0);return Temp; }
Encoder.h:
#ifndef _ENCODER_H
#define _ENCODER_Hint16_t Encoder_Get(void);void Encoder_Init(void);#endif
main.c:
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "delay.h"
#include "Timer.h"
#include "Encoder.h"int16_t speed;int main(void)
{OLED_Init();Timer_Init();Encoder_Init();OLED_ShowString(1,1,"CNT:");while(1) {OLED_ShowSignedNum(1,5,speed,5);Delay_ms(1000);}}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){speed=Encoder_Get();TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //更新中斷就是產(chǎn)生一個中斷標志位}}