我最近有一个项目要利用stm32的编码器模式计数,我很苦恼,我想用原子的寄存器设置模式,库函数的我没有很好的接触,我自己也配置了,可是lcd上始终显示不到数字,这是库函数的程序:
void ENC_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APBPeriph_ENCODER_TIMER, ENABLE); // ENCODER_TIMER时钟初始化
RCC_APB2PeriphClockCmd(RCC_APBPeriph_ENCODER_GPIO, ENABLE); // ENCODER_GPIO时钟初始化
GPIO_StructInit(&GPIO_InitStructure); //TI1 TI2初始化
GPIO_InitStructure.GPIO_Pin = ENCODER_TI1 | ENCODER_TI2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(ENCODER_GPIO, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIMER_IRQChannel; //设置ENCODER_TIMER的优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Timer configuration in Encoder mode */ //设置ENCODER_TIMER为编码器模式
TIM_DeInit(ENCODER_TIMER); //ENCODER_TIMER复位
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 无分频
TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1; //计数器重载值 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //编码器接口初始化
//TIM_ICPolarity_Rising: TIM输入捕获上升沿
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER; // TIM_ICFilter选择输入比较滤波器。该参数取值在0x0和0xF之间
TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);
// Clear all pending interrupts
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);// 清除TIMx的待处理标志位
TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE); //使能或者失能指定的TIM中断
//Reset counter
TIM2->CNT = COUNTER_RESET;
TIM_Cmd(ENCODER_TIMER, ENABLE); // 使能或者失能TIMx外设
}
//****************************************************************************************************
// 计算马达转子相对于初始位置的角度 -180至+180
//****************************************************************************************************
void ENC_Get_Electrical_Angle(uint16_t *degree)
{
int32_t temp;
int16_t tim_count;
tim_count=TIM_GetCounter(ENCODER_TIMER); //获取ENCODER_TIMER的值
if(tim_count>=400) //如果超过180度,角度为负数
{
degree[0]='-';
degree[1]=(800-tim_count)*180/(4*ENCODER_PPR/2); //整数部分
temp = (int32_t)(800-tim_count) * (int32_t)(1000000/(4*ENCODER_PPR/2))*360-degree[1]*1000000;
degree[2]=(unsigned char)temp; //小数部分
}
else //如果未超过180度,角度为正数
{
degree[0]='+';
degree[1]=tim_count*180/(4*ENCODER_PPR/2); //整数部分
temp = (int32_t)tim_count * (int32_t)(1000000/(4*ENCODER_PPR/2))*180-degree[1]*1000000;
degree[2]=(unsigned char)temp; //小数部分
}
}
//****************************************************************************************************
//TIm2_IRQ 计算编码器每秒钟产生的脉冲数
//**************************************************************************************************
void Tim2_IRQ(void)
{
unsigned int temp;
if(Count[0]==0)
{
Count[0]++; //以便下次读取并计算
Count[2]=Count[1];
Encoder_TIM_Count[0]=TIM_GetCounter(ENCODER_TIMER); //第一次读取ENCODER_TIMER的值
}
else
{
temp=Count[1]-Count[2]; //ENCODER_TIMER溢出次数
Encoder_TIM_Count[1]=TIM_GetCounter(ENCODER_TIMER); //第二次读取ENCODER_TIMER的值
Count[0]=0;
Count[1]=0;
if(temp==0) //如果ENCODER_TIMER溢出次数为0
{
if(Encoder_TIM_Count[1]>=Encoder_TIM_Count[0])
{
Speed[1]=(Encoder_TIM_Count[1]-Encoder_TIM_Count[0])*8; //每秒的脉冲数等于两次计数器差的绝对值*4
}
else
{
Speed[1]=(Encoder_TIM_Count[0]-Encoder_TIM_Count[1])*8;
}
}
else //如果ENCODER_TIMER溢出次数不为0
{
if(Speed[0]=='+') //如果ENCODER_TIMER正向溢出
{
if(Encoder_TIM_Count[1]>=Encoder_TIM_Count[0])
{
Speed[1]=(Encoder_TIM_Count[1]-Encoder_TIM_Count[0]+(4*ENCODER_PPR)*temp)*8;
}
else
{
Speed[1]=(800-Encoder_TIM_Count[0]+Encoder_TIM_Count[1]+(4*ENCODER_PPR)*(temp-1))*8;
}
}
else //如果ENCODER_TIMER逆向溢出
{
Speed[1]=(800-Encoder_TIM_Count[1]+Encoder_TIM_Count[0]+(4*ENCODER_PPR)*(temp-1))*8;
}
}
}
}
//****************************************************************************************************
//TIm4_IRQ 获得溢出此数count[1]和旋转方向speed
//****************************************************************************************************
void Tim4_IRQ(void)
{
unsigned int temp;
Count[1]++;
/* Clear the interrupt pending flag */
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);
temp=TIM_GetCounter(ENCODER_TIMER);
if(temp==0) //如果计数器的值为0,则正向旋转
Speed[0]='+';
else if(temp==799) //如果计数器的值为0,则逆向旋转
Speed[0]='-';
}
库函数版本的编码器很多例子,可是原子大哥配置的寄存器模式,不知道哪位大哥、大神可曾经调试过,或者有什么经验,可以交流一下,我的qq号是505021476,谢谢了!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
---------------------------------
你的编码器模式能够起作用了没?
一周热门 更多>