AVR单片机教程——按键动作

发布者:hylh2008最新更新时间:2019-12-02 来源: eefocus关键字:AVR  单片机教程  按键动作 手机看文章 扫描二维码
随时随地手机看文章

上一篇教程中我们学习了如何读取按键状态。而按键的动作,比如单击,至少需要两个状态才能判定,长按、双击的判定更加复杂。今天我们来学习如何使用库函数判断按键单击,以及其实现原理。


我们要实现的是:当一个按键被单击时,一个LED的状态改变(即亮变暗,暗变亮);4个按键对应4个LED。利用库提供的 button_pressed 函数,很容易就能实现这个功能。


 1 #include

 2 #include

 3 #include

 4 

 5 int main()

 6 {

 7     led_init();

 8     button_init(PIN_0, PIN_1);

 9     while (1)

10     {

11         for (uint8_t i = 0; i != BUTTON_COUNT; ++i)

12             if (button_pressed(i))

13                 led_flip(i);

14         delay(40);

15     }

16 }


在主循环中,程序对每个按键调用 button_pressed ,若返回真,则用 led_flip 将LED状态反转。


按键动作需要两个状态来判断,而函数在当下是无法从按键读取到以前的信息的,只能在本次调用时保存状态以供下次使用。自动变量保存的内容无法保留到下一次调用,可选的有全局变量与静态变量。由于此状态只被这一个函数使用,可以把它定义成静态变量。


button_pressed 函数可以判断4个按键的动作,每个按键需要一个 bool 变量,即一个bit的存储空间。为了节省空间,我使用了位操作,这里先不讲,把重心放在按键动作判断逻辑上。以下是判断一个按键动作的函数。


1 bool pressed()

2 {

3     static bool status = true;

4     bool pre = status;

5     status = button_down(BUTTON_0);

6     return !pre && status;

7 }


静态变量 status 用于保存按键在上一次调用时的状态。函数体中,先用自动变量 pre 临时保存了 status ,然后将 status 更新为当前的状态。return 语句返回的是 !pre && status ,即仅当 pre 为假且 status 为真时返回 true 。其逻辑为,如果上一次按键没有被按下而这一次被按下,则按键被单击了。


想一想,为什么 status 的初值要设置成 true ?


另外,上面的代码开头处的蓝色 bool 特别醒目,因为博客园代码着色是按照C#的规则,bool 是其中一个关键字。但是应当注意,C语言中没有 bool 这个关键字,而是 _Bool ;bool 与 true 和 false 都在  中定义。


我们还没有解释过第一段代码中的 delay(40) 。如果你把它去掉,你会发现判定经常出错,往往在抬起的时候被多判定了一次,在按得不是很用力时很不稳定。这是按键内部的机械结构决定的,当处于连通和不连通位置的交界处时,单片机检测到的电平会迅速跳变(按键的原理,以及单片机如何检测按键状态,将在几篇后介绍),而一段延时就可以让这些跳变的电平被 button_down 函数忽略。这里的40是根据经验选取的。其实把40换成10到100之间的数,手感基本没有差别。


然而,即使有这句延时,单击判定还是有出错的时候。如果不能允许这样的错误,就需要“消抖”上场了,我们以后再讲。

关键字:AVR  单片机教程  按键动作 引用地址:AVR单片机教程——按键动作

上一篇:AVR单片机教程——拨动开关
下一篇:AVR单片机教程——按键状态

推荐阅读最新更新时间:2024-11-10 14:00

中断应用设计要点
AVR的中断源比较多,尤其是ATmega128,一共有35个外部以及内部中断源。通常情况下,Flash程序存储器空间的最低位置(0x0000-0x0045)定义为复位和中断向量空间。完整的中断向量见第二章表 2-23。在中断向量表中,处于低地址的中断向量所对应的中断拥有高优先级,所以,系统复位RESET拥有最高优先级。 A.中断设计注意点: 1.具备Bootloader功能的AVR,其中断向量区可以在Flash程序存储器空间最低位置和Bootloader区的头部来回迁移,这主要用于配合Bootloader程序的应用。如果不使用Bootloader功能,一般不要中断向量区进行迁移。 2.Flash较小的AVR芯片,其一个中断向
[单片机]
熔丝位(Fuse)快速入门
AVR Studio 中 STK500 处理熔丝位有巨大的优势:它是以功能组合让用户配置。 这种方式与小马(PnoyProg2000,SL-ISP)相比,具有以下的优势(优势是如此明显,可以用 巨大优势 来形容): 1. 有效避免因不熟悉熔丝位让芯片锁死 (这是初学者的恶梦) 2. 不需要靠记忆与查文档,就能配置熔丝位(这也是初学者的恶梦)这是我们网站为何推荐使用STK500下载器的又一原因。 操作界面如下: (注意:下图中,打勾的表示选中,代表0。没有打勾的表示1)。 上图的资料整理如下(该表下面有中文翻译与说明): On-Chip Debug Enabled; JTAG In
[单片机]
LED 驱动控制专用电路 TM1628 AVR 测试程序源代码
#include avr/io.h #include util/delay.h #define TM1628_DIO_PORTNAME B #define TM1628_DIO_BIT 5 #define TM1628_CLK_PORTNAME B #define TM1628_CLK_BIT 7 #define TM1628_STB_PORTNAME B #define TM1628_STB_BIT 4 #ifndef _CONCAT_ #define _CONCAT_ #define CONCAT(a, b) a ## b #define CONCAT_DDR(portn
[单片机]
AVR单片机中断实现 ATmega16 INT ISR(INT0_vect)
2.21实例功能 前面例子中分别介绍了按键控制发光二极管的亮灭,但是我们注意到,在程序中需要一直检测按键的状态,这样明显的浪费了单片机的资源,降低了单片机的工作效率,。那么有没有一种方法可以让单片机不用一直检测按键的状态,而只在有按键动作时才去响应呢? 当然有!单片机中除了具有基本输入输出功能的作用外,还有专门检测外界信号并作出响应的中断系统。在本例中,通过利用外部中断实现单片机对按键事件的响应和处理。 本例中三个功能模块描述如下: ● 单片机系统:对按键事件产生的中断时间作出响应,并在数码管上显示按键按下的次数。 ● 外围电路:通过将按键连接到单片机的外部中断检测端口,实现中断产生电路,数码管显示电路用于指示
[单片机]
一个avr单片机的汇编程序,注意几个宏指令
//晶振1MHz //LED接PB0 //使用定时器1,1024分频,0.5秒中断一次,LED闪烁一次 程序如下: .include m8def.inc .equ led =0 .equ flash =$60 .org $0000//中断向量表 rest: rjmp START INT0addre: ; External Interrupt0 Vector Address reti INT1addre: ; External Interrupt1 Vector Address reti OC2addre : ; Output Compare2 Interrupt Vector Address reti OVF2addre: ;
[单片机]
AVR定时器的要点介绍
M16的T1 16位定时器一共有15种工作模式,其他2个8位定时器(T0/T2)相对简单,除了T2有异步工作模式用于RTC应用外 (可以利用溢出中断和比较匹配中断作定时功能) 符号定义: BOTTOM 计数器计到0x0000 时即达到BOTTOM MAX 计数器计到0xFFFF ( 十进制的65535) 时即达到MAX TOP 计数器计到计数序列的最大值时即达到TOP。 TOP 值可以为固定值0x00FF、0x01FF或 0x03FF,或是存储于寄存器 OCR1A或ICR1里的数值,具体有赖于工作模式 ------注意MAX和TOP是不同的,在表格 可以看到它们的作用 分5种工
[单片机]
学习AVR(二)ATtiny2313的特点
特点: 使用AVR RISC架构 AVR 高性能、低功耗RISC架构 -120条功能强大的指令 大部分只需 单个时钟周期 就可执行(罗亩按:确实牛) - 32 8位通用工作寄存器 -全静态工作 -20MHz时,最高 20MIPS的处理能力 数据和非易失性程序和数据存储器 -2K字节在系统自编程Flash,寿命:10,000次擦写周期 -128字节在系统可编程EEPROM,寿命:100,000次擦写周期 -128字节内部SRAM -用于Flash编程和EEPROM数据安全的编程时钟 外围特性 -一个8位定时/计数器,具有分离的预标定(Prescaler)和比较模式 -一个16位定时/计数器,具有分离的预标定、比较和捕捉模式
[单片机]
AVR单片机模拟比较器的设计
模拟比较器对正极PB2(AINO)和负极PB3(AINI)的输入电压进行比较,当PB2的电压高于PB3的电压时,模拟比较器输出脚ACO置l。 模拟比较器的控制和状态寄存器ACSR地址为$018($28),复位时值为$O。各位定义如下: ACD:模拟比较器禁止。置l时,模拟比较器的电源被关闭。改变ACD时,必须清ACIE位,否则将产生中断。 ACO:模拟比较器输出。ACO直接与模拟比较器的输出脚相连接。 ACI:模拟比较器中断标志。有模拟比较器输出事件时,该位置1。若ACIE置1,且SREG中的1置1,产生中断。中断执行后,ACI由硬件清O。 ACIE:模拟比较器中断使能位。ACIE置l允许中断,清O禁止中断。 ACIC:模
[单片机]
<font color='red'>AVR</font><font color='red'>单片机</font>模拟比较器的设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved