找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机16led心形灯闪烁程序

[复制链接]
跳转到指定楼层
楼主
ID:619899 发表于 2021-12-19 14:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
控制要求:                                                      
    1. 用16盏小灯实现灯光变换,若有需要可另添加;              
    2.可以用输入按钮在几种灯光效果间切换;                     
    3. 可以通过暂停按钮暂停彩灯效果,使小灯全亮,再按下后继续之前效果;                                                                                                            
    4.自动、手动两种模式,并通过按钮可以在这两个模式之间切换。模式说明:顺时针逐一点亮、逆时针逐一点亮、奇偶交替点亮闪烁、顺时针逐一点亮、顺时针逐一熄灭、逆时针逐一点亮、逆时针逐一熄灭 、对角顺序点亮、对角倒序点亮、二进制加法点亮。                                                                                                                                                                                                           
    设计要求:                                                  
    本设计由16个发光二极管组成灯光电路,并且呈现心形样式,设计其中工作模式不少五种并由定时中断控制自由变化,并显示第几种灯光效果。

硬件电路设计

LED灯显示模块(如图2-1)

图3-1LED灯显示模块

类型显示模块(如图2-2)

图3-2类型显示模块


按键显示模块(如图2-3)

图3-3按键显示模块


时钟控制模块(如图2-4)

图3-4时钟控制模块


总体电路(如图2-5)

图3-5总体电路


4软件设计4.1软件设计思路

流水灯采用的是发光二极管(Light-Emitting Diode),简称LED,是一种将电能转换为光能的半导体器件,具有体积小、耗电低的优点,常被用作微型计算机与数字电路的输出装置。当LED两端加上一定的正向电压,使之流过一定的工作电流就会发光,其亮度随流过的电流增加而增加,但电流过大LED的寿命也将缩短。普通LED正向电流一般为5~20mA。由于51的I/0是弱上拉的方式,在输出高电平时,只能输出几十微安的电流,而在输出低电平时,I/0最大可以输入几十毫安的电流。所以,通常采用灌电流的方式,即电流从电源经LED流向I/0口。为了不让流过LED的电流太大而把它烧坏,还得串上限流电阻R,当P0和P2口输出高电平(+5V)时,LED两端没有电压降,所以熄灭:当P0和P2口输出低电平(即P0/P2=0)时,LED正向导通发光。此时LED两端电压VD约为1.7V.则限流电阻R两端将存在3.3V(即5-1.7=3.3V)。查阅AT89C5l技术手册后发现,单个I/0口的输入电流不能超过10mA:P0口的输入电流总和不能超过26mA;P1、P2、P3的输入电流总和不能超过15mA;所有I/0口的输入电流总和不能超过71mA。                                             

4.2软件设计流程

灯光控制设计:

  • 用16盏小灯实现灯光变换,若有需要可另添加。
  • 可以用输入按钮在几种灯光效果间切换。
  • 可以通过暂停按钮暂停彩灯效果,使小灯全亮,再次按下后继续之前效果。
  • 自动、手动两种模式,并通过按钮可以在这两个模式之间切换。
  • 至少有九种灯光模式,闪烁时显示种类。

主程序框图

图4-1

4.3软件程序

#include <reg51.h>
#define false 0
#define true 1
#define uchar unsigned char
#define uint unsigned int
sbit pause_key=P3^0;
sbit auto_key= P3^1;
sbit change_key=P3^2;
sbit pauseLed=P3^6;
sbit autoLed = P3^7;
uint ledCode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uint ledCode2[8]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};
void displayLed (void);
void keyScan(void);
void Delay10ms(unsigned int n);
bit isPause = false;
bit isAuto  = true;
bit isChange= false;
uchar time;
uchar a,flag,types;
uint counts;
//函数名称:定时中断函数
//函数功能:在时间判定后,更新数码管显示
void T0_INT(void) interrupt 1
{
TL0=(65536-50000)/256;
TH0=(65536-50000)%256;
time ++;
if (time>=10)
              {
                            time=0;
if(isChange==true)
    {
                        counts=0;
            types++;
if(types>9)types=0;
P0=disCode[types];
isChange=false;
    }
displayLed();
counts ++;
}
}
void main(void)
{
//函数名称:主函数
TMOD=0x61;//0110 0001//方式一
TL0=(65536-50000)/256;//50ms
TH0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
time=0;
counts=0;
types=0;
pauseLed=0;
P0=disCode[types];
while(1)
{
              keyScan();
}
}
函数名称:displayLed
函数功能:LED灯的显示,共有十种变化,分别为顺时针逐一点亮、逆时针逐一点亮、奇偶交替点亮闪烁、顺时针逐一点亮、顺时针逐一熄灭、逆时针逐一点亮、逆时针逐一熄灭 、对角顺序点亮、对角倒序点亮、二进制加法点亮。                                                                                                                                 
void displayLed(void)
{
switch(types)
{
   case 0:
   {
   if(counts>=16)counts=0;
     if(counts>=15)
      {
        if(isAuto==true) isChange=true;
      }
if(counts <8)
{
P1=0xff;
P2=ledCode[7-counts];
}
else
{
P1=ledCode[15-counts];
P2=0xff;
}
break;
}
case 1:
{
if(counts >=16)counts=0;
if(counts >=15)
if(isAuto==true)isChange=true;
}
if(counts<8)
{
P1=ledCode[counts];
P2=0xff;
}
else
{
P1=0xff;
              P2=ledCode[counts-8];
}
break;
case 2:
{
if(counts>=16)counts=0;
if(counts>=15)
              {
if(isAuto==true) isChange=true;
}
if(counts%2==0)
{
P1=0xaa;
P2=0xaa;
}
else
{
P1=0x55;
P2=0x55;
}
break;
case 3:
{
if (counts>=17) counts=0;
if(counts<8)
{
P1=~ledCode2[7-counts];
              P2=0xff;
}
else if(counts <16)
{
P1=0x00;
P2=~ledCode2[15-counts];
}
else//全亮
{
P1=0x00;
P2=0x00;
if(isAuto==true)isChange=true;
}
break;
}
case 4:
{
if(counts>=17)counts=0;
if(counts<8)
{
P1=ledCode2[7-counts];
              P2=0x00;
}
else if(counts<16)
{
P1=0xff;
P2=ledCode2[15-counts];
}
else//全灭
{
P1=0xff;
P2=0xff;
if(isAuto==true) isChange=true;
}
break;
}
case 5:
{
if(counts>=17)counts=0;
if(counts <8)
{
P1=0xff;
P2=ledCode2[counts];}
else if(counts<16)
{
P1= ledCode2[counts-7];
P2=0x00;
}
else
{
P1=0x00;
P2=0x00;
if(isAuto==true)isChange=true;
}
break;}
case 6:
{
if(counts>=17)counts=0;
if(counts<8)
{
P1=0x00;
P2=~ledCode2[counts];
}
else if(counts <16)
{
P1=~ledCode2[counts-7];
              P2=0xff;
}
else
{
P1=0xff;
P2=0xff;
if(isAuto==true) isChange=true;
}
break;
}
case 7:
{
if(counts>=8)counts=0;
if(counts>=7){
if(isAuto==true)isChange=true;}
P1=ledCode[7-counts];
P2=ledCode[7-counts];
break;
}
case 8:
{
if(counts>=8)counts=0;
if(counts>=7)
{
if(isAuto==true)isChange=true;
}
P1=ledCode[counts];
P2=ledCode[counts];
break;
}
case 9:
{
if(counts>=255)counts=0;
if(counts==254&& isAuto==true)isChange=true;
P1=~counts;
P2=~counts;
break;
}
default:types=0;
P0=disCode[types];
}
}
}
void Delay10ms(uint n)
{
uchar a, b;
for(;n>0;n--)
{
for(b=38;b>0;b--)
{
for(a=130;a>0;a--);
}
}
}

5电路仿真调试

      

5-1  灯光控制设计

5-2  灯光控制设计仿真图


结论

1、对于该设计是以AT-89C51单片机为主控芯片,通过程序控制彩灯流水花样。本文所给程序实现的功能比较简单,旨在抛砖引玉,可以在此基础上扩展成更复杂的彩灯控制,比如键盘控制流水花样、控制流水灯显示数字或图案等等。通过花样彩灯的制作,给我最大的体会是对一个程序整体的把握和控制,只有将子程序有效的结合起来,才能完成设计的目的。另外,在程序的调试过程中,我也遇到了很多意想不到的困难


本人初学,仅供参考,存在错误和不足之处,请大家回帖多多指教,切勿照搬
以上图文的Word格式文档下载(内容和本网页上的一模一样,方便大家保存,切勿照搬):
灯光控制设计.docx (255.76 KB, 下载次数: 11)

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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