原创 数字旋转编码开关的原理及使用方法

2011-2-12 09:15 5739 17 26 分类: 消费电子

在电子产品设计中,经常会用到旋转编码开关,比如数码电位器等,它的英文名翻译过来就是Rotary Encoder Switch。在写这个元件的驱动程序之前,我google、baidu了一些它的使用说明资料,知道了它具有左转、右转和按下三个功能,有五个脚,它的外形如下图所示:

1.jpg2.jpg

 

3.jpg


(1)1、3脚要外接上拉电阻,一般10K就足矣;

(2)2脚一般接地就行;

(3)4、5脚是下按键的开关接线(按下时,4脚为低电平);


我调试这个元件时的实物接线示意图为:

4.jpg



其实它使用起来并不难,我看到网上的资料大都说操作它时判断正转和反转是一个难点,在这里我希望博友在看了我的代码后会觉得这其实只是一个“传说”!我的代码会把这个问题说的清清楚楚、简简单单的!我觉得其实判断正转和反转的关键就是:当BMA为低电平时,BMB的跳变沿是怎样的——上升沿表示正转,下降沿表示反转。只要用代码把这个描述清楚就OK了,这个器件就基本可以顺利地操作了。

没有多余的再说了,直接附上代码:

 

#include

 

#define uchar unsigned char

#define uint  unsigned int

 

sbit BMA=P1^4;

sbit BMB=P1^5;

sbit BMC=P1^6;

sbit P27=P2^7;

sbit P26=P2^6;

sbit P25=P2^5;

 

uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

uchar count=0;

uchar flag;

uchar Last_BMB_status;

uchar Current_BMB_status;

//************************************************

void delay(uchar z)    //大约1ms的延时

{

    uchar x,y;

    for(x=z;x>0;x--)

     for(y=110;y>0;y--);

}

//************************************************

void display() //显示子程序

{

    P0=table[count%10];    //个位

    P27=0;

    delay(10);

    P27=1;

 

    P0=table[count%100/10];    //十位

    P26=0;

    delay(10);

    P26=1;

 

    P0=table[count/100];    //百位

    P25=0;

    delay(10);

    P25=1;

}

//************************************************

void main()

{

    TMOD="0x01";    //定时器0,工作方式1

    TH0=0xD8;

    TL0=0xF0;     //给定时器装上初值,10ms中断一次

    ET0=1;    //打开定时器中断

    EA =1;    //打开总中断

    TR0=1;    //启动定时器0

 

    while(1)

    {

        Last_BMB_status=BMB;

        while(!BMA)    //BMA为低电平时

        {

            Current_BMB_status=BMB;

            flag="1";    //标志位置为1说明编码开关被旋转了

        }

        if(flag==1)

        {

            flag="0";    //时刻要注意这一点!给标志位清零

            if((Last_BMB_status==0)&&(Current_BMB_status==1)) //BMB上升沿表示正转

            {

                count++;

                if(count==255)

                {

                    count="0";

                }

            }

            if((Last_BMB_status==1)&&(Current_BMB_status==0)) //BMB下降沿表示反转

            {

                count--;

                if(count==0)

                {

                    count="255";

                }

            }

        }

    }

}

//************************************************

void timer0() interrupt 1    //定时器0的中断服务程序

{

    TH0=0xD8;

    TL0=0xF0;    //再次装入初值

    display();   //每隔10ms显示一次

    if(!BMC)     //按下旋转编码开关则计数清零

    {

        count="0";

    }

}

PARTNER CONTENT

文章评论9条评论)

登录后参与讨论

用户1409213 2011-8-15 09:23

好资料,谢谢主分享.

用户1103829 2011-2-17 22:56

好东西,以前有一些困扰,谢谢博主!!

用户1521612 2011-2-17 12:25

讲的蛮清晰的!谢谢!

用户1592446 2011-2-16 18:27

好文章,要好好学习。

用户1339513 2011-2-16 09:19

谢谢博主,能把自己的经验分享给别人

用户1413800 2011-2-15 21:52

以前有一些困扰,看了高人的经验,好像开阔了

财智聚 2011-2-15 19:13

谢谢分享

用户1575892 2011-2-15 15:53

好东西 学习学习

用户1277994 2011-2-12 10:38

博主辛苦了,新年第一篇文章就那么长!
相关推荐阅读
用户1528479 2011-04-12 21:50
设计第一个六层板所得到的一个深刻体会
        今天中午,由于确实有点困,于是乎仰躺在座椅上眯了半个小时的眼,睡眼朦胧中,好消息随即到来——我的第一个六层板从深圳寄到长沙了!而且元器件都已经由深圳那边的人焊接好了,拆开包装袋一看,简...
用户1528479 2011-03-25 15:28
DDR2 SDRAM×32布局、布线经验谈
最近忙于一块以CycloneIII为核心主控芯片的六层板设计,开发环境是Capture+Allegro+CAM350,从原理图修改到PCB的布局、布线这整个过程中我遇到了相当多的问题,值得庆幸的是...
用户1528479 2011-03-25 13:30
DDR2 SDRAM×32布局、布线经验谈
DDR2 SDRAM×32布局、布线经验谈最近忙于一块以CycloneIII为核心主控芯片的六层板设计,开发环境是Capture+Allegro+CAM350,从原理图修改到PCB的布局、布线这整个过...
用户1528479 2011-02-27 19:48
使用Cadence16.2过程中遇到的一些问题(附解惑方法)
使用Cadence16.2过程中遇到的一些问题(附解惑方法) 很久没有写博文了!确实有点过意不去。最近两个多月以来,由于公司的需要,我不得不学习Cadence16.2的使用方法——用它来画高速板子...
用户1528479 2011-02-27 19:46
使用Cadence16.2过程中遇到的一些问题(附解惑方法)
使用Cadence16.2过程中遇到的一些问题(附解惑方法)很久没有写博文了!确实有点过意不去(呵呵,这意味着自己最近懈怠了)。最近两个多月以来,由于公司的需要,我不得不学习Cadence16.2的使...
EE直播间
更多
我要评论
9
17
关闭 站长推荐上一条 /3 下一条