这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 8051流水灯,这个实验你用熟了吗?

共9条 1/1 1 跳转至

8051流水灯,这个实验你用熟了吗?

助工
2010-12-08 14:01:15     打赏

单片机初学者几乎都做的一个实验就是流水灯实验,因为大家都做,所以就觉得很简单,很多人对这个实验几乎不屑。其实要彻底的玩转这个实验也是很不简单的事情,不信看看你能不能应付我下面的实验题:
    硬件前提:用51的P1口控制8个LED,1 点亮,0 熄灭。
    (1)第1,3,5,7个灯半亮,其余的全亮。
     (2)第1个亮1/8,第2个亮2/8,第3个亮3/8,第4个亮4/8,第5个亮5/8,第6个亮6/8,第7个亮7/8,第8个全亮。
     (3)来点小难的,所有的灯逐渐从暗到全亮,再由全亮到暗。
     (4)最难的:8个灯从第一个开始依次渐亮,直到最后一个。再从最后一个起渐暗,直到第一个。如此循环往复。这才是真正的流水灯。

理解是:
(1)第1,3,5,7个灯半亮,其余的全亮。
把显示时间分成2个时间段,半亮的灯只在一个时间段内点亮,另一个时间段关闭
(2)第1个亮1/8,第2个亮2/8,第3个亮3/8,第4个亮4/8,第5个亮5/8,第6个亮6/8,第7个亮7/8,第8个全亮。
和第一个类似,只是分成了8个时间段,当然8个时间段加起来的时间最好小于20MS(满足刷新率大于50HZ)
(3)来点小难的,所有的灯逐渐从暗到全亮,再由全亮到暗。
这个可以按照第二个例子来延伸一下,分成8个时间段,如果要明显一点可以多分几个时间段,所有灯同时工作就相当于一个LED一样。
(4)最难的:8个灯从第一个开始依次渐亮,直到最后一个。再从最后一个起渐暗,直到第一个。如此循环往复。这才是真正的流水灯。




关键词: 流水     这个     实验     你用     熟了    

助工
2010-12-08 14:12:30     打赏
2楼
有兴趣的可以编写一下这几个程序,

工程师
2010-12-08 14:31:16     打赏
3楼

高工
2010-12-10 10:26:21     打赏
4楼

第一题参考程序:
#include <AT89X52.H>  //头文件
#include "Led.h"
#include "timer0.h"
#include "mytype.h"
#include "config.h"

uint8 counter=0;

void main(void)
{
     InitTimer0();
         EA=1;
         while(1)
         {
              OnLed2();  OnLed4();  OnLed6();  OnLed8();//点亮LED2 LED4 LED6 LED8
         }

}
/********************************************************************
函数功能:定时器0中断处理。
入口参数:无。
返    回:无。
备    注:22.1184M晶体约5ms中断一次。
********************************************************************/
void Timer0Isr(void) interrupt 1
{
         TH0=(65536-Fclk/1000/12*5)/256;        
         TL0=(65536-Fclk/1000/12*5)%256;   //
         counter++;
 
         if(counter%2==0)
         {
             OnLed1();  OnLed3();  OnLed5();  OnLed7();             //点亮LED1 LED3 LED5 LED7
         }
         else
         {
             OffLed1();  OffLed3();  OffLed5();  OffLed7();         //关闭LED1 LED3 LED5 LED7
         }

}

 


高工
2010-12-10 10:40:17     打赏
5楼

第二题参考程序:
#include <AT89X52.H>  //头文件
#include "Led.h"
#include "timer0.h"
#include "mytype.h"
#include "config.h"

uint8 counter=0;

void main(void)
{
     InitTimer0();
         EA=1;
         while(1)
         {
         }

}
/********************************************************************
函数功能:定时器0中断处理。
入口参数:无。
返    回:无。
备    注:22.1184M晶体约2ms中断一次。
********************************************************************/
void Timer0Isr(void) interrupt 1
{
         TH0=(65536-Fclk/1000/12*2)/256;        
         TL0=(65536-Fclk/1000/12*2)%256;   //
         counter++;
           switch(counter%8)
         {
              case 0:       LEDs=0x00;        break;
              case 1:       LEDs=0x01;        break;
              case 2:       LEDs=0x03;        break;
              case 3:       LEDs=0x07;        break;
              case 4:       LEDs=0x0f;        break;
              case 5:       LEDs=0x1f;        break;
              case 6:       LEDs=0x3f;        break;
              case 7:       LEDs=0x7f;        break;
         }
}

 


高工
2010-12-10 10:41:26     打赏
6楼

第三题参考程序:
#include <AT89X52.H>  //头文件
#include "Led.h"
#include "timer0.h"
#include "mytype.h"
#include "config.h"         

uint16 counter=0;
uint16 duty_cnt=0;
uint16 period_cnt=400;
uint8 dir_flag=0;
void main(void)
{
     InitTimer0();
         EA=1;
         while(1)
         {
         }

}
/********************************************************************
函数功能:定时器0中断处理。
入口参数:无。
返    回:无。
备    注:22.1184M晶体约4us中断一次。
********************************************************************/
void Timer0Isr(void) interrupt 1
{
         TH0=(65536-Fclk/1000/1000/12*4)/256;        
         TL0=(65536-Fclk/1000/1000/12*4)%256;   //
         counter++;
         if(counter<duty_cnt)
              LEDs=0x00;
         else if(counter<period_cnt)
              LEDs=0xff;
         else
              {
                       counter=0;
                           if(!dir_flag)     duty_cnt++;
                           else                duty_cnt--;
                           if(duty_cnt==period_cnt) dir_flag=1;
                           if(duty_cnt==10)   dir_flag=0;
                  }   
         }

}

 


高工
2010-12-10 10:42:37     打赏
7楼


第四题参考程序:
#include <AT89X52.H>  //头文件
#include "Led.h"
#include "timer0.h"
#include "mytype.h"
#include "config.h"         

uint16 counter=0;
uint16 counter1=0;
uint16 duty_cnt=0;
uint16 period_cnt=400;
uint8 dir_flag=0;
uint8  LED_value=0xff;
void main(void)
{
     InitTimer0();
         EA=1;
         while(1)
         {
         }

}
/********************************************************************
函数功能:定时器0中断处理。
入口参数:无。
返    回:无。
备    注:22.1184M晶体约4us中断一次。
********************************************************************/
void Timer0Isr(void) interrupt 1
{
         TH0=(65536-Fclk/1000/1000/12*5)/256;        
         TL0=(65536-Fclk/1000/1000/12*5)%256;   //
         counter++;
         if(counter<duty_cnt)
              LEDs=LED_value;
         else if(counter<=300)                    
                  LEDs=((LED_value>>1)|0x80);
         else
              {
                       counter=0;

                           if(!dir_flag)
                           {
                               duty_cnt++;
                                   if(duty_cnt==301)
                                   {
                                       duty_cnt=1;
                                           LED_value<<=1;
                                           counter1++;
                                           if(counter1==9)
                                           {
                                               counter1=0;
                                                   dir_flag=1;
                                                   duty_cnt=300;
                                           }
                                   }
                           }
                           else
                           {
                               duty_cnt--;
                                   if(duty_cnt==0)
                                   {
                                       duty_cnt=300;
                                           LED_value>>=1;
                                           LED_value|=0x80;
                                           counter1++;
                                           if(counter1==9)
                                           {
                                               counter1=0;
                                                   dir_flag=0;
                                                   duty_cnt=1;
                                           }
                                   }
                           }
           }
}


高工
2010-12-10 10:46:35     打赏
8楼

有兴趣的可以试试这几个简单程序,做到举一反三


菜鸟
2010-12-13 14:40:16     打赏
9楼

好怀念……


共9条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]