本帖最后由 magicoctoy 于 2017-1-3 14:08 编辑
直接上代码:
/*********************************************************************************************************
编码器脉冲数/1圈
*********************************************************************************************************/
#define ENCODER_PULSE 1000
int main(void)
{
TimerEncoderInit(TIM2); /* 编码器2初始化 */
while(1){
/* 系统灯 1S/闪亮1次 */
if(DelayBuf.SystemLedRunning > 100){
DelayBuf.SystemLedRunning = 0;
LedSystemRun = ~LedSystemRun;
}
Encoder2.Counter = TIM_GetCounter(TIM2);
/* 计算方案2,适用于多圈,且十分简单。
总脉冲 = 单圈实时脉冲值 + (圈数 * 编码器单圈脉冲值 * 4倍数速)
单圈实时脉冲值:通过获取 TIM_GetCounter(TIMx)。
圈数:定时器溢出中断中得到。
编码器单圈脉冲值:编码器参数。
4倍数速:定时器设定值,A相和B相上下沿都计数。*/
Encoder2.Pulse = Encoder2.Counter + (Encoder2.Circle * ENCODER_PULSE * 4);
/* 计算方案1,适用于单圈,多圈时必须在溢出时增加判断,否则有误。 */
// Encoder2.Pulse += Timer2GetCount();
}
}
/*
*********************************************************************************************************
* 函数名称: TimerEncoderInit
* 函数功能: 定时器/计数器,编码器接入初始化配置
* 输入参数:timer:TIM1~TIM4。
* 输出参数:无
* 返回值: 无
* 说明:
*********************************************************************************************************
*/
void TimerEncoderInit(TIM_TypeDef* timer)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/*----------------------------------------------------------------*/
if(timer == TIM1){
RCC_APB2PeriphClockCmd(ENCODER_1_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = ENCODER_1_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(ENCODER_1_PORT, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}else if(timer == TIM2){
RCC_APB2PeriphClockCmd(ENCODER_2_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = ENCODER_2_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(ENCODER_2_PORT, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}else if(timer == TIM3){
RCC_APB2PeriphClockCmd(ENCODER_3_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = ENCODER_3_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(ENCODER_3_PORT, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}else if(timer == TIM4){
RCC_APB2PeriphClockCmd(ENCODER_4_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = ENCODER_4_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(ENCODER_4_PORT, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
}
/*----------------------------------------------------------------*/
/*初始化TIM1定时器-时间基数 */
TIM_TimeBaseStructure.TIM_Period =(ENCODER_PULSE * 4)-1; //设定计数器重装值
TIM_TimeBaseStructure.TIM_Prescaler =0; //设置预分频,=0无预分频器,捕获输入口上检测到的每一个边沿都触发一次捕获
TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ; //设置时钟分频系数:不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式,DIR方向 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重复计数设置(高级定时器TIM1和TIM8)不加进不了定时器1和8中断
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
/*-----------------------------------------------------------------*/
/* 编码配置-编码模式 */
TIM_EncoderInterfaceConfig(timer, TIM_EncoderMode_TI12,
TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge); //使用编码器模式3,上升下降都计数
/*----------------------------------------------------------------*/
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //TIM输入捕获上升沿
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//TIM输入1/2/3/4选择对应的与IC1/IC2/IC3/IC4相连
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //TIM捕获在捕获输入上每探测到一个边沿执行一次
TIM_ICInitStructure.TIM_ICFilter = 6; //选择输入比较滤波器:0x0~0xF
TIM_ICInit(timer, &TIM_ICInitStructure); //将TIM_ICInitStructure中的指定参数初始化TIM3
/*----------------------------------------------------------------*/
TIM_ClearFlag(timer, TIM_FLAG_Update); //清除,溢出更新中断。
TIM_ITConfig(timer, TIM_IT_Update, ENABLE); //使能,溢出更新中断,计数器向上溢出/向下溢出。
/*----------------------------------------------------------------*/
if(timer == TIM1){
// TIM1->CNT =0; //复位计数值
TIM_SetCounter(TIM1,0);
}else if(timer == TIM2){
TIM_SetCounter(TIM2,0);
}else if(timer == TIM3){
TIM_SetCounter(TIM3,0);
}else if(timer == TIM4){
TIM_SetCounter(TIM4,0);
}
TIM_Cmd(timer, ENABLE); //使能定时器
/*----------------------------------------------------------------*/
}
/*
*********************************************************************************************************
* 函数名称: TIM2_IRQHandler
* 函数功能: TIM2中断处理函数
* 输入参数:无
* 输出参数:无
* 返回值: 无
* 说明:
*********************************************************************************************************
*/
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET){
TIM_ClearITPendingBit(TIM2,TIM_IT_Update); /* 清除中断标志 */
Encoder2.Counter = TIM_GetCounter(TIM2);
if((((TIM2->CR1)&0x0010)>>4) == 1){ /* 判断计数器计数方向 */
/* =1,向下计数 */
Encoder2.Direction = 1;
Encoder2.Circle --;
}else{
/* =0,向上计数 */
Encoder2.Direction = 0;
Encoder2.Circle ++;
}
}
}
/*
*********************************************************************************************************
* 函数名称: Timer2GetCount
* 函数功能: TIM2得到编码器脉冲值。
* 输入参数:无
* 输出参数:无
* 返回值: 无
* 说明:
*********************************************************************************************************
*/
s32 Timer2GetCount(void)
{
static u16 lastCount = 0;
u16 nowCount;
s32 pulse;
nowCount = TIM_GetCounter(TIM2);
pulse = nowCount - lastCount;
if(pulse >= (ENCODER_PULSE/2)){
pulse -= ENCODER_PULSE;
}else if(pulse < -(ENCODER_PULSE/2)){
pulse += ENCODER_PULSE;
}
lastCount = nowCount;
return (s32)pulse;
}
一周热门 更多>