找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机按键控制灯问题,不能按照我的要求工作

[复制链接]
跳转到指定楼层
楼主
ID:237797 发表于 2018-12-9 20:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
要求K1,K2都能控制灯,控制逻辑关系是:K1一直按下,灯亮6S后,如果K2按下灯微亮(亮度10%),K2没有按下灯全亮,K1松开不按下灯灭;如此反复循环。


编译没有问题,现在不能按照我的要求工作。现象是:按下K1灯亮6S后,如果K2按下灯微亮(亮度10%),K2没有按下灯全亮,K1松开不按下灯应该灭,现在灯不灭了,也不循环。程序一直工作在循环(whlie)里面没有跳出来,若是把while注解了不用,K1按下延时6S灯灭。问题出在哪里?

本人写的单片机程序如下:
  1. #include<reg51.h>
  2. typedef unsigned char U8;
  3. sbit led=P1^0;
  4. sbit sun=P1^1;
  5. sbit pir=P1^2;
  6. void delay10ms(unsigned int c)
  7. {
  8. unsigned char a,b;
  9. for(;c>0;c--)
  10.   for(a=38;a>0;a--)
  11.    for(b=130;b>0;b--);
  12. }
  13. //可调pwm函数
  14. void pwm(unsigned char a)   //改变a的值调整占空比
  15. {
  16. U8 i;
  17. led=0X00;
  18. {
  19.   for(i=0;i<255;i++)
  20.   {
  21.    if(i<a)        //改变a的值调整占空比
  22.     led=0xFF;
  23.    else
  24.     led=0x00;
  25.   }
  26. }
  27. }
  28. void main()
  29. {
  30. if(sun==0)
  31. {
  32.   led=1;
  33.   delay10ms(600);
  34.   while(1)
  35.   {
  36.    if(pir==1)
  37.     led=1;
  38.     else
  39.      pwm(25);    //改变1到255的大小值调整占空比         
  40.   }
  41.   }
  42.   else
  43.   {
  44.   led=0;
  45.   }
  46.   }
复制代码

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

使用道具 举报

沙发
ID:410399 发表于 2018-12-10 08:11 | 只看该作者
把while括住整个main函数的内容
回复

使用道具 举报

板凳
ID:359468 发表于 2018-12-10 09:21 | 只看该作者
好好检查一下逻辑和共阴阳极
回复

使用道具 举报

地板
ID:443039 发表于 2018-12-10 09:29 | 只看该作者
要了解单片机的工作流程啊,裸机工作你的工作代码都要放在while里面,初始化代码放在while外面
回复

使用道具 举报

5#
ID:443178 发表于 2018-12-10 12:17 | 只看该作者
你的共阳极是不是俩摩羯错误
回复

使用道具 举报

6#
ID:443178 发表于 2018-12-10 12:17 | 只看该作者
检查一下共阳极和共阴极是否混乱
回复

使用道具 举报

7#
ID:237797 发表于 2018-12-10 15:46 | 只看该作者
sprouty195 发表于 2018-12-10 09:21
好好检查一下逻辑和共阴阳极

共阳极的
回复

使用道具 举报

8#
ID:237797 发表于 2018-12-10 15:47 | 只看该作者
mosqu 发表于 2018-12-10 08:11
把while括住整个main函数的内容

while整个main函数,运行就停在开机延时哪里,K2不起作用了
回复

使用道具 举报

9#
ID:443406 发表于 2018-12-10 16:16 | 只看该作者

void main()
{
  while(1)
  {
   if(sun==0)
   {
     led=1;
     delay10ms(600);

     if(pir==1)
      led=1;
      else
       pwm(25);    //改变1到255的大小值调整占空比         
    }
    else
    {
      led=0;
    }
  }
}
回复

使用道具 举报

10#
ID:304235 发表于 2018-12-10 16:43 | 只看该作者
6S用定时器中断来定时。main函数内先初始化变量 然后再用while函数进行循环。
下面程序有个框架, 你再根据自己的需求改一改,调试调试。。
#include<reg52.h>
typedef unsigned char U8;
sbit led=P1^0;
sbit sun=P1^1;
sbit pir=P1^2;
U8 j;

void pwm(unsigned char a)  
{
U8 i;
led=0X00;
{
  for(i=0;i<255;i++)
  {
   if(i<a)      
    led=0xFF;
   else
    led=0x00;
  }
}
}

void delay10ms(unsigned int c)
{
unsigned char a,b;
for(;c>0;c--)
  for(a=38;a>0;a--)
   for(b=130;b>0;b--);
}

void Timer1Init(void)               
{       
        TMOD &= 0x0F;               
        TL1 = 0x00;               
        TH1 = 0xDC;       
        TF1 = 0;               
        TR1 = 1;               
}

void main()
{
        Timer1Init();
        while(1)
        {
                if(j == 600)
                {
                        led = 1;
                        TR1 = 0;
                }
               
                if(!pir)
                {
                        delay10ms(5);
                        if(!pir)
                        {
                                 pwm(25);
                        }
                }
               
                if(!sun)
                {
                        delay10ms(5);
                        if(!sun)
                        {
                                 led = 0;
                                 TR1 = 1;
                        }
                }
               
        }
}

void Timer0() interrupt 1
{
        if(!sun)
        {
                TL1 = 0x00;               
                TH1 = 0xDC;
                j++;
        }else
        {
                j = 0;
        }
}
回复

使用道具 举报

11#
ID:237797 发表于 2018-12-11 08:00 | 只看该作者
djh635498852 发表于 2018-12-10 16:43
6S用定时器中断来定时。main函数内先初始化变量 然后再用while函数进行循环。
下面程序有个框架, 你再根 ...

今天晚上用你的方法试试。
回复

使用道具 举报

12#
ID:237797 发表于 2018-12-11 08:03 | 只看该作者
futon18 发表于 2018-12-10 16:16
void main()
{
  while(1)

我开始程序就是你这样的,进去灯一直亮。不受控制。我也想了好久,感觉逻辑上没有错,控制就是不正常;后面才把while放在我贴上来的程序位置。
回复

使用道具 举报

13#
ID:237797 发表于 2018-12-11 21:14 | 只看该作者
#include<reg52.h>
typedef unsigned char U8;
sbit led=P1^0;
sbit sun=P1^1;
sbit pir=P1^2;
U8 j;

void pwm(unsigned char a)  
{
U8 i;
led=0X00;
{
  for(i=0;i<255;i++)
  {
   if(i<a)      
    led=0xFF;
   else
    led=0x00;
  }
}
}

void delay10ms(unsigned int c)
{
unsigned char a,b;
for(;c>0;c--)
  for(a=38;a>0;a--)
   for(b=130;b>0;b--);
}

void main()
{
  while(1)
  {
   if(sun==0)
   {
//     led=1;
//     delay10ms(600);

     if(pir==1)
      led=1;
      else
       pwm(25);    //改变1到255的大小值调整占空比         
    }
    else
    {
      led=0;
    }
  }
}
我按照这样把开灯后灯亮这6S注释了,能满足我的K1,K2控制灯的要求,就是K1按下要工作6S不行,也要这6S期间K1也是一直按下去的,在这6S之间要的K1断开,要求灯也要灭。
回复

使用道具 举报

14#
ID:237797 发表于 2018-12-11 21:15 | 只看该作者
本帖最后由 lclbf 于 2018-12-12 07:50 编辑
djh635498852 发表于 2018-12-10 16:43
6S用定时器中断来定时。main函数内先初始化变量 然后再用while函数进行循环。
下面程序有个框架, 你再根 ...

按照你这个程序我没有调试出来,按下K2的时候灯变暗了,但是灯还会闪烁。后来发现灯闪烁是因为开关按下加了消抖延时的原因。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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