技术文档

单片机 拨码开关 8421编码开关如何使用,请看这里

小编 2024-10-16 技术文档 23 0

8421编码开关如何使用,请看这里

8421编码开关

8421编码开关种类繁多,按操作方式分有指拔式、旋转式;按制式分有二进制、十进制、十六进制等。每一位都有一个独立的BCD编码拨动盘,我们每选择的一个数字都由里面的印刷电路产生BCD编码,分别由下面的4个管脚输出。组合非常灵活,我们可以根据设计的需要,任意组合多个BCD编码拨动盘来组成多位的应用。

在单片机设计中,特别是工业应用的设计中,一些外部的数值设置我们经常会选择用到它。使用起来也比较方便。

一个8421编码拔动盘,如果是十进制的是数字0-9,如果是十六进制的数字是0-F。也就是说十进制有10个数字,十六进制有十六个数字。而8421编码正好可以编码16个数字,它的编码方式参考图1。

图1 8421编码方式

8421编码开关与单片机的硬件连接参考图2,这里以4位拔码盘为例。

图2 硬件连接方式

图2中的电阻为限流电阻,阻值选择300R。二极管,是为了防止各位编码盘数据位的相互窜扰,可以选择1N4001。

读取编码盘的工作原理

单片机上电复位时,W1-W4保持高电平。我们用它们来读取各数据位的状态,在工作期间不去变更它们的电平状态,它们的电平状态将由D0-D3来决定。

在读取数据时,首先把D0-D4全部拉到高电平。D0拉为低电平,延时一段时间再分别去读取W1-W4的状态就可以知道4位编码盘的D0是什么状态。W1-W4读到的是低电平,那么说明相应4位编码盘的D0被编码了。用相同的方式去操作D1-D3就可以把完整的数值读取出来。

下面用程序来说明这一操作过程

/***********************拔码开关应用程序*************************/

#include <STC15F2K60S2.H>

int t_1ms, t_50ms; //这里定义的是1ms和50ms定时器,详细说明在上一课中有详细介绍

unsigned int Read_Switch[2], Read_Switch_Dec[2]; //定义读取到编码开关的16进制和10进制值的存储数组

void Read_8421_Switch();

void main()

{

Read_8421_Switch();

}

void Read_8421_Switch() //指拔开关设置值读取

{

static float scantime = 0;

static bit reachtime = 0, savetime = 0, R_W = 0;

static char switch_bite = 1;

char turnchar = 0, turncnt = 1, i;

static int turnchartmp[1], Read_Switch[1];

int turnmul = 0;

if(!savetime)

{

scantime = t_1ms;

savetime = 1;

}

if((t_1ms - scantime) < 0) //防止定时寄存器溢出时出现负数的情况

scantime = t_1ms;

if(savetime && t_1ms - scantime > 5) //5ms等待延时

reachtime = 1;

if(!reachtime)

goto Read__out;

//这一段设置了一个5ms的状态保持时间,在时间到了之后才会去读取W1-W4的状态

switch(switch_bite) //选择去拉低D0-D3中的哪一个

{

case 1: //操作D0

if(R_W) //决定是去拉低D0的电平,还是去读取W1的状态

{

//读取D0状态并写入暂存寄存器

if(P33)

Read_Switch[0] &= 0xEFFF;

else

Read_Switch[0] |= 0x1000;

if(P35)

Read_Switch[0] &= 0xFEFF;

else

Read_Switch[0] |= 0x100;

if(P36)

Read_Switch[0] &= 0xFFEF;

else

Read_Switch[0] |= 0x10;

if(P37)

Read_Switch[0] &= 0xFFFE;

else

Read_Switch[0] |= 0x1;

P15 = 1; //读取完成时重新拉高D0,以备下一次的读取

}else{

P15 = 0; //拉低D0

}

break;

case 2: //操作D1

if(R_W) //决定是去拉低D1的电平,还是去读取W2的状态

{

//读取D1状态并写入暂存寄存器

if(P33)

Read_Switch[0] &= 0xDFFF;

else

Read_Switch[0] |= 0x2000;

if(P35)

Read_Switch[0] &= 0xFDFF;

else

Read_Switch[0] |= 0x200;

if(P36)

Read_Switch[0] &= 0xFFDF;

else

Read_Switch[0] |= 0x20;

if(P37)

Read_Switch[0] &= 0xFFFD;

else

Read_Switch[0] |= 0x2;

P16 = 1; //读取完成时重新拉高D1,以备下一次的读取

}else{

P16 = 0; //拉低D1

}

break;

case 3: //操作D2

if(R_W) //决定是去拉低D2的电平,还是去读取W3的状态

{

//读取D2状态并写入暂存寄存器

if(P33)

Read_Switch[0] &= 0xBFFF;

else

Read_Switch[0] |= 0x4000;

if(P35)

Read_Switch[0] &= 0xFBFF;

else

Read_Switch[0] |= 0x400;

if(P36)

Read_Switch[0] &= 0xFFBF;

else

Read_Switch[0] |= 0x40;

if(P37)

Read_Switch[0] &= 0xFFFB;

else

Read_Switch[0] |= 0x4;

P17 = 1; //读取完成时重新拉高D2,以备下一次的读取

}else{

P17 = 0; //拉低D2

}

break;

case 4: //操作D3

if(R_W) //决定是去拉低D3的电平,还是去读取W4的状态

{

//读取D3状态并写入暂存寄存器

if(P33)

Read_Switch[0] &= 0x7FFF;

else

Read_Switch[0] |= 0x8000;

if(P35)

Read_Switch[0] &= 0xF7FF;

else

Read_Switch[0] |= 0x800;

if(P36)

Read_Switch[0] &= 0xFF7F;

else

Read_Switch[0] |= 0x80;

if(P37)

Read_Switch[0] &= 0xFFF7;

else

Read_Switch[0] |= 0x8;

P32 = 1; //读取完成时重新拉高D3,以备下一次的读取

}else{

P32 = 0; //拉低D3

}

break;

}

savetime = 0; //5ms定时时间到后的操作完成,等待下一次5ms定时

reachtime = 0; //重置定时标志

R_W = ~R_W; //拉低D0-D3或读取W1-W4标志转换

if(!R_W)

switch_bite++; //D0-D3循环

if(switch_bite > 4) //D0-D3全部读取完成进行数据处理,把十六进制值转换为我们设置的十进制值

{

switch_bite = 1;

Read_Switch_Dec[0] = 0;

turnchartmp[0] = Read_Switch[0];

for(i = 0; i < 4; i++)

{

switch(i)

{

case 0:

turnmul = 1;

break;

case 1:

turnmul = 10;

break;

case 2:

turnmul = 100;

break;

case 3:

turnmul = 1000;

break;

}

turnchar = turnchartmp[0] & 0xF;

Read_Switch_Dec[0] = Read_Switch_Dec[0] + turnchar * turnmul;

turncnt = (i + 1) * 4;

turnchartmp[0] = Read_Switch[0] >> turncnt;

}

turnchartmp[0] = Read_Switch[0];

}

Read__out:

_nop_();

}

如何使用数字旋转编码开关

数字旋转编码器在现在的工控领域运用广泛,跑步机的旋钮,控制器的旋钮,音响的音量控制旋钮,都是数字旋转编码器的典型应用。

看一个数字旋转编码器的视频,加深一下理解。

5脚的数字旋转编码器:

图 1 旋转编码器的实物图

具有左转,右转,按下三个功能。4、5脚是中间按下去的开关接线 1 2 3脚 一般是中间2脚接地,1、3脚上拉电阻后,当左转、右转旋纽时,在1、3脚就有脉冲信号输出了。

着这是标准资料:

图2 旋转编码器的结构图

在单片机编程时,左转和右转的判别是难点,用示波器观察这种开关左转和右转时两个输出脚的信号有个相位差,见下图:

图3 旋转编码器在旋转的时候的输出波形

由此可见,如果输出1为高电平时,输出2出现一个高电平,这时开关就是向顺时针旋转; 当输出1 为高电平,输出2出现一个低电平,这时就一定是逆时针方向旋转。

所以,在单片机编程时只需要判断当输出1为高电平时,输出2当时的状态就可以判断出是左旋转或是右旋转了。

还有另外一种3脚的,除了不带按钮开关外,和上面是一样的使用。

图4 三个脚的旋转编码器

参考程序:#include "reg51.h"#define uint unsigned int#define uchar unsigned charsbit Rotation_Key_A = P1_1; //定义旋转编码器的方向判断A口sbit Rotation_Key_B = P1_2; //定义旋转编码器的方向判断B口uint CodingsWitchPolling()//{ static uchar A_Last_State,B_Last_State; //定义了两个变量用来储蓄上一次调用此方法是编码开关两引脚的电平 static uchar High_Last_State;//定义了一个变量用来储蓄以前是否出现了两个引脚都为高电平的状态 uint tmp = 0; if(Rotation_Key_A&&Rotation_Key_B) High_Last_State = 1; // if(High_Last_State) //如果High_Last_State为1执行下面的步骤 { if(Rotation_Key_A==0&&Rotation_Key_B==0) //如果当前编码开关的两个引脚都为底电平执行下面的步骤 { if(B_Last_State) //为高说明编码开关在向加大的方向转 { High_Last_State = 0; tmp++; // } if(A_Last_State) //为高说明编码开关在向减小的方向转 { High_Last_State = 0; tmp--; //设返回值 } } } A_Last_State = Rotation_Key_A; //储存A口的当前状态 B_Last_State = Rotation_Key_B; //储存B口的当前状态 return tmp; //}//编码器计数程序void encoder_cnt(void){ uchar Reade_Io_Data; Reade_Io_Data = PIND; //取端口D管脚信号 Reade_Clr_Signal = (Reade_Io_Data & 0x08); //读取编码器清零信号 if(Reade_Clr_Signal != false) //有编码器清零信号 { couch_num = 0; //水平床码清零 } else { if(encoder_cnt_en == false) //编码器计数模块没有启动 { pr_couch_ba = Reade_Io_Data & 0x03; //取编码器A、B相电平信号 } else { couch_ba = Reade_Io_Data & 0x03; //取编码器A、B相电平信号 if(pr_couch_ba == 0x00) { if(couch_ba == 0x01) { couch_num++; //水平床码加1 } else if(couch_ba == 0x10) { couch_num--; //水平床码减1 } } else if(pr_couch_ba == 0x01) { if(couch_ba == 0x11) { couch_num++; //水平床码加1 } else if(couch_ba == 0x00) { couch_num--; //水平床码减1 } } else if(pr_couch_ba == 0x10) { if(couch_ba == 0x00) { couch_num++; //水平床码加1 } else if(couch_ba == 0x11) { couch_num--; //水平床码减1 } } else if(pr_couch_ba == 0x11) { if(couch_ba == 0x10) { couch_num++; //水平床码加1 } else if(couch_ba == 0x01) { couch_num--; //水平床码减1 } } } pr_couch_ba = couch_ba; }}编码器及其计数模块原理旋转编码器的检测程序(基于51单片机)//旋转编码器检测程序,A/B信号分别接在了INT0和INT1上//2005年3月27用KEIL编译、硬件测试通过//注意:编码器的信号,程序未做消抖处理。测试中,A/B信号上各//接了一只104的瓷片电容,工作很正常。如果不接电容,请自行编//写信号消抖程序。#include <at89x51.h>sbit led=0xB1;//有一只LED接在了RXD引脚上,用来指示正反转;main(){ EA=1; //总中断允许 EX0=1; //外部中断0允许 IT0=1; //外部中断0为边沿触发方式 while(1);;}/*********************编码器中断函数入口:无出口:无*********************/void encoder(void) interrupt 0 { //外部中断0 if (INT1) { led=1; } else { led=0; }}whimsy 的AVR程序//外部中断0,用于编码开关解码,解码图: A接中断脚(AVR的PD2),以此为基准,B用来判断方向(连到AVR的PA1), C接地//A -|// | -----|__________|----------|____________//C -|////B -|// | ----------|__________|----------|____________//C -| // CW ===>>> ROTATION//外部中断设置(ISC01=0,ISC00=1): INT0 引脚上任意的逻辑电平变化都将引发中断#pragma interrupt_handler int0_isr:2void int0_isr(void){ //external interupt on INT0 GICR=0; //禁止外部中断 if ((PIND & 0x04)==0) //先判断是高电平产生的中断还是低点平的中断 { if ((PINA & 0x02)==0) //再判断B线上的电平 { keycounter--; keydirection=0; } else { keycounter++; keydirection=1; } else if ((PINA & 0x02)==0) { keycounter++; keydirection=1; } else { keycounter--; keydirection=0; } GICR=0x40; }}

复制代码

以上图文内容均转载自订阅号:电子工程世界(微信搜索 eeworldbbs 关注)

欢迎微博@EEWORLD

如果您也写过此类原创干货欢迎将您的原创发至:bbs_service@eeworld.com.cn,一经入选,我们将帮你登上头条!

与更多行业内网友进行交流请登陆EEWorld论坛。

相关问答

单片机 编码怎么输入?

单片机编码输入方式有多种,包括按键输入、串口输入、ADC输入等等。其中按键输入是最常见的一种方式,通过连接到单片机的IO口,当按下按键时,IO口会产生相应的...

proteus 拨码 盘的名称是什么啊。还有怎么接线啊?

我查下了,proteus里面好像没有拨码盘,但可以使用拨码开关替代。其中,DIPSW_2-DIPSW_10都是各路独立的拨码开关,DIPSWC_4-DIPSWC_10都是有一个公共端的拨码开...

单片机 中的存储器地址编码是补码吗?

在单片机中,存储器地址编码通常不是补码。一般来说,单片机的存储器地址编码采用二进制数或十六进制数来表示。这些编码方式可以直接映射到存储器的物理地址,用...

拨码开关 怎么用_土巴兔装修问答

拔码开关的精密度一定要高,那种还没按下去数字就跳出来的绝对不能要,拔码开关线路板要求最好是镀金的,因为其他镀的容易氧化造成精密度受损,至于接...

基于 单片机 的电梯控制系统难不难做?

基于单片机的电梯控制系统,其原理实现并不难,通过采集按键选择停留的楼层,单片机系统结合楼层信息,控制电动机转动,控制电梯停留在相应的楼层。电梯控制系统...

为什么 单片机 中的注释是问号?

单片机中的注释应该是以双斜杠(//)或者斜杠加星号(/*...*/)的方式表示的,而不是问号。如果你在查看单片机代码时发现注释出现了问号,可能有以下几种原因...

单片机 的EA/VPP引脚有什么作用?

EA/VPP:外部程序存储器选择信号,低电平有效。在复位期间CPU检测并锁存EA/VPP引脚电平状态,当该引脚为高电平时,从片内程序存储器读取指令,只有当程序计数器P...

检测到的音频AD值用什么编码方式传到一条线上?我现在做一个这...

[回答]就是用一条线,两个双向开关的输出端接在这条线上,输入端分别接单片机引脚和音频输出,单片机的通讯直接用高低电平的时间差判别,当音频通讯就关单片...

关于 单片机 、编解码器PT2262/2272、DF无线收发模块之间的问题?

PT2262/PT2272是编码解码新品,有地址位,数据位,地址位一般两者都设定好,不用再动它,数据位可以根据需要连接,可接按键,按键对应要实现的功能,也可按你设...PT...

51 单片机 怎样处理偏移二进制编码?

以8位二进制数来说明。看看插图,即可知道如何处理了。看出来了吗?只要把符号位取反,就大功告成了。这是多么简单的事!以8位二进制数来说明。看看插图,即可...

猜你喜欢