stm32 用定时器的编码器模式来检测正反转444444

stm32 用定时器的编码器模式来检

2、脉冲计数对应电机速度的数据两种处理方式
(1) 定时器中断法,计算电机的圈数(过程小题大做,不推荐)
前面提到了编码器的线数为1024线(编码器每转一周就会输出1024个脉冲),那么你的重装载值为(1024-1),当计数值达到1024就会发生溢出中断,也就是说识别到了脉冲数为1024个(编码器转了一圈)。每发生一次中断,就说明电机转了一圈
(1)脉冲计数法,直接根据单位时间内所采集到的脉冲数作为电机的转速(更加精准,推荐)
编码器在实际的测数使用时确实是根据,电机转一圈:编码器转多少圈的方式来实际测量电机的转速的,但是在其本质就还是编码器的输出的脉冲数,所以直接计算编码器的单位时间的脉冲数推算电机的速度是一样的,数据来的更加直接、精准。
3、STM32定时器编码器模式理论分析
(1)定时器编码器模式选择


首先是定时器编码器模式的选择,其实就是选择在那一个通道计数,还是两个通道都要计数也就是这三种模式。
对于带方向的就只有一路脉冲,所以选择其中一路通道就ok了。
对于正交编码器而言有两路脉冲,所以就选择第三中方式,两路通道都计数。
(2)定时器编码器输入极性的选择
看懂这张图才是,确定输入极性的关键所在:所谓极性就是选择在输入脉冲信号的上升沿计数还是下降沿计数。

(3)定时器编码器输入极性的寄存器配置

CC1S=’01’ (TIMx_CCMR1寄存器,IC1FP1映射到TI1) 
CC2S=’01’ (TIMx_CCMR1寄存器,IC2FP2映射到TI2) 
CC1P=’0’ (TIMx_CCER寄存器,IC1FP1不反相,IC1FP1=TI1) 
CC2P=’0’ (TIMx_CCER寄存器,IC2FP2不反相,IC2FP2=TI2) 
SMS=’011’ (TIMx_SMCR寄存器,所有的输入均在上升沿和下降沿有效). 
CEN=’1’ (TIMx_CR1寄存器,计数器使能)
1
2
3
4
5
6
这里解释一下
TIx 就相当于输入信号的 TIM4->CH1 TIM4->CH2;
TIxF 滤波后信号;
TIxFPx经过带极性选择的边缘检测器过后的产生的信号;

4、结合手册函数刨析库函数
(1)STM32定时器编码器模式的库函数配置代码
/*TIM2初始化为编码器接口*/
void Encoder_Init_TIM2(void)
{
    //结构体变量的创建
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
    TIM_ICInitTypeDef TIM_ICInitStructure;  
    GPIO_InitTypeDef GPIO_InitStructure;
    //RCC时钟使能
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器4的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口时钟
    
     //编码器引脚的配置,对于定时器的通道管脚在用户手册上的==8.3.7定时器复用功能重映射==
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;    //端口选择
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                //根据设定参数初始化GPIOA
    
    //定时器的基本配置,这里主要介绍定时器的编码器模式,不做过多解释
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 
    TIM_TimeBaseStructure.TIM_Period = 0xffff; //设定计数器自动重装值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数  
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    //编码器模式选择与配置
    //参数一TIMx:定时器的选择
    //参数二TIM_EncoderMode:编码器模式的选择
    //参数三TIM_IC1Polarity:通道一的极性选择
    //参数四TIM_IC2Polarity:通道二的极性选择
//具体配置->正交编码器:配置如下
    TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
//带方向的编码器配置如下->区别只在于带方向的编码器只有一个脉冲输入,而正交编码器有两个脉冲输入
    TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

    TIM_ICStructInit(&TIM_ICInitStructure);
    TIM_ICInitStructure.TIM_ICFilter = 10;
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    //Reset counter
    TIM_SetCounter(TIM2,0);
    TIM_Cmd(TIM2, ENABLE); 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(2)刨析
转到void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)函数下可以看到如下代码:
/* Get the TIMx SMCR register value */
  tmpsmcr = TIMx->SMCR;
  
  /* Get the TIMx CCMR1 register value */
  tmpccmr1 = TIMx->CCMR1;
  
  /* Get the TIMx CCER register value */
  tmpccer = TIMx->CCER;
1
2
3
4
5
6
7
8
再看下面来自用户手册中的截图,就不用我再继续挖下去了。

5、编码器速度的读取
前面已经说过了编码器的脉冲计数对应电机速度的数据处理方法,这里就继续说明了。
速度是单位时间为前提的,我这里采用的是直接计算单位时间对应的脉冲数来推算电机的速度的。这里的单位时间也就是采样率的意思,就是我们间隔多少时间去采集然后清零脉冲计数值一次。这里的采样率不能太高,也不能太低。对电机的控制,一般采样率=5毫秒越小就越接近瞬时速度,为什么不能过小想必不用说大家也知道。所以这里就需要一个定时器来计算采样周期
————————————————
版权声明:本文为优快云博主「君墨蘭」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_45276147/article/details/126309377

#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;
}
 

测正反转

2、脉冲计数对应电机速度的数据两种处理方式
(1) 定时器中断法,计算电机的圈数(过程小题大做,不推荐)
前面提到了编码器的线数为1024线(编码器每转一周就会输出1024个脉冲),那么你的重装载值为(1024-1),当计数值达到1024就会发生溢出中断,也就是说识别到了脉冲数为1024个(编码器转了一圈)。每发生一次中断,就说明电机转了一圈
(1)脉冲计数法,直接根据单位时间内所采集到的脉冲数作为电机的转速(更加精准,推荐)
编码器在实际的测数使用时确实是根据,电机转一圈:编码器转多少圈的方式来实际测量电机的转速的,但是在其本质就还是编码器的输出的脉冲数,所以直接计算编码器的单位时间的脉冲数推算电机的速度是一样的,数据来的更加直接、精准。
3、STM32定时器编码器模式理论分析
(1)定时器编码器模式选择


首先是定时器编码器模式的选择,其实就是选择在那一个通道计数,还是两个通道都要计数也就是这三种模式。
对于带方向的就只有一路脉冲,所以选择其中一路通道就ok了。
对于正交编码器而言有两路脉冲,所以就选择第三中方式,两路通道都计数。
(2)定时器编码器输入极性的选择
看懂这张图才是,确定输入极性的关键所在:所谓极性就是选择在输入脉冲信号的上升沿计数还是下降沿计数。

(3)定时器编码器输入极性的寄存器配置

CC1S=’01’ (TIMx_CCMR1寄存器,IC1FP1映射到TI1) 
CC2S=’01’ (TIMx_CCMR1寄存器,IC2FP2映射到TI2) 
CC1P=’0’ (TIMx_CCER寄存器,IC1FP1不反相,IC1FP1=TI1) 
CC2P=’0’ (TIMx_CCER寄存器,IC2FP2不反相,IC2FP2=TI2) 
SMS=’011’ (TIMx_SMCR寄存器,所有的输入均在上升沿和下降沿有效). 
CEN=’1’ (TIMx_CR1寄存器,计数器使能)
1
2
3
4
5
6
这里解释一下
TIx 就相当于输入信号的 TIM4->CH1 TIM4->CH2;
TIxF 滤波后信号;
TIxFPx经过带极性选择的边缘检测器过后的产生的信号;

4、结合手册函数刨析库函数
(1)STM32定时器编码器模式的库函数配置代码
/*TIM2初始化为编码器接口*/
void Encoder_Init_TIM2(void)
{
    //结构体变量的创建
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
    TIM_ICInitTypeDef TIM_ICInitStructure;  
    GPIO_InitTypeDef GPIO_InitStructure;
    //RCC时钟使能
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器4的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口时钟
    
     //编码器引脚的配置,对于定时器的通道管脚在用户手册上的==8.3.7定时器复用功能重映射==
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;    //端口选择
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                //根据设定参数初始化GPIOA
    
    //定时器的基本配置,这里主要介绍定时器的编码器模式,不做过多解释
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 
    TIM_TimeBaseStructure.TIM_Period = 0xffff; //设定计数器自动重装值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数  
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    //编码器模式选择与配置
    //参数一TIMx:定时器的选择
    //参数二TIM_EncoderMode:编码器模式的选择
    //参数三TIM_IC1Polarity:通道一的极性选择
    //参数四TIM_IC2Polarity:通道二的极性选择
//具体配置->正交编码器:配置如下
    TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
//带方向的编码器配置如下->区别只在于带方向的编码器只有一个脉冲输入,而正交编码器有两个脉冲输入
    TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

    TIM_ICStructInit(&TIM_ICInitStructure);
    TIM_ICInitStructure.TIM_ICFilter = 10;
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    //Reset counter
    TIM_SetCounter(TIM2,0);
    TIM_Cmd(TIM2, ENABLE); 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(2)刨析
转到void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)函数下可以看到如下代码:
/* Get the TIMx SMCR register value */
  tmpsmcr = TIMx->SMCR;
  
  /* Get the TIMx CCMR1 register value */
  tmpccmr1 = TIMx->CCMR1;
  
  /* Get the TIMx CCER register value */
  tmpccer = TIMx->CCER;
1
2
3
4
5
6
7
8
再看下面来自用户手册中的截图,就不用我再继续挖下去了。

5、编码器速度的读取
前面已经说过了编码器的脉冲计数对应电机速度的数据处理方法,这里就继续说明了。
速度是单位时间为前提的,我这里采用的是直接计算单位时间对应的脉冲数来推算电机的速度的。这里的单位时间也就是采样率的意思,就是我们间隔多少时间去采集然后清零脉冲计数值一次。这里的采样率不能太高,也不能太低。对电机的控制,一般采样率=5毫秒越小就越接近瞬时速度,为什么不能过小想必不用说大家也知道。所以这里就需要一个定时器来计算采样周期
————————————————
版权声明:本文为优快云博主「君墨蘭」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_45276147/article/details/126309377

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值