一、编码器接口简介
(1)Encoder Interface 编码器接口
<1>
编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,
自动控制CNT自增或自减
,从而指示
编码器的位置
、
旋转方向
和
旋转速度
<2>每个
高级定时器和通用定时器
都拥有
1个编码器接口
<3>
两个输入引脚借用了输入捕获的通道
1和通道2
(2)正交编码器
二、编码器接口基本结构框图
三、编码器接口测速代码
#include "stm32f10x.h" // Device header
#include "OLED.h"
uint16_t speed=0;
void TimerInit(void);
void EncoderInit(void);
int16_t EncoderGetCount(void);
int main(void)
{
TimerInit();
OLED_Init();
EncoderInit();
while(1)
{
OLED_ShowNum(1,7,speed,5);
}
}
/***************************************************************
* @brief void TimerInit(void)
* @param void
* @note 初始化中断引脚
* @Sample TimerInit();
**************************************************************/
void TimerInit(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
NVIC_InitTypeDef NVIC_InitStruct;
TIM_InternalClockConfig(TIM2);//选用内部时钟
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//指定时钟分频
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式
TIM_TimeBaseInitStruct.TIM_Period=10000-1;//周期ARR自动重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//PSC预分频器的值
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器的值
//定时频率=72M/(PSC+1)*(ARR+1)
//定时时间=1/[72/(PSC+1)]*(ARR+1)
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断
NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;//中断通道
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择分组2
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM2,ENABLE);//启动定时器
}
/***************************************************************
* @brief void TIM2_IRQHandler()
* @param void
* @note 定时器中断函数
* @Sample 无
**************************************************************/
void TIM2_IRQHandler()
{
if( TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//判断中断标志位是否被置一
{
speed=EncoderGetCount();
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
/***************************************************************
* @brief void EncoderInit(void)
* @param void
* @note 编码器模式初始化
* @Sample EncoderInit();
**************************************************************/
void EncoderInit(void)
{
//1、开始时钟
TIM_ICInitTypeDef TIM_ICInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//2、配置GPIO引脚
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//指定时钟分频
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式
TIM_TimeBaseInitStruct.TIM_Period=65536-1;//周期ARR自动重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;//PSC预分频器的值 决定了测周法的标准频率fc
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器的值
//定时频率=72M/(PSC+1)*(ARR+1)
//定时时间=1/[72/(PSC+1)]*(ARR+1)
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
//3、配置输入捕获模式
TIM_ICStructInit(&TIM_ICInitStruct);
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_Rising,TIM_ICPolarity_Rising);
TIM_Cmd(TIM3,ENABLE);
}
/***************************************************************
* @brief int16_t EncoderGetCount(void)
* @param void
* @note 获取转动速度
* @Sample EncoderGetCount( );
**************************************************************/
int16_t EncoderGetCount(void)
{
int16_t Tem;
Tem=TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return Tem;
}