用 AT89C52 使 LED 闪亮的程序

本文提供了一个使用定时器控制LED闪烁的C语言程序,通过按键切换LED的状态,实现了不同状态下LED以1秒快闪和3秒慢闪的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

电路:P0.0、P0.1 分别外接一个 LED,输出高电平时,LED 发光。
   P2.0 外接一个按键。
请“不用延时程序”写个这样的程序:
当按键不按的时候,LED(D1)先以1秒的时间快闪三下,然后再以3秒的时间慢闪三下。
若按下按键后,LED(D2)先以1秒的时间快闪三下,然后再以3秒的时间慢闪三下。
是不用“不用延时程序”写的哦。(*^__^*)……

问题补充: 请用C语言写。
当按键按下、松开,都应该立即转到相应的 LED 先以1秒的时间快闪三下,然后再以3秒的时间慢闪三下。

悬赏分:130 | 解决时间:2011-9-30 23:19
;============================================
最佳答案:“不用延时程序”,就是要求用定时器控制时间,这和时钟程序的思路是相同的。
下列程序,已经调试成功:
//-----------------------------------------------
#include<reg51.h>

unsigned char  n_25ms, M1_n, M2_n, Last_p2, in_p2;
unsigned char code  O_c[] = {
    0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
    0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00};
bit  TT_f;
//-----------------------------------------------
void main() 
{
    P0 = 0;
    TMOD = 0x01;
    TH0 = (65536 - 12500) / 256; //12.5ms@12MHz
    TL0 = (65536 - 12500) % 256;
    TR0 = 1;
    ET0 = 1;
    EA = 1;
    n_25ms = 0;
    M1_n = 0;
    TT_f = 0;
    Last_p2 = P2;
    while(1) ;
}
//-----------------------------------------------
void T0_INT() interrupt 1
{
    TH0 = (65536 - 12500) / 256; //12.5ms@12MHz
    TL0 = (65536 - 12500) % 256;
    n_25ms++;
//**********************************按键检测与状态的变换
    in_p2 = 8;
    if (P2 == 255)  in_p2 = 0;
    M2_n = 8;
    if (TT_f)  M2_n *= 3;
    if (P2 != Last_p2) {
      Last_p2 = P2;
      n_25ms = M2_n;
      M1_n = 0;
      TT_f = 0;
    }
//**********************************
    if (n_25ms == M2_n) {   //如果到预定的时间
      n_25ms = 0;           //清零
      M1_n++;               //输出下一个数据
      if (M1_n == 8) {      //输出8个了?
        M1_n = 0;           //清零
        TT_f = ~TT_f;       //变更状态
      }
      P0 = O_c[M1_n + in_p2];//输出数据
    }
}
//-----------------------------------------------
注意,P0口需要加上上拉电阻。
;============================================
回答时间:2011-9-29 11:15 |
回答者: 做而论道 | 十五级采纳率:43% 名人
提问者对于答案的评价:谢谢,可以了!
原题网址:http://zhidao.baidu.com/question/324515357.html
;============================================
后记:

这个题目的要求有些令人费解,即要有定时中断,还有按键的检测,按键不变时,输出还要有两种花样。

有人给出了如下的建议:
-------------------------------------------------
用定时器吗!你先做出1秒的基准,3个基准就是3秒。
主函数用:
if(按键标志位位0) {
  for(循环3次) {点亮LED1,一秒后,灭LED1}
  for(循环3次) {等3秒,点亮LED1,3秒后,灭LED1}
else {
  for(循环3次) {点亮LED1,一秒后,灭LED1}
  for(循环3次) {等3秒,点亮LED2,3秒后,灭LED2}
}
没有写定时程序,自己写吧
回答者: ---------- | 四级 | 2011-9-29 11:19
-------------------------------------------------
这个回答,缺少按键变化时,“即时”更改显示位置的功能,LED 闪烁的也明显不对。
这个回答,在主程序里面,放了这么多的循环!呵呵,这也太占用 CPU 的资源了。
这个回答,可以到原题网址看到原文。

做而论道写的程序,思路和定时时钟、定时的交通灯,基本一致。
在中断函数中,仅仅用下面几行,就进行了按键检测与状态的变换:

//**********************************按键检测与状态的变换
    in_p2 = 8;
    if (P2 == 255)  in_p2 = 0;
    M2_n = 8;
    if (TT_f)  M2_n *= 3;
    if (P2 != Last_p2) {
      Last_p2 = P2;
      n_25ms = M2_n;
      M1_n = 0;
      TT_f = 0;
    }
//**********************************

这些程序,每隔 12.5ms 才执行一遍,执行时,也用不上几十微秒,对系统资源的占用,是很微小的。
这样,主函数,就几乎可用全部的时间,执行各种程序。

做而论道编写的程序,完全没有使用那么多的循环,同样可以满足题目的要求,大家可以自己实验。

上述的程序是如何解释的,这就不好说了,读者的水平参差不齐,有缘者自己领会吧。
;============================================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值