搜索
bottom↓
回复: 15

按键小程序请教

[复制链接]

出0入0汤圆

发表于 2015-11-12 16:57:41 | 显示全部楼层 |阅读模式
刚开始学习51单片机,写了个小程序,当P3^2口按键按下,点亮P1^0口的LED,并间隔约0.5秒闪烁;当P3^7口按键按下,熄灭LED。现在看到的现象是能点亮和熄灭,但不会闪烁。请大家帮忙看看是什么问题。
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar num;
sbit key_sec05=P3^2;
sbit key_stop=P3^7;
sbit out=P1^0;

void allport_Init()                                //端口初始化
{
        P0=P1=P2=P3=0xff;
}

void delayms(uint xms)      //延时
{
        uint b,c;
        for(b=xms;b>0;b--)
    for(c=100;c>0;c--);
}

void keyscan()                                //按键扫描
{
        if(key_sec05==0)
        {
                delayms(10);
                if(key_sec05==0)
                {
                    while(1)
                        {
                                out=0;
                                if(num==10)
                {
                                        num=0;
                        out=~out;                        //使发光管状态取反
                                }               
                                if(key_stop==0)
                                {       
                                        delayms(10);
                                        if(key_stop==0)
                                        {
                                                out=1;
                                                break;
                                        }       
                        }
                          }
                }
        }
}
                               
void T0_time() interrupt 1
{
        TH0=(65535-50000)/256;
        TL0=(65535-50000)%256;
        num++;
}

void main()
{
        allport_Init();       
        TMOD=0x01;//定时器0工作于方式1
          TH0=(65535-45872)/256;
          TL0=(65535-45872)%256;
          EA=1;//开总中断
          ET0=1;//开定时器0的中断
          TR0=1;//启动定时器                                       
        while(1)
        {
                keyscan();
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2015-11-12 17:06:31 | 显示全部楼层
代码写的整齐一些吧,至少大括号要好好对齐!while(1)   {     out=0;   if(num==10)这个地方out=0;去掉吧

出0入0汤圆

发表于 2015-11-12 17:11:40 | 显示全部楼层
  1. void keyscan(void)
  2. {
  3.     if(key_sec05 == 0)
  4.     {
  5.         delayms(10);
  6.         if(key_sec05 == 0)
  7.         {
  8.             out = 0;
  9.             while(1)
  10.             {
  11.                 if(num == 10)
  12.                 {
  13.                     num = 0;
  14.                     out = ~out;
  15.                 }
  16.                 if(key_stop == 0)
  17.                 {
  18.                     delayms(10);
  19.                     if(key_stop == 0)
  20.                     {
  21.                         out = 1;
  22.                         break;
  23.                     }
  24.                 }
  25.             }
  26.         }
  27.     }
  28. }
复制代码

出0入0汤圆

 楼主| 发表于 2015-11-12 17:14:23 | 显示全部楼层
我试了,去掉后,当P3^2口按键按下,要过差不多10秒后P1^0口的LED才会点亮并闪烁

出0入0汤圆

 楼主| 发表于 2015-11-12 17:15:23 | 显示全部楼层
倒是P3^7口按键一按下,马上就熄灭LED。

出0入8汤圆

发表于 2015-11-12 17:15:30 | 显示全部楼层
你那个 while(1) 里面的内容写的有问题

你想一下,当下面这个 if 语句成立后会出现什么情况

  1.          if(num==10)
  2.                 {
  3.                         num=0;
  4.                         out=~out;                        //使发光管状态取反
  5.                  }           
复制代码


情况就是灯确实取反了,但是程序马上进入下次的 while (1)里,在这里面执行的第一条
程序就是点灯
  1. out=0;
复制代码


上面这个过程非常快,你肉眼看到的就是灯一直在亮,没闪烁……

你的要求实现起来很简单的,你再仔细想想吧

出0入8汤圆

发表于 2015-11-12 17:20:47 | 显示全部楼层
建议你看一下我之前发的一个帖子,可以轻松实现你的要求,希望对你有帮助,下面是链接

[代码分享]一个LED状态模块,支持亮、灭时间和闪烁次数设定

出0入8汤圆

发表于 2015-11-12 17:23:19 | 显示全部楼层
Jmhh247 发表于 2015-11-12 17:20
建议你看一下我之前发的一个帖子,可以轻松实现你的要求,希望对你有帮助,下面是链接

[代码分享]一个LED ...

晕,我回贴的时候回复还是零呢,结果发表后连板凳都没占到……

出0入0汤圆

 楼主| 发表于 2015-11-12 17:24:05 | 显示全部楼层
谢谢楼上的朋友

出0入0汤圆

发表于 2015-11-12 17:37:19 | 显示全部楼层
你这个好像没有延时吧 而且代码也不好阅读

出0入0汤圆

发表于 2015-11-12 19:30:12 | 显示全部楼层
void keyscan()  干嘛要用while(1)啊
直接这样
IF ----P3^2口按键按下
delay(10);
IF ----P3^2口按键按下
隔约0.5秒闪烁
else if ----P3^7口按键按下
    关灯

出0入0汤圆

发表于 2015-11-12 19:54:17 | 显示全部楼层
闪太快看不到,视觉暂留

出0入0汤圆

发表于 2015-11-12 23:08:49 | 显示全部楼层
LZ可以看看本坛的金沙滩工作室写的教程,挺适合入门的

出100入85汤圆

发表于 2015-11-13 02:25:26 来自手机 | 显示全部楼层
问题在你if(num==10)你这个扫描的频率比定时中断低。有两个办法1把==改为>= 2把取反放到定时器中断中

出0入0汤圆

发表于 2015-11-13 07:32:42 | 显示全部楼层
我看到的第一个问题,你MAIN里面有个WHILE(1)
在KEYSCAN里面还有一个,如此,当进入KEYSCAN里面后,知道你按下了STOP后才被BREAK;,正如楼上前辈们说的,在里面的那个WHILE里面被以极快的速度执行了OUT=0;,所以你看不到闪。
试试这样,把里面的WHILE去掉,在启动按键==0时使NUM=1;,在后面的判断里面把NUM=0;也改成NUM=1;在停止按键==0时使NUM=0;并同时OUT=1;,在定时器中断里面的NUM++;改为IF(NUM)NUM++;

出0入96汤圆

发表于 2015-11-13 08:25:12 | 显示全部楼层
按键和输出功能分开,会很清晰,
按键中利用标志传递你当前的状态,
输出功能中通过标志判断输出。
  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. uchar num;
  5. sbit key_sec05=P3^2;
  6. sbit key_stop=P3^7;
  7. sbit out=P1^0;
  8. unsigned char Led_Flag;
  9. void allport_Init()                                //端口初始化
  10. {
  11.         P0=P1=P2=P3=0xff;
  12. }

  13. void delayms(uint xms)      //延时
  14. {
  15.         uint b,c;
  16.         for(b=xms;b>0;b--)
  17.     for(c=100;c>0;c--);
  18. }

  19. void keyscan()                                //按键扫描
  20. {
  21.         if(key_sec05==0)
  22.         {
  23.                 delayms(10);
  24.                 if(key_sec05==0)
  25.                 {
  26.                         Led_Flag=0;//闪烁标志
  27.                 }
  28.                 if(key_stop==0)
  29.                 {
  30.                         Led_Flag=1;//熄灭标志
  31.                 }
  32. /*                                {  
  33.                     while(1)
  34.                         {
  35.                                 out=0;
  36.                                 if(num==10)
  37.                                                 {
  38.                                         num=0;
  39.                                                                 out=~out;                        //使发光管状态取反
  40.                                 }               
  41.                                 if(key_stop==0)
  42.                                 {        
  43.                                         delayms(10);
  44.                                         if(key_stop==0)
  45.                                         {
  46.                                                 out=1;
  47.                                                 break;
  48.                                         }        
  49.                                         }
  50.                           }
  51.                 }
  52. */
  53.         }
  54. }
  55.                                 
  56. void T0_time() interrupt 1
  57. {
  58.         TH0=(65535-50000)/256;
  59.         TL0=(65535-50000)%256;
  60.         num++;
  61. }
  62. void Led_Out(void)
  63. {
  64.         if (Led_Flag==0)
  65.         {  
  66.                 if(num==10)                        // 0.5秒时间到
  67.         {
  68.                        num=0;
  69.                         out=~out;       //使发光管状态取反
  70.                 }
  71.         }
  72.         else if (Led_Flag==1)
  73.         {
  74.                 out=0;//熄灭
  75.         }   
  76. }
  77. void main()
  78. {
  79.         allport_Init();        
  80.         TMOD=0x01;//定时器0工作于方式1
  81.           TH0=(65535-45872)/256;
  82.           TL0=(65535-45872)%256;
  83.           EA=1;//开总中断
  84.           ET0=1;//开定时器0的中断
  85.           TR0=1;//启动定时器                                       
  86.         while(1)
  87.         {
  88.                 keyscan();
  89.                 Led_Out();
  90.         }
  91. }
复制代码
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 00:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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