OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1074|回复: 13

stm32通过输入捕获捕捉霍尔编码器脉冲数的问题

[复制链接]

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
发表于 2024-2-22 01:07:38 | 显示全部楼层 |阅读模式
15金钱
正常电机转一圈会产生330脉冲,我使用stm32的输入捕获捕捉霍尔编码器的AB相脉冲,四倍频,手动扭电机一圈得到1320是正确的。但是我通过单片机控制电机,在捕捉得到的脉冲数远远大于,电机旋转一圈得到2万多脉冲,这是为什么,怎么解决

最佳答案

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8205
金钱
8205
注册时间
2020-5-11
在线时间
3700 小时
发表于 2024-2-22 01:07:39 | 显示全部楼层
专治疑难杂症
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 11:49:05 | 显示全部楼层
主要是没有示波器,在家里还没去学校
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 11:55:14 | 显示全部楼层
我发现了问题,当不接电机的时候,输入捕获捕捉到的值会自增,下面是我的代码
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 11:56:09 | 显示全部楼层
TIM_ICInitTypeDef  TIM2_ICInitStructure;

void TIM2_Cap_Init(u16 arr,u16 psc)
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
           NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //使能TIM5时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_0);       

        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_1);
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_2);
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOA,GPIO_Pin_3);
       
       
        //初始化定时器5 TIM5         
        TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler =psc;         //预分频器   
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  
        //初始化TIM5输入捕获参数
                TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01         选择输入端 IC1映射到TI1上
          TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
          TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
          TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
          TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
          TIM_ICInit(TIM2, &TIM2_ICInitStructure);
               
                TIM2_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01         选择输入端 IC1映射到TI1上
          TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
          TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
          TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
          TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
          TIM_ICInit(TIM2, &TIM2_ICInitStructure);
               
                TIM2_ICInitStructure.TIM_Channel = TIM_Channel_3; //CC1S=01         选择输入端 IC1映射到TI1上
          TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
          TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
          TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
          TIM2_ICInitStructure.TIM_ICFilter = 0;//IC1F=0000 配置输入滤波器 不滤波
          TIM_ICInit(TIM2, &TIM2_ICInitStructure);
               
                TIM2_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=01         选择输入端 IC1映射到TI1上
          TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
          TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
          TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
          TIM2_ICInitStructure.TIM_ICFilter = 0;//IC1F=0000 配置输入滤波器 不滤波
          TIM_ICInit(TIM2, &TIM2_ICInitStructure);
       
        //中断分组初始化
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级0级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
       
        TIM_ITConfig(TIM2,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4,ENABLE);//允许更新中断 ,允许CC1IE捕获中断       
       
           TIM_Cmd(TIM2,ENABLE );         //使能定时器5
}


// 定时器2中断服务程序  
void TIM2_IRQHandler(void)  
{  
    if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) // 捕获1发生捕获事件  
    {  
        electrical_machinery_encoder2++;  
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) // 如果当前是高电平,那么下降沿, 反之设置上升沿  
        {  
            TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Falling); // CC1P=1 设置为下降沿捕获  
        }  
        else  
        {  
            TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Rising); // CC1P=0 设置为上升沿捕获  
        }  
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);  
    }  
  
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) // 捕获2发生捕获事件  
    {  
        electrical_machinery_encoder2++;  
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)) // 如果当前是高电平,那么下降沿, 反之设置上升沿  
        {  
            TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling); // CC2P=1 设置为下降沿捕获  
        }  
        else  
        {  
            TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising); // CC2P=0 设置为上升沿捕获  
        }  
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);  
    }  
  
    if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET) // 捕获3发生捕获事件  
    {  
        electrical_machinery_encoder1++;  
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)) // 如果当前是高电平,那么下降沿, 反之设置上升沿  
        {  
            TIM_OC3PolarityConfig(TIM2, TIM_ICPolarity_Falling); // CC3P=1 设置为下降沿捕获  
        }  
        else  
        {  
            TIM_OC3PolarityConfig(TIM2, TIM_ICPolarity_Rising); // CC3P=0 设置为上升沿捕获  
        }  
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);  
    }  
  
    if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET) // 捕获4发生捕获事件  
    {  
        electrical_machinery_encoder1++;  
        if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)) // 如果当前是高电平,那么下降沿, 反之设置上升沿  
        {  
            TIM_OC4PolarityConfig(TIM2, TIM_ICPolarity_Falling); // CC4P=1 设置为下降沿捕获  
        }  
        else  
        {  
            TIM_OC4PolarityConfig(TIM2, TIM_ICPolarity_Rising); // CC4P=0 设置为上升沿捕获  
        }  
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);  
    }  
}

回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 12:42:40 | 显示全部楼层
现在又不会自增了,搞迷茫了
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 12:51:32 | 显示全部楼层
本帖最后由 yk1084574506 于 2024-2-22 12:59 编辑

有没有大佬帮忙一下
回复

使用道具 举报

10

主题

116

帖子

0

精华

高级会员

Rank: 4

积分
842
金钱
842
注册时间
2021-12-23
在线时间
202 小时
发表于 2024-2-22 13:49:12 | 显示全部楼层
有没有可能是电机的电磁干扰导致的,多试试,看看啥情况下会自增
回复

使用道具 举报

17

主题

161

帖子

0

精华

高级会员

Rank: 4

积分
955
金钱
955
注册时间
2022-7-21
在线时间
446 小时
发表于 2024-2-22 14:34:56 | 显示全部楼层
没遇到过,如果有别的板子尝试下用别的板子写一个脉冲输出的用现在的这个板子的电机编码器程序捕获下看看
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 14:54:41 | 显示全部楼层
突然发现一个现象,通过单片机控制电机四个捕获通道有一个是正确的,其他三个异常过多,直接手扭四个都正确
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 15:50:25 | 显示全部楼层
还在忙 发表于 2024-2-22 14:34
没遇到过,如果有别的板子尝试下用别的板子写一个脉冲输出的用现在的这个板子的电机编码器程序捕获下看看

可以捕获,数目也是对的
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 15:51:00 | 显示全部楼层
就是驱动电机旋转,编码器没有转很多,却捕获很多
回复

使用道具 举报

5

主题

22

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2022-2-3
在线时间
18 小时
 楼主| 发表于 2024-2-22 20:50:49 | 显示全部楼层

确实是有杂波,通过滤波后解决问题
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8205
金钱
8205
注册时间
2020-5-11
在线时间
3700 小时
发表于 2024-2-23 09:11:40 | 显示全部楼层
yk1084574506 发表于 2024-2-22 20:50
确实是有杂波,通过滤波后解决问题

嗯,看来示波器还是很有用的,有必要准备一个。
如果条件有限,正点原子的DS100不错,有些开源的示波器是用STM32单片机自带的ADC做的,可以考虑一下。
专治疑难杂症
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 10:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表