极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 27152|回复: 6

arduino宏的应用实例7--读编码器模块

[复制链接]
发表于 2016-6-6 01:32:09 | 显示全部楼层 |阅读模式
本帖最后由 wwwymq 于 2016-6-6 11:56 编辑

用于读取旋转编码器模块


[pre lang="arduino" line="1" file="encoder4.ino"]//非阻塞编码器模块读取,通过编码器按键使能编码器事件,当编码器使能时分别增减计数值。
//未用到中断,通过轮询读取编码器,周期5ms,编码器旋钮模块用,更高线数的编码器需要中断读。
#include "key.h"     //按键检测宏
#include "edge.h"    //边沿检测宏
#include "encoder.h" //编码器检测宏
#define pinA 2       //编码器A相
#define pinB 3       //编码器B相
#define pinK 4       //编码器按键
int count = 0;       //编码器计数值
bool en = true;      //编码器使能标志

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(pinK, INPUT_PULLUP);  //编码器按键设为内部上拉
  Serial.println("Ready");
}

void loop() {
  // put your main code here, to run repeatedly:
  /*readKey(enable,cycleTime,x,no,onTrigger,onPop)   (使能,扫描周期,端口,信号是否反向,上升沿执行动作,下降沿执行动作)
    按键使能,20ms扫描一次,4号端口,不反向,每次按下时把编码器使能标志反向,弹起时不动作*/
  readKey(true, 20, pinK, false, if (en ^= true) {
  Serial.println("Encoder enable");
  } else {
    Serial.println("Encoder unable");
  }, void());
  /*readEncoder(enable,cycleTime,pinA,pinB,incEvent,dincEvent   (使能,扫描周期,A相端口,B相端口,计数增执行动作,计数减沿执行动作)
    编码器根据使能信号en启动,5ms扫描一次,2、3端口,分别增减计数值*/
  readEncoder(en, 5, pinA, pinB, Serial.println(++count), Serial.println(--count));
}[/code]

[pre lang="arduino" line="1" file="edge.h"]#ifndef __EDGE_H__
#define __EDGE_H__
//逻辑量的四种状态:低,上升,高,低
enum edgeSta {low, trg, high, pop};
//宏名:edge。 返回值:逻辑量状态。输入参数:bool值 用途:检测逻辑量的边沿。
#define edge(ReadData) ({\
    static bool Trg = false;\
    static bool Cont = false;\
    static bool Pop = false;\
    Trg = ReadData & (ReadData ^ Cont); \
    Pop = Cont != ReadData & !Trg; \
    Cont = ReadData; \
    enum edgeSta sta = low;\
    if (Cont) {\
      sta = high;\
    } else {\
      sta = low;\
    }\
    if (Trg) {\
      sta = trg;\
    }\
    if (Pop) {\
      sta = pop;\
    }\
    sta;\
  })
#endif[/code]

[pre lang="arduino" line="1" file="encoder.h"]#ifndef __ENCODER_H__
#define __ENCODER_H__
#include "edge.h"
#include "key.h"

//readEncoder(enable,cycleTime,pinA,pinB,incEvent,dincEvent   (使能,扫描周期,A相端口,B相端口,计数增执行动作,计数减沿执行动作)
#define readEncoder(enable,cycleTime,pinA,pinB,incEvent,dincEvent)({\
    static bool no=false;\
    if(edge(enable)==trg){\
      pinMode(pinA, INPUT);\
      pinMode(pinB, INPUT);\
      no = !digitalRead(pinA);\
    }\
    readKey(enable,cycleTime,pinA, no, if (digitalRead(pinB)^no) {incEvent;} else {dincEvent;}, if (digitalRead(pinB)^no) {dincEvent;} else {incEvent;});\
  })

#endif[/code]

[pre lang="arduino" line="1" file="key.h"]#ifndef __KEY_H__
#define __KEY_H__
#include "edge.h"

//readKey(enable,cycleTime,x,no,onTrigger,onPop)   (使能,扫描周期,端口,信号是否反向,上升沿执行动作,下降沿执行动作)
#define readKey(enable,cycleTime,x,no,onTrigger,onPop) do{\
    static bool Trg = false;\
    static bool Cont = false;\
    static bool Pop = false;\
    static unsigned long timdel = millis();\
    switch(edge(enable)){\
      case trg:\
        Trg = false;\
        Cont = false;\
        Pop = false;\
        timdel = millis();\
        break;\
      case high:\
        if (millis() - timdel >= cycleTime) {\
          bool ReadData = !digitalRead(x)^no;\
          Trg = ReadData & (ReadData ^ Cont); \
          Pop = Cont != ReadData & !Trg; \
          Cont = ReadData; \
          if (Trg) {\
            onTrigger;\
          }\
          if (Pop) {\
            onPop; \
          }\
          timdel = millis(); \
        }\
        break;\
      default:\
        break;\
    }\
  } while (0)
#define keyReadInit(x) do{\
    pinMode(x, INPUT_PULLUP);\
  } while (0)
#endif[/code]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2016-6-6 16:17:04 来自手机 | 显示全部楼层
超大玉挽尊术。
回复 支持 反对

使用道具 举报

发表于 2016-6-7 07:57:53 | 显示全部楼层
字写得好。
回复 支持 反对

使用道具 举报

发表于 2016-6-7 14:39:50 | 显示全部楼层
有时间试试,我前一阵子,用stm32折腾了好久,用的外部中断,总是出错,干扰很严重。
不过stm32官方提供了编码器的专用接口,会好用点
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-7 16:22:21 | 显示全部楼层
本帖最后由 wwwymq 于 2016-6-7 16:23 编辑
Hackerpro 发表于 2016-6-7 14:39
有时间试试,我前一阵子,用stm32折腾了好久,用的外部中断,总是出错,干扰很严重。
不过stm32官方提供了 ...


这个用起来也差强人意,手头有个最快300k的编码器,stm32f030硬件编码器接口采样,稍快一点就丢脉冲,实在是不敢用,stm32并不是高级的数采芯片,硬件的编码器接口也只能对付些低速的编码器。
真有需要还是数据采集卡靠谱。
回复 支持 反对

使用道具 举报

发表于 2016-6-8 11:50:50 | 显示全部楼层
wwwymq 发表于 2016-6-7 16:22
这个用起来也差强人意,手头有个最快300k的编码器,stm32f030硬件编码器接口采样,稍快一点就丢脉冲,实 ...

嗯,只是控制个菜单还可以,要求不太高
回复 支持 反对

使用道具 举报

发表于 2019-4-5 21:09:48 | 显示全部楼层
今天网上翻了半天,只有楼主的程序是可用的
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 14:27 , Processed in 0.042895 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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