找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3725|回复: 14
打印 上一主题 下一主题
收起左侧

EC11增量型脉冲数字电位器单片机驱动程序

  [复制链接]
跳转到指定楼层
楼主
论坛里的代码都是用定时扫描端口的,没有一例采用外中断或端口变化中断的。这种方法占用mcu时间极少,适用面广(0~MHz级),代码简短,极其可靠。

单片机源程序如下:
  1. /*
  2. 所有微芯系mcu(例如PIC、九齐、义隆等)都有引脚变化中断。
  3. 十速51mcu的P1有引脚变化中断。
  4. PIN_A P10  开启引脚变化中断,可接P1任意端口P1x。
  5. PIN_B P11  不开启引脚变化中断,可接任意端口Pxx。
  6. */
  7. //只开启一个引脚(PIN_A)变化中断
  8. volatile u8 gPosition; // EC11 8位足够。如需定位应用,16位32位都有可能。
  9. u8 gPositionOld;
  10. void p1_change_int(void) interrupt 8
  11. { //加消抖电容,减少mcu开销
  12.         bit bZZ = 0;//使用该临时变量是为了加快端口读取过程
  13.         if (PIN_A)
  14.         {//上跳
  15.                 if (!PIN_B)
  16.                         bZZ = 1;
  17.         }
  18.         else
  19.         {//下跳
  20.                 if (PIN_B)
  21.                         bZZ = 1;
  22.         }
  23.         if (bZZ)
  24.                 gPosition++; //正传
  25.         else
  26.                 gPosition--; //反转
  27.         INTFLG = 0;                 //清除变化中断
  28. }

  29. void EC11_init(void)
  30. {
  31.         //开启P10引脚变化中断
  32.         gPositionOld=gPosition;
  33. }

  34. void EC11_Scan(void)
  35. {//定时执行,选择合适定时使任何时候(step<2)
  36.         u8 step=gPosition-gPositionOld;
  37.         if(0==step) return;
  38.         gPositionOld=gPosition;
  39.         if(step&0x80){
  40.                 step=0-step;
  41.                 //反转处理 step为步数
  42.         }
  43.         else{
  44.                 //正传处理 step为步数
  45.         }
  46. }
复制代码



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏15 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:390416 发表于 2022-6-15 11:35 | 只看该作者
//**********************************---祁绪电子---2020年5月 *************
// 按键或者旋转编码器 底层驱动 加减函数
//*********************************************************************
void ROTARY_ROTARY_Scan_Drive(void)
{
        static xdata u8 count=0,Rotary_Flag=0;
        if(count>30)
        {
                count=0;
                if((ROTARY_B==0)&&(Rotary_Flag==0))                        //如果按键B按下,且flag是0       
                {
                        Rotary_Flag=1;
                        Rotary_Read_Data_Rotary++;                                //按键值增加1
                        if(Rotary_Read_Data_Rotary>Key_MAX)                //如果大于最大值 跳回0
                        {
                                Rotary_Read_Data_Rotary=Key_MIN;
                        }
                }
                if((ROTARY_A==0)&&(Rotary_Flag==0))                        //如果按键A按下,且flag是0       
                {
                        Rotary_Flag=1;
                        Rotary_Read_Data_Rotary--;                                //按键值减少1
                        if(Rotary_Read_Data_Rotary<Key_MIN)                //如果按键值等于0,跳回最大值
                        {
                                Rotary_Read_Data_Rotary=Key_MAX;
                        }
                }
                if((ROTARY_B!=0)&&(ROTARY_A!=0))                        //按键必须释放,下次按键才有效
                {
                        Rotary_Flag=0;
                }
        }
        count++;
}

EC11很简单 主函数不断的扫描这个函数 就行了  ,两个按键和EC11通用这段代码
回复

使用道具 举报

板凳
ID:401564 发表于 2022-6-15 16:12 | 只看该作者
为什么要节省MCU占用时间?是真的一个EC11让整个程序停滞不前了吗?有必要去省下那点时间吗?
更多的时候,加一个电容才是不可取的.明明可以不要这个电容的,你却要加电容?
自己DIY点小玩意玩玩也就无所谓了,批量的产品,一个一分钱的电容都是一个敏感的成本,而这个成本的增加只是不想让单片机太累而已
回复

使用道具 举报

地板
ID:887371 发表于 2022-6-16 09:29 | 只看该作者
Y_G_G 发表于 2022-6-15 16:12
为什么要节省MCU占用时间?是真的一个EC11让整个程序停滞不前了吗?有必要去省下那点时间吗?
更多的时候,加 ...

EC11这种超慢速设备,可靠性不做要求的设备,好像随便写都能达到要求。
但节省MCU占用时间,总比浪费要好吧(可让改代码用于极低主频的mcu)。
并且这个节省还附带了提高可靠性、代码简单,方便易用等好处。

我这代码天然自带消抖,这个电容不是必须,但有了这电容,mcu主频可工作于10kHz。
回复

使用道具 举报

5#
ID:887371 发表于 2022-6-16 09:47 | 只看该作者
本帖最后由 datouyuan 于 2022-6-16 09:52 编辑
Y_G_G 发表于 2022-6-15 16:12
为什么要节省MCU占用时间?是真的一个EC11让整个程序停滞不前了吗?有必要去省下那点时间吗?
更多的时候,加 ...

假如这个EC11速度快了1000倍,并且还不允许丢步,扫描法还能不能用?
而用中断法的方式,代码不做修改还能用。

回复

使用道具 举报

6#
ID:401564 发表于 2022-6-16 20:04 | 只看该作者
datouyuan 发表于 2022-6-16 09:29
EC11这种超慢速设备,可靠性不做要求的设备,好像随便写都能达到要求。
但节省MCU占用时间,总比浪费要 ...

关键节省MCU时间来干嘛呢?总觉得提高MCU效率是件好事,可关键是这用得着吗?如果不是极端条件下,这种"优化"一点意义都没有,自己知道怎么优化就行,并不需要每次都要优化的
而且,用外部中断的办法并不是适用所有情况,因为大多的单片机,外部中断有最高等级的中断,它会打断其它所有的中断,不知道你看过EC11的波形没有,它转动一次,新的EC11抖动有五六下,电平就固定了,如果是用了很久的时间,它抖动有上百次的,以你的代码,会直接打断其它程序上百次,你试想一下,比如有波特率高点的串口,你能保证数据手准确性?又或者是再去更改一下中断优先等级?
回复

使用道具 举报

7#
ID:446113 发表于 2022-6-17 08:04 | 只看该作者
学习学习学习,每天进步一点点
回复

使用道具 举报

8#
ID:887371 发表于 2022-6-17 11:55 | 只看该作者
Y_G_G 发表于 2022-6-16 20:04
关键节省MCU时间来干嘛呢?总觉得提高MCU效率是件好事,可关键是这用得着吗?如果不是极端条件下,这种"优化" ...

你有几条最基本的错误:
1.提高MCU效率,节约mcu的占用时间当然是好事。
2.中断就是要打断程序,甚至频繁打断。假如中断会对其它功能造成影响,最主要的解决办法是减少相关代码的占用时间,例如提高卖出主频、提高代码效率。
3.外部中断虽是最高等级(非嵌入式优先级)的中断,但它只会打断嵌入式优先级比它低的中断。


在你说的极其恶劣环境下,甚至还差,我这代码能保证波特率高点的串口数据准确性,并且还保证了ec11的可靠性。这可靠性就是靠减少mcu占用时间保证的。
回复

使用道具 举报

9#
ID:887371 发表于 2022-6-17 15:00 | 只看该作者
本帖最后由 datouyuan 于 2022-6-17 15:08 编辑
3.外部中断虽是最高等级(非嵌入式优先级)的中断,但它只会打断嵌入式优先级比它低的中断。

你对很多基本知识有错误理解,我表达能力又不好,所以多啰嗦几句。
1.远古51嵌入式优先级有2级,现在很多51嵌入式优先级有4级。
2.相同嵌入优先级的中断同时发生时,mcu会先处理普通优先级高的中断,但不会打断正在处理的中断。提高代码效率,减少mcu占用时间,能处理更多的中断。
3.你所说的“外部中断有最高等级的中断,它会打断其它所有的中断”不会发生,因为你不特意调整嵌入式优先级的话,外部中断的嵌入优先级是最低的。
4.使用中断解决问题是单片机初学者必须掌握的技能,该整理下你的知识体系了。
5.一直围绕着基础讨论,却忽略了我这简单代码的精妙之处,希望你能仔细体会。
回复

使用道具 举报

10#
ID:171036 发表于 2023-9-12 18:42 | 只看该作者
人人学会单片机 发表于 2022-6-15 11:35
//**********************************---祁绪电子---2020年5月 *************
// 按键或者旋转编码器 底 ...

count这个变量咋么计数  定时器计数  还是旋转编码开关旋动就抖动计数
回复

使用道具 举报

11#
ID:406132 发表于 2023-10-27 15:40 | 只看该作者
虽然不会软件,但能不用增加产品成本,就不要增加产品成本,毕竟消费电子对成本比较敏感,老板来了句,为什么别人的可以做这么便宜?你的又要这个电容那个电容的……你不吐血?能解决项目工程的问题就好。
回复

使用道具 举报

12#
ID:514317 发表于 2023-10-28 10:10 | 只看该作者
yanggo 发表于 2023-10-27 15:40
虽然不会软件,但能不用增加产品成本,就不要增加产品成本,毕竟消费电子对成本比较敏感,老板来了句,为什 ...

你这个说法不敢苟同   如果节省一两个贴片电容就可以节省成本的话我无话可说    节省的途径是以高可靠设计电路来节省使用元器件    试问你的功能都不稳定节省这两个电容有什么意义??   使用者使用时数字乱窜是什么使用体验??   还有设计的原则是程序尽可能优化   宁愿让MCU空转也不能让他堵塞运行
回复

使用道具 举报

13#
ID:996773 发表于 2023-10-30 10:47 | 只看该作者


这种数字电位器我也用了几年了,从来不用防抖和电容,也不用中断,中断用在逐个点亮数码管

我觉得保障显示正常很重要,这电位器两脚从00变化到01的时间对于主程序来说太漫长了,

把中断用在编码器也太浪费,我的程序大多数时间都是闲置状态和软件读取数字电位器两脚状态
回复

使用道具 举报

14#
ID:774081 发表于 2024-1-5 13:07 | 只看该作者
赞同楼主的理念!有的人的思维逻辑和你奇怪,如果你说人用两条腿走路比较好,他都会提出残疾人没有两条腿怎么走这样类似的反驳理由。中断不够用你就用轮训呗!中断多余的话,用中断不是挺好的吗?至于用不用电容,你买产品的时候一定希望产品里用电容吧,怎么你是制造者了就不想用电容了?匠心何在?
回复

使用道具 举报

15#
ID:774081 发表于 2024-1-8 11:03 | 只看该作者
今天实测楼主的中断方式检测EC11的转动,不好用!主要是判断结果里正传中夹杂反转、反转中夹杂正转!一开始分析程序,发现对于一个U8变量step,你来一句“step=0-step;”就令人费解。以下是我的代码,同样采取中断,结果非常准确稳定,能完整输出当前转动方向和累计计数值(正转增大数值,反转减小数值),通过方向和计数就可用于特定的功能设计了。代码对EC11的A脚进行中断响应(下降沿检测),响应函数为:
void EC11_Change_Interupt(){
  static bool prev_A = 0;//必须为static!或者定义为一般的全局变量
  volatile bool curr_A = digitalRead(EC11_A);
  volatile bool curr_B = digitalRead(EC11_B);
  if((prev_A == 0) && (curr_A == 1)){
    if(curr_B == 0){
      count = count - 1;
      direction = 0;
    }
    else{
      count = count + 1;
      direction = 1;
    }
  }
  else if((prev_A == 1) && (curr_A == 0)){
    if(curr_B == 0){
      count = count + 1;
      direction = 1;
    }
    else{
      count = count - 1;
      direction = 0;
    }
  }
  prev_A = curr_A;
  if(direction){
    Serial1.println((String("正转:") + String(count)));
  }
  else{
    Serial1.println((String("反转:") + String(count)));
  }
}

对于SW脚,也可以通过下降沿中断,使count归零。以上代码由图形化软件转化而来,可能比较累赘,可以适当去掉一些强制转换和括号。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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