找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机C语言按键功能切换有问题,没法实现两种功能的多次切换

[复制链接]
跳转到指定楼层
楼主
#include <reg51.h>        

sbit led = P1^0;        
sbit speaker= P1^1;
sbit key = P2^1;


void main()               
{
        key = a;
        if(key == 1)
        {
        unsigned int delay;
        while(1){        
                led = 1;        
                speaker = 0;
                delay = 20000;
                while(delay--);               
                led = 0;
    speaker = 1;               
                delay = 20000;
                while(delay--);        
        }        
        }
        else
        {
                led = 0;
                speaker = 0;
  }
}


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

使用道具 举报

沙发
ID:526108 发表于 2023-5-10 14:33 | 只看该作者
用函数指针啊
回复

使用道具 举报

板凳
ID:1043290 发表于 2023-5-10 15:49 | 只看该作者
不知道你要实现什么功能,修改While条件判断,防止按键按下之后进入死循环。

void main()               
{
        key = a;
        if(key == 1)
        {
        unsigned int delay;
        led = 1;  

        delay = 20000;
       }
        else  //这里最好不要加什么判断,因为单片机都是死循环的,里面的值容易和后面的进行互锁
       {
               // led = 0;  
               // speaker = 0;
  }
        while(led ){
                speaker = 0;
                while(delay--);
       if(delay==0)
        {
            speaker=1;
            led=0;
            delay = 20000;
               }

               }

      while(speaker )
  {

while(delay--);
       if(delay==0)
            speaker=0;
               }

}

回复

使用道具 举报

地板
ID:1043290 发表于 2023-5-10 15:51 | 只看该作者
按键切换建议自己标定几个状态(变量),按下之后把KeyUp==1,然后用if(KeyUp==1){
回复

使用道具 举报

5#
ID:1043290 发表于 2023-5-10 16:07 | 只看该作者
按键扫描的话很多例子,在网上可以搜搜。
比如很简单的:
定义按键状态:
u8 KeyUp=0;
u8 KeyDown=0;
假设需要触发按钮:
int Main()
{
unsigned int delay=20000;
sbit led = P1^0;        
sbit speaker= P1^1;
sbit key = P2^1;
  /***这里是外设初始化和时钟初始化***/
  While(1)
  {
    if(KEY==1)
    {
        KeyDown=1;
        delay=20000;
    }
   else
   {
     KeyDown=0;
    /*这里清零状态,等等*/

   }

//执行按键按下的动作
  if(KEY==1&KeyDown==1)//一般这里增加消抖会好点
  {
     //这里添加要用的代码,比如设置动作等等
    led=1;点灯
    speaker = 0;
    //延时;
   While(delay--);
  //关灯
    led=0;点灯    speaker = 1;
    delay=20000;
    While(delay--);

  }

  }

}

以上逻辑用在死等延时,不死等延时的话重新考虑状态即可;


回复

使用道具 举报

6#
ID:838962 发表于 2023-5-10 16:19 | 只看该作者
huxiaolin 发表于 2023-5-10 15:49
不知道你要实现什么功能,修改While条件判断,防止按键按下之后进入死循环。

void main()               ...

做的是一个接收信号做出反应的报警装置,仿真上就只能使用直接连接电源做模拟了,开关部分就是信号输入端,开关按下就是有故障,要求是正常情况下无反应,开关按下led闪烁,断开就还原成初始态。没要求具体使用什么传感器,仿真的模拟上就是直接给高电平,所以也不需要消抖那些。
回复

使用道具 举报

7#
ID:1043290 发表于 2023-5-10 16:29 | 只看该作者
spom 发表于 2023-5-10 16:19
做的是一个接收信号做出反应的报警装置,仿真上就只能使用直接连接电源做模拟了,开关部分就是信号输入端 ...

按我后面给的那版试试,不要在else里面死锁实时状态。
回复

使用道具 举报

8#
ID:838962 发表于 2023-5-10 16:57 | 只看该作者
huxiaolin 发表于 2023-5-10 16:29
按我后面给的那版试试,不要在else里面死锁实时状态。

已解决了,代码如下
我把按键值的检测放到while语句里面,然后加个return避免卡在死循环里。
#include <reg51.h>       
#define uchar unsigned char
#define uint unsigned int

sbit led = P1^0;       
sbit speaker= P1^1;
sbit key = P2^1;


void main()               
{
        key=0;
        led=0;
        speaker=0;
        {
        unsigned int delay;
        while(1){       
                if(key == 1)
                {
                led = 1;       
                speaker = 0;
                delay = 20000;
                while(delay--);               
                led = 0;
    speaker = 1;               
                delay = 20000;
                while(delay--);       
                }
                return;
        }       
        }
}
回复

使用道具 举报

9#
ID:1043290 发表于 2023-5-10 17:11 | 只看该作者
spom 发表于 2023-5-10 16:57
已解决了,代码如下
我把按键值的检测放到while语句里面,然后加个return避免卡在死循环里。
#include  ...

嗯嗯,裸机的话上电是循环执行的,在While里面。你之前那种,初始化IO外设都没执行完,if是做不了判断的。基本就死机了。然后哪个return我没搞懂呐,加了的话应该也没啥用,单片机主函数没有用到返回值的,应该不用的
回复

使用道具 举报

10#
ID:838962 发表于 2023-5-10 19:47 | 只看该作者
huxiaolin 发表于 2023-5-10 17:11
嗯嗯,裸机的话上电是循环执行的,在While里面。你之前那种,初始化IO外设都没执行完,if是做不了判断的 ...

没return的话程序会卡在循环里面,因为考虑到没收到信号(开关断开)的时候要恢复初始状态,如果说手动复位的话在题目的要求上感觉不太合理。甚至说可以手动复位的话最开始的那串代码就已经能用了。
回复

使用道具 举报

11#
ID:838962 发表于 2023-5-10 19:50 | 只看该作者
huxiaolin 发表于 2023-5-10 17:11
嗯嗯,裸机的话上电是循环执行的,在While里面。你之前那种,初始化IO外设都没执行完,if是做不了判断的 ...

最开始只考虑到闪烁的部分,那时候的想法是P2^!端口有两个状态嘛,一个低电平就是正常情况下,高电平就是工作状态,然后0态即初始态就是else部分,
回复

使用道具 举报

12#
ID:161164 发表于 2023-5-11 10:35 | 只看该作者
零延时,零等待



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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