总务部竞赛部联合培训(硬件)

一.按键

(1)按键介绍

按键种类繁多,功能有简有繁,极大的充斥着我们的生活。但是无论如何,所有的按键其实都有一个原型,来源于同一种原理,所有的按键无论多复杂,多华丽,都是从这样一个原型发展而成的。我们平日所见到的绝大部分的按键,其实都可以归类为一种,叫“接触式按键”,又称轻触开关。
在这里插入图片描述
如上图,请对照图一想象,1、2、3、4 分别对应按键的四个引脚,其中蓝色的线表示按键未被按下之时的状态,它是不导通的;而绿色的线是却永久导通的。各位明白了么,其实是两个相同的结构连在一起了。我们只要将需要按键开关作用的线路分别接在1、3 和2、4 的任意取一组合,概括起来就是(1,2)、(1,4)、(3,2)、(3,4)四种组合,都可以起到我们预期的开关作用。

(2)上拉输入和下拉输入

上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用。下拉同理,也是将不确定的信号通过一个电阻钳位在低电平。如果没有上拉/下拉电阻,在没有外界输入的情况下输入端是悬空的,它的电平是未知的。
强弱(强上拉、弱上拉、强下拉、弱下拉)只是上拉电阻的阻值不同,没有什么严格区分。

上拉电阻加到VCC
在这里插入图片描述
下拉电阻加到GND

(2)上拉输入和下拉输入

在这里插入图片描述

(3)按键抖动和消抖

通常按键所用的开关都是机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动,如图所示:

在这里插入图片描述

按键稳定闭合时间长短是由操作人员决定的,通常都会在100ms以上,刻意快速按的话能达到40-50ms左右,很难再低了。抖动时间是由按键的机械特性决定的,一般都会在10ms以内,为了确保程序对按键的一次闭合或者一次断开只响应一次,必须进行按键的消抖处理。当检测到按键状态变化时,不是立即去响应动作,而是先等待闭合或断开稳定后再进行处理。按键消抖可分为硬件消抖和软件消抖。

硬件消抖:

方式:在电路中并联一个电容,电容容量为0.1uf即可。

原理:利用电容两端的电压不能突变的特性,将其并联在机械触点两端,消除接触抖动产生的毛刺电压,并且电容需要一定的充放电时间,充放电时间大于抖动时间,以此实现硬件消抖
在这里插入图片描述

软件消抖:

关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms 左右,在按下瞬间到稳定的时间为5-10ms,在松开的瞬间到稳定的时间也为5-10ms,如果我们再首次检测到键被按下后延时10ms 左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理
在这里插入图片描述
单片机实现:1、先设置IO口为高电平(一般上电默认就为高)
2、读取IO口电平确认是否有按键按下
3、如有IO电平为低电平后,延时几个ms
4、再读取该IO电平,如果任然为低电平,说明对应按键按下
5、执行相应按键的程序
参考代码

#include”reg51.h”
sbit K1 = P3^0;
sbit LED = P2^0; 
int main()
{
	while(1){
		if(K1==0){
			delay(1000);      //软件延时消抖
			if(K1 == 0){
				LED = ~LED; //LED 取反查看按键情况
                             }
                        }
                  }
}

二.蜂鸣器

(1)蜂鸣器类型:有源和无源

在这里插入图片描述
注意:这里的“源”不是指电源,而是指震荡源。
有源蜂鸣器内部带震荡源,所以只要一通电就会叫。无源蜂鸣器内部不带震荡源,所以如果用直流信号无法令其鸣叫,必须用2K-5K的方波去驱动它。有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。有源蜂鸣器直接接上额定电源(新的蜂鸣器在标签上都有注明)就可连续发声。无源蜂鸣器则和电磁扬声器一样,需要接在音频输出电路中才能发声。无源蜂鸣器的工作发声原理是:方波信号输入谐振装置转换为声音信号输出
在这里插入图片描述
有源蜂鸣器的工作发声原理是:直流电源输入经过振荡系统的放大取样电路在谐振装置作用下产生声音信号
在这里插入图片描述
无源蜂鸣器的优点是:
1、便宜。2、声音频率可控,可以做出“多来米发索拉西”的效果3、在一些特例中,可以和LED复用一个控制口
有源蜂鸣器的优点是:程序控制方便

蜂鸣器的其他分类方法

电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。

压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。

自激蜂鸣器是直流电压驱动的,不需要利用交流信号进行驱动,只需对驱动口输出驱动电平并通过放大电路放大驱动电流就能使蜂鸣器发出声音,非常简单。

(2)电路设计

一般小的那种蜂鸣器,就是5V的那种,电压一般是十几到几十毫安的。单片机一般都无法直接驱动。
51单片机的IO口每个引脚的电流驱动能力比较弱:
①拉电流:即单片机引脚置高电平时对外输出的电流,不超过1毫安。
②灌电流:即单片机引脚置低电平时对外吸收的电流,不超过10毫安。
在这里插入图片描述

在这里插入图片描述
代码展示

void main()
{	
	while(1)
	{	
		beep=~beep;
		delay(100); //延时大约1ms   通过修改此延时时间达到不同的发声效果	
	}
}

(3)单片机的应用

在单片机应用的设计上,很多方案都会用到蜂鸣器,大部分都是使用蜂鸣器来做提示或报警,比如按键按下、开始工作、工作结束或是故障等等
改变单片机引脚输出波形的频率,就可以调整控制蜂鸣器音调(频率越高,音调越高)
改变输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小(高电平占空比越高,声音越大
可以使用延时实现不同频率和声音强度的变化。
附:生日快乐歌——蜂鸣器发声程序:

#include <reg51.h>
#define uint unsigned int 
#define uchar unsigned char
sbit  beep = P1^5;
uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
212,212,106,126,159,169,190,119,119,126,159,142,159,0};
uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
9,3,12,12,12,12,12,9,3,12,12,12,24,0};

void DelayMS(uint x)
{
uchar t;
while(x--) for(t=0;t<120;t++);
}

void PlayMusic()
{
uint i=0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{   //播放各个音符,SONG_LONG 为拍子长度
for(j=0;j<SONG_LONG[i]*20;j++)
{
beep=~beep;
/ /SONG_TONE 延时决定了每个音符的频率
for(k=0;k<SONG_TONE[i]/3;k++);
 }
DelayMS(10);
i++;
}
}

void main()
{
   beep=0;
while(1)
{
PlayMusic(); //播放生日快乐
DelayMS(500); //播放完后暂停一段时间
}
}

三.数码管

在这里插入图片描述
发光原理:
与led小灯发光原理一样,皆是通过发光二极管工作,而我们要选择数码管上的发光二极管的搭配,来显示我们需要的字符
在这里插入图片描述
需要注意的是,开发板上的数码管是共阳极,因此I/O口输出低电平才会发光。

锁存器介绍:
锁存器(Latch)是一种对脉冲电平敏感的存储单元电路,它们可以在特定输入脉冲电平作用下改变状态。锁存,就是把信号暂存以维持某种电平状态。锁存器的最主要作用是缓存,其次完成高速的控制器与慢速的外设的不同步问题,再其次是解决驱动的问题,最后是解决一个 I/O 口既能输出也能输入的问题。锁存器是利用电平控制数据的输入,它包括不带使能控制的锁存器和带使能控制的锁存器。

(1)使用译码器的多位数码管显示:

138译码器介绍:
在这里插入图片描述在这里插入图片描述
74LS138 :3 线-8线译码器,共有 54LS138和 74LS138 两种线路结构型式。
工作原理:当一个选通端(E1)为高电平,另两个选通端((/E2))和(/E3))为低电平时,可将地址端(A0、A1、A2)的二进制编码在Y0至Y7对应的输出端以低电平译出。(即输出为Y0至Y7的非)比如:A2A1A0=110时,则Y6输出端输出低电平信号。
应用:
①利用 E1、E2和E3可级联扩展成 24 线译码器;若外接一个反相器还可级联扩展成 32 线译码器。
②若将选通端中的一个作为数据输入端时,74LS138还可作数据分配器。
③可用在8086的译码电路中,扩展内存。
74HC138 : 一款高速CMOS器件,74HC138引脚兼容低功耗肖特基TTL(LSTTL)系列。74HC138译码器可接受3位二进制加权地址输入(A0, A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。
74HC138特有3个使能输入端:两个低有效(E1和E2)和一个高有效(E3)。除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。
功能:74HC138 作用于高性能的存贮译码或要求传输延迟时间短的数据传输系统,在高性能存贮器系统中,用这种译码器可以提高译码系统的效率。将快速赋能电路用于高速存贮器时,译码器的延迟时间和存贮器的赋能时间通常小于存贮器的典型存取时间,这就是说由肖特基钳位的系统译码器所引起的有效系统延迟可以忽略不计。HC138 按照三位二进制输入码和赋能输入条件,从8 个输出端中译出一个 低电平输出。两个低电平有效的赋能输入端和一个高电平有效的赋能输入端减少了扩展所需要的外接门或倒相器,扩展成24 线译码器不需外接门;扩展成32 线译码器,只需要接一个外接倒相器。在解调器应用中,赋能输入端可用作数据输入端。

附:点亮多个数码管——译码器使用程序

#include<reg51.h>
#define uint unsigned int 			   
#define uchar unsigned char 
sbit C138=P2^4;  //定义译码器的三个输入端
sbit B138=P2^3;
sbit A138=P2^2;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0X7D,0X07,0x7f,0x6f};
//数码管数字显示数组
 void delay1ms(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}

void number_led()
{
  C138=0;
  B138=0;
  A138=0;

  P0=table[5];  //显示数字5,段选
  delay1ms();   //延时
  C138=0;     //选择数码管,位选
  B138=0;
  A138=1;

  P0=table[2];
  delay1ms();
  C138=0;
  B138=1;
  A138=0;

  P0=table[0];
  delay1ms();
  C138=0;
  B138=1;
  A138=1;

  P0=table[1];
  delay1ms();
  C138=1;
  B138=0;
  A138=0;

  P0=table[3];
  delay1ms();
  C138=1;
  B138=0;
  A138=1;

  P0=table[1];
  delay1ms();
  C138=1;
  B138=1;
  A138=0;

  P0=table[4];
  delay1ms();
     C138=1;
  B138=1;
  A138=1;

  }
  void main()
{
  while(1)
  {
  number_led();
  }
}

(2)不使用译码器的多位数码管显示:

在这里插入图片描述
动态数码管显示原理:
通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。

附:不使用译码器显示数字程序:

#define GPIO_DIG   P0   //段选	
#define GPIO_PLACE P1	//位选
unsigned char code DIG_PLACE[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char code DIG_CODE[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

unsigned char DisplayData[8];
void DigDisplay(); 
void main(void)
{
	unsigned char i;
for(i=0; i<8; i++)
	{
		DisplayData[i] = DIG_CODE[i];	
	}
	while(1)
	{
		DigDisplay();
	}				
}
void DigDisplay()
{
	unsigned char i;
	unsigned int j;
for(i=0; i<8; i++)
	{
		GPIO_PLACE = DIG_PLACE[i];	 
		GPIO_DIG = DisplayData[i];     
		j = 10;						
		while(j--);	
		GPIO_DIG = 0x00;
	}
}

接线图:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值