OpenEdv-开源电子网

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

旋转编码器程序--问题

[复制链接]

30

主题

73

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-6-5
在线时间
85 小时
发表于 2017-12-14 21:54:07 | 显示全部楼层 |阅读模式
20金钱
利用中断实现编码器方向判断  上升沿中断进入中断 消抖 判断另一个管脚的电平判断转向 现象就是编码器转的快得时候方向会乱一下  不知道有没有什么好的思路只用中断的方法 让编码器稳定些   

最佳答案

查看完整内容[请看2#楼]

[mw_shl_code=c,true]#include "sys.h" #define switch_a PBin(0) //编码开关b脚 #define switch_b PBin(1) //编码开关a脚 #define switch_c PBin(12) //编码开关按键 void SWITCH_Init(void); //编码开关初始化函数 [/mw_shl_code] [mw_shl_code=c,true]#include "delay.h" #include "switch_code.h" volatile uint8_t sw_val=0;//表示编码器顺时针或逆时针动作 volatile uint8_t sw_sta=0;//表示当前编码器 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
586
金钱
586
注册时间
2016-5-13
在线时间
106 小时
发表于 2017-12-14 21:54:08 | 显示全部楼层
[mw_shl_code=c,true]#include "sys.h"

#define        switch_a        PBin(0)                //编码开关b脚
#define        switch_b         PBin(1)                //编码开关a脚
#define switch_c        PBin(12)        //编码开关按键

void SWITCH_Init(void);        //编码开关初始化函数
[/mw_shl_code]

[mw_shl_code=c,true]#include "delay.h"
#include "switch_code.h"

volatile uint8_t sw_val=0;//表示编码器顺时针或逆时针动作
volatile uint8_t sw_sta=0;//表示当前编码器所处状态

void SWITCH_Init(void)
{
        GPIO_InitTypeDef                GPIO_InitStructure;
        EXTI_InitTypeDef                EXTI_InitStructure;
        NVIC_InitTypeDef                NVIC_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);        //使能PB端口时钟

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                                                                //上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                                //IO口速度为50MHz
        GPIO_Init(GPIOB, &GPIO_InitStructure);                                                                                                        //根据设定参数初始化GPIOB

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟

        //GPIOB.0 中断线以及中断初始化配置
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);

        EXTI_InitStructure.EXTI_Line = EXTI_Line0;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升沿触发
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);                 //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

        NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                                        //使能按键所在的外部中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;        //抢占优先级2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                                //子优先级1
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                //使能外部中断通道
        NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
       
        if(switch_a==0)sw_sta=0;
        else sw_sta=1;
}

void EXTI0_IRQHandler(void)
{
        EXTI_ClearITPendingBit(EXTI_Line0);  //清除EXTI0线路挂起位
        if(sw_sta==0)
        {
                delay_ms(1);
                if((switch_b==1)&&(switch_a==1))//顺时针旋转一次
                {
                        sw_val=1;
                        sw_sta=1;
                }
                if((switch_b==0)&&(switch_a==1))//逆时针旋转一次
                {
                        sw_val=2;
                        sw_sta=1;
                }
        }
        else if(sw_sta==1)
        {
                delay_ms(1);
                if((switch_b==0)&&(switch_a==0))//顺时针旋转一次
                {
                        sw_val=1;
                        sw_sta=0;
                }
                if((switch_b==1)&&(switch_a==0))//逆时针旋转一次
                {
                        sw_val=2;
                        sw_sta=0;
                }
        }
}
[/mw_shl_code]

使用的是一周30分位15脉冲的编码开关,一秒4,5圈的速度拧没有发现丢步或者错误
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2017-12-14 23:21:11 | 显示全部楼层
不要用中断,用查询方式
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-12-15 05:43:24 | 显示全部楼层
STM32有专门的模块来处理这个事情.这里有个名词.叫正交编码.STM32的定时器有这个输入的功能. 有个正交编码输入接口.请查看一下资料.可以解决楼主的问题.
回复

使用道具 举报

30

主题

73

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-6-5
在线时间
85 小时
 楼主| 发表于 2017-12-17 14:51:25 | 显示全部楼层
Acuity 发表于 2017-12-14 23:21
不要用中断,用查询方式

谢谢您 只能用中断实现
回复

使用道具 举报

30

主题

73

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-6-5
在线时间
85 小时
 楼主| 发表于 2017-12-17 14:52:00 | 显示全部楼层
操作系统 发表于 2017-12-15 05:43
STM32有专门的模块来处理这个事情.这里有个名词.叫正交编码.STM32的定时器有这个输入的功能. 有个正交编码 ...

现在只能用一个或者两个中断实现
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-12-18 08:17:49 | 显示全部楼层
用中断也是可以的.好像我以前也是用中断实现过的.
回复

使用道具 举报

29

主题

486

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3083
金钱
3083
注册时间
2014-7-19
在线时间
413 小时
发表于 2017-12-20 09:40:00 | 显示全部楼层
电子人生!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-23 18:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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