找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3373|回复: 7
收起左侧

51单片机定时器以及led灯闪烁问题,求大神指点下

[复制链接]
ID:704252 发表于 2020-3-7 20:59 | 显示全部楼层 |阅读模式
烧录进单片机后,按下按键无法加减时间,led灯正常闪烁。功能要求如下:用定时器实现准确的延时,延时到后点亮或熄灭一盏灯,然 后通过两个按键(增、 减) 改变延时长短。比如:刚开始的时候点
亮 1s 后熄灭 1s,当按下“增”按键后,点亮 1.5s,然后熄灭 1.5s, 再点亮 1.5s,如此循环。当按下“减”按键后,点亮 0.5s,然后 熄灭 0.5s, 再点亮 0.5s,如此循环。
以下是单片机代码,不知道是否合理,出现了按下按键,时间无法加和减
#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;

sbit LED = P0^0;
unsigned int i =1000 ; //定时1s


void delay();

void main()
{
    bit keybuf1 = 1;  //按键值暂存,临时保存按键的扫描值
        bit keybuf2 = 1;
    bit backup = 1;  //按键值备份,保存前一次的扫描值
        unsigned int i =1000 ; //定时1s

    ENLED = 0;   //选择LED进行显示
    ADDR3 = 1;
    ADDR2 = 1;
    ADDR1 = 1;
    ADDR0 = 0;  

        TMOD=0X01;
          TH0=0XFC;//赋初值使定时时间为1ms
          TL0=0X18;
        EA=1; //打开总中断
        ET0=1;//打开定时器中断
          TR0=1;//打开定时器

    P2 = 0xF7;   //P2.3置0,即KeyOut1输出低电平
    LED = 0;

        while (1)
    {
        keybuf1 = KEY1;            //把当前扫描值暂存
        if (keybuf1 != backup)     //当前值与前次值不相等说明此时按键有动作
        {
            delay();              //延时大约10ms
            if (keybuf1 == KEY1)   //判断扫描值有没有发生改变,即按键抖动
            {
                if (backup == 0)  //如果前次值为0,则说明当前是弹起动作
                {
                    i = i+500;  //
                }
                backup = keybuf1;  //更新备份为当前值,以备进行下次比较
            }
        }
                keybuf2 = KEY2;            //把当前扫描值暂存
        if (keybuf2 != backup)     //当前值与前次值不相等说明此时按键有动作
        {
            delay();              //延时大约10ms
            if (keybuf2 == KEY2)   //判断扫描值有没有发生改变,即按键抖动
            {
                if (backup == 0)  //如果前次值为0,则说明当前是弹起动作
                {
                    i = i-500;  //
                }
                backup = keybuf2;  //更新备份为当前值,以备进行下次比较
            }
        }
    }
}
/* 软件延时函数,延时约10ms */
void delay()
{
    unsigned int i = 1000;
        
    while (i--);
}

/******中断子程序*******/
void timer0() interrupt 1
{        
        static int cnt;
        TH0=0XFC; //重新赋初值
        TL0=0X18;
          cnt++;
        if(cnt >= i)
        {
                cnt = 0;
                LED = ~LED;
        }
}




回复

使用道具 举报

ID:213173 发表于 2020-3-8 08:20 | 显示全部楼层
不用把按键程序写那么复杂,结果把自己搞晕了。改简单点:
  1. #include <reg52.h>

  2. sbit ADDR0 = P1^0;
  3. sbit ADDR1 = P1^1;
  4. sbit ADDR2 = P1^2;
  5. sbit ADDR3 = P1^3;
  6. sbit ENLED = P1^4;
  7. sbit KEY1 = P2^4;
  8. sbit KEY2 = P2^5;

  9. sbit LED = P0^0;

  10. unsigned int i=2; //定时1s

  11. void delay();

  12. void main()
  13. {
  14.         bit keybuf1 = 0;
  15.         bit keybuf2 = 0;
  16.         ENLED = 0;   //选择LED进行显示
  17.         ADDR3 = 1;
  18.         ADDR2 = 1;
  19.         ADDR1 = 1;
  20.         ADDR0 = 0;  
  21.         TMOD=0X01;
  22.         TH0=0XFC;//赋初值使定时时间为1ms
  23.         TL0=0X18;
  24.         EA=1; //打开总中断
  25.         ET0=1;//打开定时器中断
  26.         TR0=1;//打开定时器
  27.         P2 = 0xF7;   //P2.3置0,即KeyOut1输出低电平
  28.         LED = 0;
  29.         while (1)
  30.         {
  31.                 if (!KEY1)
  32.                 {
  33.                         delay();              //延时大约10ms
  34.                         if(!KEY1 && keybuf1==0)
  35.                         {
  36.                                 keybuf1=1;
  37.                                 if(i<3)
  38.                                         i++;
  39.                         }
  40.                 }
  41.                 else keybuf1=0;

  42.                 if (!KEY2)
  43.                 {
  44.                         delay();              //延时大约10ms
  45.                         if(!KEY2 && keybuf2==0)
  46.                         {
  47.                                 keybuf2=1;
  48.                                 if(i>1)
  49.                                         i--;
  50.                         }
  51.                 }
  52.                 else keybuf2=0;
  53.         }
  54. }
  55. /* 软件延时函数,延时约10ms */
  56. void delay()
  57. {
  58.     unsigned int i = 1000;
  59.         
  60.     while (i--);
  61. }

  62. /******中断子程序*******/
  63. void timer0() interrupt 1
  64. {        
  65.         static int cnt;
  66.         TH0=0XFC; //重新赋初值
  67.         TL0=0X18;
  68.         cnt++;
  69.         if(cnt >= i*500)
  70.         {
  71.                 cnt = 0;
  72.                 LED = ~LED;
  73.         }
  74. }
复制代码
回复

使用道具 举报

ID:332444 发表于 2020-3-8 08:37 | 显示全部楼层
很简单的问题,代码写那么多,看了逻辑也不够清晰,看得都晕乎,其实很简单,一个变量存储时间调节值,初始化中断,主程序判断按键增减变量的值即可。
回复

使用道具 举报

ID:704252 发表于 2020-3-11 12:13 | 显示全部楼层
wulin 发表于 2020-3-8 08:20
不用把按键程序写那么复杂,结果把自己搞晕了。改简单点:

好哒,谢谢
回复

使用道具 举报

ID:704252 发表于 2020-3-11 12:14 | 显示全部楼层
xianfajushi 发表于 2020-3-8 08:37
很简单的问题,代码写那么多,看了逻辑也不够清晰,看得都晕乎,其实很简单,一个变量存储时间调节值,初始 ...

好的,我修改一下
回复

使用道具 举报

ID:704252 发表于 2020-3-11 20:31 | 显示全部楼层
wulin 发表于 2020-3-8 08:20
不用把按键程序写那么复杂,结果把自己搞晕了。改简单点:

可以问一下我的代码哪里出错了吗?
回复

使用道具 举报

ID:213173 发表于 2020-3-12 06:25 | 显示全部楼层
har-d 发表于 2020-3-11 20:31
可以问一下我的代码哪里出错了吗?

backup作为记忆按键状态的位变量不可以共用于多个按键,如只作一个按键记忆在此程序中还是有缺陷:按键按下并不会响应,松手后才会响应。用Keil走单步就一目了然了。
回复

使用道具 举报

ID:704252 发表于 2020-3-12 18:18 | 显示全部楼层
wulin 发表于 2020-3-12 06:25
backup作为记忆按键状态的位变量不可以共用于多个按键,如只作一个按键记忆在此程序中还是有缺陷:按键按 ...

好的,谢谢你
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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