找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 941|回复: 19
打印 上一主题 下一主题
收起左侧

按键加减为什么会出现两次1 附单片机程序

[复制链接]
跳转到指定楼层
楼主
/********************************************************************
* 文件名  : 独立按键.c
* 描述    :  该程序实现独立按键去控制 LED灯 的亮灭,并讲诉了对按键的处理方法。
                         独立按键相应的IO口平时为高电平,一旦按键按下,单片机便检测到低电平。
                         按下P3.2,P0.0口对应的LED亮灭交替变化。
                         按下P3.3,P0.1口对应的LED亮灭交替变化。
                         按下P3.4,P0.2口对应的LED亮灭交替变化。
* 创建人  : 东流,2009年8月27日
* 版本号  : 1.0
***********************************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
#define u8 unsigned char
sbit KEY1 = P3^2;   
sbit KEY2 = P3^3;
sbit KEY3 = P3^4;

sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sfr P4 =0Xe8;
sbit P4_0 = P4^0;
u8 cost=0;
/********************************************************************
* 名称 : Delay()
* 功能 : 延时,延时时间为 10ms * del
* 输入 : del
* 输出 : 无
***********************************************************************/
void Delay(uint del)
{
        uint i,j;
        for(i=0; i<del; i++)
        for(j=0; j<1827; j++)   
        ;
}

/********************************************************************
* 名称 : Delay()
* 功能 : 实现按键功能,当按键按下时,相应的LED亮灭交替
* 输入 : 无
* 输出 : 无
***********************************************************************/
void KEY()
{
        if(KEY1==0 || KEY2==0 || KEY3==0)        
        {
//                Delay(2);                            //20毫秒软件防抖
                if(KEY1 == 0)
                {
                Delay(2);
                 P4_0  = 0 ;                //LED显示取反
             cost++;                  
         SBUF= cost;
                 while(!TI);TI=0;
                }
if(KEY2 == 0)
                {                        
                P4_0 = 1;
                cost--;
                         SBUF= cost;
                           while(!TI);TI=0;
                }
                else
                {                        
                        LED3 = !LED3;
                }
                Delay(50);                        //延时0.5秒再进行下次按键的检测
        }        
}

/*------------------------------------------------
                    串口初始化
------------------------------------------------*/
void InitUART  (void)
{

    SCON  = 0x50;                        // SCON: 模式 1, 8-bit UART, 使能接收  
//              // TMOD: timer 1, mode 2, 8-bit 重装
    TMOD |= 0x21;    //T1方式2、T0方式1
        TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
    TL1 = 0xFD;      //波特率
        TR1   = 1;                  // TR1:  timer 1 打开                        
    IE |= 0x92;      //开启中断
        EA    = 1;                  //打开总中断
//    ES    = 1;                  //打开串口中断
}                           

  初始时按键按下,计数器出现两次1,或者不累加是什么问题?


/********************************************************************
* 名称 : Main()
* 功能 : 实现按键控制LED的亮灭
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main(void)
{
        
        InitUART();
        while(1)
        {
                 KEY();
        }
}

捕获.PNG (12.67 KB, 下载次数: 17)

捕获.PNG
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:526543 发表于 2023-5-24 12:29 | 只看该作者
可能是由于按键的按下动作引起了按键的抖动
回复

使用道具 举报

板凳
ID:302293 发表于 2023-5-24 15:51 | 只看该作者
123456ZXC1 发表于 2023-5-24 12:29
可能是由于按键的按下动作引起了按键的抖动

但是后面再按就没有抖动了,只是初始时有这样的情况
回复

使用道具 举报

地板
ID:1079614 发表于 2023-5-24 17:22 | 只看该作者
按键1的消抖再判断之后的里面的那个延时去掉看看还有没有
回复

使用道具 举报

5#
ID:1079614 发表于 2023-5-24 17:23 | 只看该作者
sr861126 发表于 2023-5-24 15:51
但是后面再按就没有抖动了,只是初始时有这样的情况

按键1消抖后里面的延时去掉看看还有没有
回复

使用道具 举报

6#
ID:202023 发表于 2023-5-24 18:41 | 只看该作者
你这程序是没copy全,还是就是这样, SBUF,TI,都没看到定义。难到不会报错。另建议key,不要用p3.2,P3.3,p3.4.因为这几个IO有第二功能,在用这几个io时就有可能和其他冲突,程序肯定不会报错,但可能会有莫名奇妙的问题产生。
回复

使用道具 举报

7#
ID:213173 发表于 2023-5-24 21:18 | 只看该作者
描述与按键代码不一致,你这代码近乎长短按,短按响应一次,长按每隔0.5秒重复响应。延时消抖被注释掉了,移放在不恰当的位置。
回复

使用道具 举报

8#
ID:624769 发表于 2023-5-24 22:21 | 只看该作者
和按键抖动无关, 如果抖动了, 发送前 肯定会 ++ 或者 -- 一次, 绝对有别的代码,  所谓的 发两次1 是要发 2 的时候被 -1 了,  看你那个  5 后面  发了个3 就知道, 肯定有个地方在  - cost
回复

使用道具 举报

9#
ID:302293 发表于 2023-5-25 07:56 | 只看该作者
188610329 发表于 2023-5-24 22:21
和按键抖动无关, 如果抖动了, 发送前 肯定会 ++ 或者 -- 一次, 绝对有别的代码,  所谓的 发两次1 是要发 2  ...

别人的地方没有--,初始时是0,按理说按一次就加1,但是按了2次才加1,后面按就正常按一次加1
回复

使用道具 举报

10#
ID:302293 发表于 2023-5-25 08:28 | 只看该作者
188610329 发表于 2023-5-24 22:21
和按键抖动无关, 如果抖动了, 发送前 肯定会 ++ 或者 -- 一次, 绝对有别的代码,  所谓的 发两次1 是要发 2  ...

  按一次,抖动了出现了两个“1”

捕获.PNG (18.04 KB, 下载次数: 14)

捕获.PNG
回复

使用道具 举报

11#
ID:302293 发表于 2023-5-25 08:43 | 只看该作者
huaruolong 发表于 2023-5-24 18:41
你这程序是没copy全,还是就是这样, SBUF,TI,都没看到定义。难到不会报错。另建议key,不要用p3.2,P3.3 ...

没有关系,还是抖动的问题
回复

使用道具 举报

12#
ID:302293 发表于 2023-5-25 08:45 | 只看该作者
123456ZXC1 发表于 2023-5-24 12:29
可能是由于按键的按下动作引起了按键的抖动

是抖动,刚上电按下出现抖动,后面按就没有抖动了
回复

使用道具 举报

13#
ID:302293 发表于 2023-5-25 08:59 | 只看该作者
sr861126 发表于 2023-5-25 08:43
没有关系,还是抖动的问题

为什么消不掉呢
回复

使用道具 举报

14#
ID:302293 发表于 2023-5-25 10:11 | 只看该作者
A-set 发表于 2023-5-24 17:23
按键1消抖后里面的延时去掉看看还有没有

去掉延时是一样de
回复

使用道具 举报

15#
ID:384109 发表于 2023-5-25 10:28 | 只看该作者
找个例程看看防抖怎么做吧,暂时看是防抖没做好,或者说没做防抖
回复

使用道具 举报

16#
ID:330059 发表于 2023-5-25 20:01 | 只看该作者
按键代码需要做消抖处理
回复

使用道具 举报

17#
ID:624769 发表于 2023-5-26 00:05 | 只看该作者
sr861126 发表于 2023-5-25 08:28
按一次,抖动了出现了两个“1”

你明白抖动的意思么?
按你的代码,如果按键抖动,应该按一次后,连续发出 01,02  甚至还有 03
但是,你是发两次  01, 说明,运行了两次  SBUF = cost, 却没有运行两次 cost++,所以和抖动没有任何关系。
回复

使用道具 举报

18#
ID:213173 发表于 2023-5-26 08:47 | 只看该作者
188610329 发表于 2023-5-26 00:05
你明白抖动的意思么?
按你的代码,如果按键抖动,应该按一次后,连续发出 01,02  甚至还有 03
但是, ...

同意17楼意见,虽然楼主按键代码写得......,但问题核心不在于此。在于串口初始化函数被胡乱开启中断。众所周知,T1作为波特率发生器就得禁止定时器1中断。否则就可能发生不可预测的错误。按如下设置问题迎刃而解。
void InitUART(void)                //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位数据,可变波特率
        TMOD |= 0x20;                //设置定时器模式
        TL1 = 0xFD;                //设置定时初始值
        TH1 = 0xFD;                //设置定时重载值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //定时器1开始计时
}
回复

使用道具 举报

19#
ID:45879 发表于 2023-5-26 09:23 | 只看该作者
没细看程序,完按键,记得检测按键松开
回复

使用道具 举报

20#
ID:1079863 发表于 2023-5-26 14:26 | 只看该作者
按键加减时出现两次1的情况通常是由于按键抖动引起的。按键抖动是指在按下或释放按键时,由于机械性质或电气接触不稳定等原因,导致按键信号在短时间内多次切换状态。这种抖动可能会导致单片机在检测按键状态时误认为按键被按下了两次。  为了解决按键抖动问题,可以在软件中使用适当的按键消抖算法。一种常用的按键消抖方法是使用软件延时和状态判断的组合。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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