设为首页收藏本站

arduino 单片机机器人爱好者之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 7912|回复: 2

Arduino入门教程—拓展实验篇二 按钮无下拉电阻控制LED

[复制链接]

签到天数: 398 天

[LV.9]以坛为家II

发表于 2013-6-12 09:15:22 | 显示全部楼层 |阅读模式
本帖最后由 AllBlue 于 2013-8-29 16:13 编辑

按钮无下拉电阻控制LED

基础实验三 按钮控制LED中我们介绍过使用按钮控制LED,我们当时在按钮连接时,使用了一个10K的下拉电阻来将I/O口的电平钳位在低电平,从而稳定控制。
PS:数字电路有三种状态:高电平、低电平、和高阻状态(可能为高也可能为低),有些应用场合不希望出现高阻状态,可以通过上拉电阻或下拉电阻的方式使处于稳定状态,具体视设计要求而定!

在Arduino硬件介绍时,我们有过这样的介绍“ ☻14路数字输入输出口:工作电压为5V,每一路能输出和接入最大电流为40mA每一路配置了20-50K欧姆内部上拉电阻(默认不连接)。除此之外,有些引脚有特定的功能 ”;这说明我们可以使用arduino本身的上拉电阻来代替外部的下拉,也就是说我们可以不使用下拉电阻,直接通过按钮控制。这里要说一句,arduino只有上拉功能,无下拉功能~
PS:上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用。下拉同理。也是是将不确定的信号通过一个电阻钳位在低电平。
上拉是对器件输入电流,下拉是输出电流;强弱只是上拉电阻的阻值不同,没有什么严格区分;对于非集电极(或漏极)开路输出型电路(如普通门电路)提升电流和电压的能力是有限的,上拉电阻的功能主要是为集电极开路输出型电路输出电流通道。

下面我们看下电路图:
Button.jpg

电路中我们将之前的10K电阻去掉了,这时候如果你还是通过以前的程序来控制,会发现灯的状态不稳定,有时候动动线都会引起亮灭的变化,这时的数字4端口状态就为高阻态。

下面我们就看下我们使用内部上拉功能的程序:

  1. /*
  2. 按钮无下拉电阻控制LED
  3. 读取按键值,来点亮LED灯
  4. BY TSRobot
  5. */

  6. #define LED 8 //定义LED引脚为8
  7. #define BUTTON 4 //定义按钮开关引脚为4
  8. int val = 0; //变量val用来储存按钮状态

  9. void setup(){
  10. pinMode(LED, OUTPUT); //设定LED引脚为输出状态
  11. pinMode (BUTTON,INPUT_PULLUP); //设定按钮引脚为输入状态,并拉高
  12. }

  13. void loop(){
  14. val = digitalRead(BUTTON); //读取按钮状态并储存
  15. //当按钮按下时,设定val为HIGH
  16. if (val == HIGH){
  17. digitalWrite(LED,LOW); //开启LED灯
  18. }else{
  19. digitalWrite(LED,HIGH); //关闭LED灯
  20. }
  21. }
复制代码

程序中主要就是靠着个语句实现功能的:pinMode (BUTTON,INPUT_PULLUP); //设定按钮引脚为输入状态,并拉高
官网资料: http://www.arduino.cc/en/Tutorial/InputPullupSerial

将这个程序烧写到控制板中,灯就受到按钮的控制了,而且很稳定哦~~~

该用户从未签到

发表于 2013-10-22 03:45:10 | 显示全部楼层
你的试验应该会有按键 “弹跳” 的问题吧???

点评

加个延时应该就会避免那样的情况发生,我试验的时候还好,没怎么出现这个问题,所以就没有加延时~~~  发表于 2013-10-22 19:26
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2014-3-30 17:08:42 | 显示全部楼层
物理按键,存在机械抖动是非常很正常的,在实际使用时,我们可以用最简单的延时函数来消除抖动,通常取值10ms左右,代码如下:
  1. *****************************************************
  2. * 检测数字输入信号,通过按键来完成
  3. * 每按下一次按键,将灯的状态取反
  4. ******************************************************/
  5. int buttonPin = 12;     //按键输入引脚
  6. int ledPin = 13;        //灯输出控制引脚
  7. int ledState = LOW;
  8. void setup() {
  9.   pinMode(ledPin,OUTPUT);   //13号数字口设置为输出状态
  10. }

  11. void loop() {

  12. if(!digitalRead(buttonPin)) //检测按键是否被按下
  13. {
  14.    delay(15);                //延时10ms,消除按键机械抖动
  15.    if(!digitalRead(buttonPin))  //再次检测按键值
  16.    {
  17.      while(!digitalRead(buttonPin)) ;     //松手检测,等待按键释放
  18.      digitalWrite(ledPin,ledState);       //控制灯的亮灭
  19.      ledState = !ledState;                //状态取反
  20.    }
  21. }
  22. }
复制代码
在实时系统中,加入delay();延时势必会影响到系统的实时性,尤其是在多按键的情况下,下面将采用状态机的思想来改写上面的程序,主程序中只需要每10ms调用一次该检测函数即可,程序选自 --马潮编写的AVR书籍.
  1. #define buttonStateOff 0   //状态1,无键按下
  2. #define buttonStateOn  1   //状态2,有键按下,但无法确定是否有效
  3. #define buttonStateOnOff  2 //状态3,确定按键是否按下
  4. char buttonValue()
  5. {
  6.   static int buttonState = 0;   //按键状态值,必须定义为static类型
  7.   int buttonValue = 0;  //读取到的按键状态
  8.   int buttonReturn = 0;  //返回的状态值
  9.   buttonValue = digitalRead(buttonPin);  //读当前按键值
  10.   switch(buttonState)  //判断当前按键状态
  11.   {
  12.     case buttonStateOff:  //状态1
  13.       if(!buttonValue)  //如果键按下
  14.       buttonState = buttonStateOn; //则转到状态2
  15.       break;
  16.     case buttonStateOn:  //状态2
  17.       if(!buttonValue)  //如果按键仍被按下
  18.       {
  19.         buttonReturn = 1;   //按键赋值
  20.         buttonState = buttonStateOnOff;  //进入状态3,松手检测
  21.       }
  22.       else  //否则存在抖动
  23.       {
  24.         buttonState = buttonStateOff;
  25.       }
  26.       break;
  27.     case buttonStateOnOff:
  28.       if(buttonValue) buttonState = buttonStateOff; //松手检测
  29.       break;
  30.   }
  31.   return buttonReturn;  //返回按键值
  32. }
复制代码


回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|联系我们|YFRobot ( 苏ICP备13017135  

GMT+8, 2017-3-2 04:32 , Processed in 0.423686 second(s), 30 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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