STM32编码器读取不准确问题!!!333333

一、微项目实现目标:

检测旋转编码器模式下,检测旋转编码器的转动计数值及转速。并且区分转向,一侧转动增加cout,转速值为正,一侧转动减少count,转速值为负;

二、微项目硬件配置需求:

1,stm32F103C8T6核心板一块

2,0.96寸OLED显示,用于显示计数

3,旋转编码器,反馈正交信号脉冲

三、前置知识:

1,编码器计数模式框图

 ①信号流:

两路GIPO输入---滤波器----边沿检测极性选择---输入TI1FP1和TI2FP2给到编码器接口---根据相位模式(T1和T2的相位之差)判断CNT是向上计数还是向下计数-----经过分频器处理,最后实现计数

②计数模式

 如果一直向下计数到0,在继续计数时,则寄存器数据由于无符号整型缘故,会变成65535,由于数据以补码的形式存储,则强转为int时刻,会变成-1;

③旋转编码器的输入波形情况

正转时刻,A相输出超出B相输出90度

反转时刻,A相输出滞后B相输出90度

 ④设置正相模式与反相模式

就是对于计数模式的一次反向处理,并对应到原本的计数模式上(一般用的较少)

反向之后

四、代码逻辑分析:

①打开TIM3和GPIOA的时钟

②配置GPIOA的PA5和PA6

③初始化时基模块(注意,在编码器模式下,不需要配置时钟源,输入的TI1FP1或TI2FP2作为时钟),主要是指ARR和PSC

④初始化输入捕获模块,通道1 和通道2都需要配置

⑤配置配置编码器接口

⑥开启时钟模块

五、代码示例:

①打开TIM3和GPIOA的时钟

//初始化时钟TIM3 ,PA
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
②配置GPIOA的PA5和PA6,上拉输入

    //配置PA6\PA7输入GPIO
    GPIO_InitTypeDef GPIO_InitStruct;
    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);
③初始化时基模块(注意,在编码器模式下,不需要配置时钟源,输入的TI1FP1或TI2FP2作为时钟),主要是指ARR和PSC

//初始化时基模块
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    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=1-1;//PSC,不分频
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct);
④初始化输入捕获模块,通道1 和通道2都需要配置

    //输入捕获单元配置
    TIM_ICInitTypeDef TIM_ICInitStruct;
    TIM_ICStructInit(& TIM_ICInitStruct);//先进行默认初始化
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
    TIM_ICInitStruct.TIM_ICFilter=0xf;
    
    TIM_ICInit(TIM3,&TIM_ICInitStruct);//TIM3-CH1通道
    
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;
    TIM_ICInitStruct.TIM_ICFilter=0xf;
    TIM_ICInit(TIM3,&TIM_ICInitStruct);//TIM3-CH2通道
⑤配置配置编码器接口

    //配置编码器接口
    TIM_EncoderInterfaceConfig( TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising
                                , TIM_ICPolarity_Rising);
⑥开启时钟模块

TIM_Cmd(TIM3,ENABLE);
⑦获取速度模块

本质上,获取的是CNT的计数值,但是如果1S读取一次,并且清空为0 ,则实现了速度测算的功能

1-注意此处的强制转化为有符号数据(反码存储)

2-需要配合定时器中断1S使用(或者延时1S执行一次,当然中断的形式更佳)

int16_t getspeedn(void)
{    
    int16_t temp;
    temp= TIM_GetCounter(TIM3);
    TIM_SetCounter(TIM3,0);
    return temp;
}
⑧主函数中配置

#include "key.h"
void delay_s(unsigned long t)
{
    while(t--);
}
void led_config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//ʹŜA
    
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void key_config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//ʹŜA
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

int key_scan(GPIO_TypeDef* GPIOx,unsigned int Pin)
{
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)
    {
        delay_s(100);
        if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0)
        {
            while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0);
            return KEY_PRESS;
        }
        return KEY_OFF;
    }
    return KEY_OFF;
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32编码器测速可以使用两种方法。第一种方法是利用定时器的编码器模式来测速,这种方法更加快捷简单,并且不会占用太多的MCU资源。通常情况下,我们会优先使用这种方法,只有当定时器资源不足时才会考虑使用第二种方法。在这种方法中,我们可以直接读取定时器的CNT计数器中的值来获取捕获的脉冲数。需要注意的是,CNT寄存器的最大值是65536,超过这个值后计数器会溢出,所以我们需要及时读取CNT并将其清空。我可以提供完整的Keil代码供您参考\[1\]\[2\]。 第二种方法是使用霍尔编码器来测速。霍尔编码器在上电后的默认电平是高电平,当磁铁经过传感器前端时,会出现一段时间的低电平。我们可以通过STM32定时器的输入捕获功能来确定低电平的时间,从而计算出速度。在配置时,我们需要将第一次捕获设置为下降沿捕获\[3\]。 总结起来,STM32编码器测速可以使用定时器编码器模式或者霍尔编码器。定时器编码器模式更加简单快捷,而霍尔编码器需要通过输入捕获计算时间来测速。具体选择哪种方法取决于您的需求和资源限制。 #### 引用[.reference_title] - *1* *2* [STM32直流减速电机控制篇(三)编码器测速程序编写](https://blog.csdn.net/qhdd123/article/details/108033612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [stm32霍尔编码器测速(标准库函数版)](https://blog.csdn.net/champion_0/article/details/128046368)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值