encoder.c
#include "encoder.h"
//encoder.INPUT_B---PA6(TIM3_CH1)
//encoder.INPUT_A---PA7(TIM3_CH2)
u16 OldCNT=0;
int CNTFlowFlag=0;
void TIM_EncoderInterfaceConfig( uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
//定时器3中断服务程序
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//溢出中断
{
CNTFlowFlag=1;
}
TIM3->SR&=~(1<<0);//清除中断标志位
}
void Encoder_Configuration(void)
{
RCC->APB1ENR|=1<<1; //TIM3 时钟使能
RCC->AHB1ENR|=1<<0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);//复用功能,下拉
GPIO_Set(GPIOA,PIN7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);//复用功能,下拉
GPIO_AF_Set(GPIOA,6,2); //PA0,AF2
GPIO_AF_Set(GPIOA,7,2); //PA0,AF2
TIM_EncoderInterfaceConfig(TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);
TIM3->DIER|=1<<0; //允许更新中断
MY_NVIC_Init(1,3,TIM3_IRQn,2); //抢占1,子优先级3,组2
TIM3->CR1|=0x01; //使能定时器3
}
void TIM_EncoderInterfaceConfig( uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
{
uint16_t tmpsmcr = 0;
uint16_t tmpccmr1 = 0;
uint16_t tmpccer = 0;
/* Get the TIMx SMCR register value */
tmpsmcr = TIM3->SMCR;
/* Get the TIMx CCMR1 register value */
tmpccmr1 = TIM3->CCMR1;
/* Get the TIMx CCER register value */
tmpccer = TIM3->CCER;
/* Set the encoder Mode
SMS:从模式选择 (Slave mode selection),011:编码器模式 3––计数器在 TI1FP1 和 TI2FP2 的边沿计数,计数的方向取决于另外一
个信号的电平。
*/
tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
tmpsmcr |= TIM_EncoderMode;
/* Select the Capture Compare 1 and the Capture Compare 2 as input
CC2S[1:0]:01:CC2 通道配置为输入,IC2 映射到 TI2 上
CC1S[1:0]:01:CC1 通道配置为输入,IC1 映射到 TI1 上。
*/
tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)));
tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
/* Set the TI1 and the TI2 Polarities
CC1 通道配置为输入:CC1NP/CC1P 位可针对触发或捕获操作选择 TI1FP1 和 TI2FP1 的极性。
00:非反相/上升沿触发
TIxFP1 未反相 (在门控模式或编码器模式下执行触发操作)。
01:反相/下降沿触发
TIxFP1 反相 (在门控模式或编码器模式下执行触发操作)。
*/
tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P)));
tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
/* Write to TIMx SMCR */
TIM3->SMCR = tmpsmcr;
/* Write to TIMx CCMR1 */
TIM3->CCMR1 = tmpccmr1;
/* Write to TIMx CCER */
TIM3->CCER = tmpccer;
}
int Encoder_Get_CNT(void)
{
u16 NewCNT=0;
int CNT;
NewCNT=TIM3->CNT;
CNT=NewCNT-OldCNT;
if(CNTFlowFlag==1)
{
if(NewCNT>30000) CNT=(int)(NewCNT-(65536+OldCNT));
if(NewCNT<30000) CNT=(int)(NewCNT+65536-OldCNT);
CNTFlowFlag=0;
}
OldCNT=NewCNT;
return CNT;
}
encoder.h
#ifndef __ENCODER_H
#define __ENCODER_H
#include &quot;sys.h&quot;
#define TIM_EncoderMode_TI1 ((uint16_t)0x0001)
#define TIM_EncoderMode_TI2 ((uint16_t)0x0002)
#define TIM_EncoderMode_TI12 ((uint16_t)0x0003)
#define TIM_ICPolarity_Rising ((uint16_t)0x0000)
#define TIM_ICPolarity_Falling ((uint16_t)0x0002)
#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A)
void Encoder_Configuration(void);
int Encoder_Get_CNT(void);
#endif |