找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的心形灯的设计详细资料 含程序电路解释

[复制链接]
跳转到指定楼层
楼主
ID:654471 发表于 2020-2-21 16:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是我花了两个星期的时间完成的心形灯的实验设计,
相信需要的师兄会满意的,里面包括了仿真和源码

此次设计基于单片机技术与单片机芯片AT89C51芯片功能和c语言程序,实现心形流水灯的四种模式切换和四种速度的切换。利用中断实现开始模块的功能和暂停键的功能,在延时函数中实现了速度切换。了解了单片机的一些技术,单片机芯片AT89C51的一些功能,然后结合c语言编程,最后将它们运用到实际的电路,使心形流水灯LED灯实现多种亮灭方法。

概要设计
2.1设计目标

设计一个心形灯,包含以下功能:

1、由多个LED灯组成心形灯,要求至少在32个灯以上组成心形结构,外接4个按键,并要求两个按键(开始和暂停)接在两个外部中断引脚上;

2、上电后心形灯先全亮5秒,后亮灭闪烁5秒,以测试灯状态的好坏;

3、之后处于全灭等待状态,当按下开始按键后心形灯按照一定规律显示,规律自定义,创意越好分数越高;

4、当在任意状态下按下暂停键后心形灯停留在当前状态不再改变,再一次按下暂停键后则继续显示;

5、另外一个键为模式切换键,要求至少设计4中心形灯显示模式,每按一次切换键则切换一次显示模式,要求切换键在灯运行状态和暂停状态均可切换;

6、第四个键为速度键,要求可以改变心形灯的亮灭切换速度,至少设计4种速度,通过速度键可以切换不同的切换速度。

2.2设计框图

                                 2-1 设计框图

2.2各功能块的功能和作用

2.2.1闪烁模块

让灯先全亮五秒,再闪烁亮五秒,然后全灭。

2.2.2 中断初始化模块

开始按键和暂停按键用到了中断,并且设置暂停键的优先级要高于开始按键的优先级。并且把开始键按下之后的自己设计的心形灯闪烁的模式也写在中断初始化模块中。

2.2.3 速度切换模块

用按键控制,如果检测到按键按下就进行速度的切换。

2.2.4 模式切换模块

用按键控制,如果检测到按键按下就进行模式的切换,总共有四种模式。

2.2.5 暂停模块

在按键中断中,如果检测到按键按下,会对已经定义的标志位进行改变,然后作用在延时函数中,就会产生一个死循环,相当于产生中断。再次按下时,标志位会再次改变,从而退出死循环,继续执行。


第三章                 系统硬件设计3.1 C51单片机芯片
  • 置4组8位I/O口,其中P0口为双向I/O口,P1,P2,P3为准双向I/O口。
  • 内置2个16位定时器/计数器。
  • 内置外部中断2 路,下降沿中断或低电平触发中断,Power Down 模式可由外部中断低电平触发中断方式唤醒。
  • 内置通用异步串行口。
  • 工作电压为5V。
  • 工作温度为0℃~70℃。
图3-2  STC89C51RC引脚图
引脚说明:
I/O口:P0、P1、P2、P3四组I/O口,P0口为三态双向I/O口,没有内置的上拉电阻,需要外接上拉电阻;P1、P2、P3为准双向I/O口;所有I/O口均可独立编程使用。
VCC、GND:单片机电源引脚,常电压为+5V;
XTAL1、XTAL2:外接时钟引脚,XTAL1为输入端,XTAL2为输出端。
RST:单片机的复位引脚,连续两个机器周期以上的高电平为有效。
RXD、TXD:串行输入输出口。
INT0、INT1:外部中断0,外部中断1。
T0、T1:定时器\计数器0外部输入端、定时器\计数器0外部输入端。
PSEN:程序储存器允许输出控制端。
ALE/PROG:外部储存器锁存端。
EA/VPP:外部储存器控制端。
3.2.复位设计和时钟设计部分
图3-3时钟和复位

此中控电路叫做C51单片机的最小系统,作用是为单片机提供适合的外部工作条件。U1为STM89C51RC,即为电子表的主控芯片。左上角接在RST引脚的电路为复位按键电路,由一个按键、一个0.1μF电容和一个10Ω电阻组成。电容作用是消除按键抖动。按下按键即可为单片机提供连续两个机器周期的高电平,以供单片机复位。左下角接在XTAL两个引脚的是晶振电路,由一个晶振、两个起振电容构成。以晶振的固定频率震荡以输出固定频率的脉冲信号,为单片机提供机器周期,同时提供时间基准。左上角为P0 I/O口的上拉电阻。使其能稳定输出高低电平。

3.3按键交互

按键交互部分由四个独立按键构成,四个独立按键一端接地,另一端口链接单片机上的四个I/O口,当单片机检测到其中的I/O口为低电平时,将会触发按键功能。
按键功能简述:
R36连接按键:模式切换

R37连接按键:速度切换

R34连接按键:开始键
R35连接按键:暂停键

3.4心形灯的设计

图3-2心形灯

采用的是共阳极,每个灯的引脚送低电平时,灯亮;送高电平时,灯灭。



第四章                 系统软件设计
4.1软件设计流程图



4-1主程序流程图



4.2关键代码
延时函数
(速度切换和模式切换都在延时函数中进行切换)
void delay(uint n)              //延时
{
              uint i,j;
              if(P35==0)//速度切换
              {
                            time2++;
                            if(time2%4==0)
                            s1=200;
                            if(time2%4==1)
                            s1=500;
                            if(time2%4==2)
                            s1=700;
                            if(time2%4==3)
                            s1=1000;
              }
              for(i=0;i<n;i++)
              for(j=0;j<121;j++);
              if(P34==0)//模式切换
              {                                                                                   
                                          while(1)
                                          {
                                                        time1++;
                                                        moshiqiehuan();
                                          }                           
              }
              while(flag==1);            
}
因为灯每亮或者灭一次,都要调用延时函数,所以我们进行模式切换和速度切换都可以在延时函数中实现。

开始模块:
void D_INT0(void) interrupt 0 using 0  //开始键,设置一种波形,先亮左半边,再亮右半边
{
              uint i;
            
            
              while(1)
              {
                            P2=0x7f;
                            for(i=0;i<8;i++)
                            {
                                          P2=P2>>1;
                                          delay(500);            
                            }
                            P0=0xfe;
                            for(i=0;i<8;i++)
                            {
                                          P0=P0<<1;
                                          delay(500);            
                            }
                            P1=0xfe;
                            for(i=0;i<8;i++)
                            {
                                          P1=P1<<1;
                                          delay(500);            
                            }
                            P0=P1=P2=0XFF;//全部亮一遍之后再循环点亮            
              }
}
利用外部中断0实现了开始模块的功能。

暂停功能:
void D_INT1() interrupt 2 using 2  //控制暂停
{
                time++;
                if(time%2==1)  //time如果是奇数,说明暂停;偶数的话,则是再开始。
                {
                                            flag=1;

                }
                else
                flag=0;
}
产生一个标志位,让这个标志位作用在延时函数中,产生中断。


第五章                 系统仿真设计
                         图5-1 心形灯
p3口没有接灯,灯的一端接电源,另一端接芯片的接口。

                        5-2 引脚及开关
时钟复位电路,以及四个开关,分别控制着开始、暂停、速度切换和模式切换。


第六章                 总结

当时看到这个的时候,感觉无从下手,当我静下心来,思考如何一步步实现这个功能,首先应该把电路图画出来,以及元器件的连接。那天晚上,我先把电路图画出来,然后编写代码实现了开始亮五秒,亮灭闪烁五秒这个功能,纵观整个的设计过程,经常出现这样那样的困难,比如电路图画错、编程出现错误、软件不会使用,在这期间着实费了我不少时间,但是我还是努力认真的去学习检查和修改。虽然这个过程非常艰难,但还是值得我回味的。在整个设计过程,我查阅了大量地相关书籍和文献资料,从中学习了一些单片机的工作原理以及怎样去设计一个电子电路。通过这次设计,我不仅加深了对以前学过课本知识得以理解和应用,并且对于其在电路中的使用有了更多的认识。通过这次自主学习,我学会了很多的道理,当我们遇见一个很棘手的问题时,先不要慌,要静下心来,思考应该如何一步步实现,胆怯和畏惧时解决不了问题的。这次的功能的实现,给了我很大的信心,只要努力去做,没有完不成的事情。


  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #include<absacc.h>
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. void quanliang(); //全亮
  7. void quanmie();              //全灭
  8. void delay(uint); //延时
  9. void chushiliang(); //实现初始时亮五秒,闪烁五秒的功能
  10. void init();//初始化中断
  11. void moshi1(); //四种模式
  12. void moshi2();
  13. void moshi3();
  14. void moshi4();
  15. void moshiqiehuan();//模式切换
  16. void suduqiehuan() ;
  17. uint time=0;//定义暂停按键按下的次数
  18. uint time1=-1;//定义模式切换按键按下的次数
  19. uint time2=-1;//定义速度切换按键按下的次数
  20. uint s1;
  21. uint flag;
  22. sbit P34=P3^4;
  23. sbit P35=P3^5;
  24. sbit P33=P3^3;
  25. void main()
  26. {
  27.               chushiliang();//初始时亮五秒,闪烁五秒
  28.               init();//中断初始化
  29.               while(1); //等待中断

  30. }

  31. void chushiliang()  //初始时亮五秒,闪烁五秒
  32. {
  33.               quanliang();
  34.               delay(5000);
  35. //下面是闪烁5秒                           
  36.               quanmie();            
  37.               delay(500);
  38.               quanliang();
  39.               delay(500);
  40.               quanmie();
  41.               delay(500);
  42.               quanliang();
  43.               delay(500);
  44.               quanmie();
  45. }
  46. void delay(uint n)              //延时
  47. {
  48.               uint i,j;
  49.               if(P35==0)
  50.               {
  51.                             time2++;
  52.                             if(time2%4==0)
  53.                             s1=200;
  54.                             if(time2%4==1)
  55.                             s1=500;
  56.                             if(time2%4==2)
  57.                             s1=700;
  58.                             if(time2%4==3)
  59.                             s1=1000;
  60.               }
  61.               for(i=0;i<n;i++)
  62.               for(j=0;j<121;j++);
  63.               if(P34==0)
  64.               {                                                                                   
  65.                                           while(1)
  66.                                           {
  67.                                                         time1++;
  68.                                                         moshiqiehuan();
  69.                                           }                           
  70.               }
  71.               while(flag==1);            
  72. }
  73. void quanliang() //全亮
  74. {
  75.               P0=P1=P2=0x00;
  76. }
  77. void quanmie() //全灭
  78. {
  79.               P0=P1=P2=0xFF;            
  80. }
  81. void init()
  82. {
  83.               IT0=1;
  84.               EA=1;
  85.               EX0=1;
  86.               EX1=1;
  87.               IT1=1;
  88.               IP=0x04;//外部中断1的优先级高与外部中断零
  89. }
  90. void D_INT0(void) interrupt 0 using 0  //开始键,设置一种波形,先亮左半边,再亮右半边
  91. {
  92.               uint i;
  93.             
  94.             
  95.               while(1)
  96.               {
  97.                             P2=0x7f;
  98.                             for(i=0;i<8;i++)
  99.                             {
  100.                                           P2=P2>>1;
  101.                                           delay(500);            
  102.                             }
  103.                             P0=0xfe;
  104.                             for(i=0;i<8;i++)
  105.                             {
  106.                                           P0=P0<<1;
  107.                                           delay(500);            
  108.                             }
  109.                             P1=0xfe;
  110.                             for(i=0;i<8;i++)
  111.                             {
  112.                                           P1=P1<<1;
  113.                                           delay(500);            
  114.                             }
  115.                             P0=P1=P2=0XFF;//全部亮一遍之后再循环点亮            
  116.               }
  117. }
  118. void D_INT1() interrupt 2 using 2  //控制暂停
  119. {
  120.                 time++;
  121.                 if(time%2==1)  //time如果是奇数,说明暂停;偶数的话,则是再开始。
  122.                 {
  123.                                             flag=1;

  124.                 }
  125.                 else
  126.                 flag=0;
  127. }
  128. void moshiqiehuan()                 //模式切换
  129. {
  130.               uint i;
  131.               i=time1%4;//四种模式切换
  132.               if(i==0)
  133.               moshi1();
  134.               if(i==1)
  135.               moshi2();
  136.               if(i==2)
  137.               moshi3();
  138.               if(i==3)
  139.               moshi4();
  140.             
  141. }

  142. void moshi1()              //心形的右半边中间开始向两边亮
  143. {
  144.               uint i;
  145.               do
  146.               {
  147.               P0=P1=P2=0XFF;//全部亮一遍之后灭
  148.               P0=0x7f;
  149.               P1=0xfe;
  150.               for(i=0;i<8;i++)
  151.               {
  152.                             P0=P0>>1;
  153.                             P1=P1<<1;
  154.                             delay(s1);            
  155.               }            
  156.               P1=0xfe;
  157.               }while(1);            
  158. }

  159. void moshi2()              //顺时针循环亮
  160. {
  161.               uint i;
  162.               do
  163.               {
  164.               P0=P1=P2=0XFF;//全部亮一遍之后灭
  165.               P0=0xfe;
  166.               for(i=0;i<8;i++)
  167.               {
  168.                             P0=_crol_(P0,1);
  169.                             delay(s1);            
  170.               }
  171.               P1=0xfe;
  172.               for(i=0;i<8;i++)
  173.               {
  174.                             P1=_crol_(P1,1);
  175.                             delay(s1);            
  176.               }
  177.               P2=0xfe;
  178.               for(i=0;i<8;i++)
  179.               {
  180.                             P2=_crol_(P2,1);
  181.                             delay(s1);            
  182.               }
  183.               }while(1);            
  184. }

  185. void moshi3()              //顺时针一个一个亮,使所有的灯都亮
  186. {
  187.               uint i;
  188.               do
  189.               {
  190.               P0=P1=P2=0XFF;//全部亮一遍之后再循环点亮
  191.               P0=0xfe;
  192.               for(i=0;i<8;i++)
  193.               {
  194.                             P0=P0<<1;
  195.                             delay(s1);            
  196.               }
  197.               P1=0xfe;
  198.               for(i=0;i<8;i++)
  199.               {
  200.                             P1=P1<<1;
  201.                             delay(s1);            
  202.               }
  203.               P2=0xfe;
  204.               for(i=0;i<8;i++)
  205.               {
  206.                             P2=P2<<1;
  207.                             delay(s1);            
  208.               }
  209.               }while(1);            
  210. }
  211. void moshi4()              //从心形的最底部,两边同时开始向上亮
  212. {
  213.               uint i;
  214.               do
  215.               {
  216.               P0=P1=P2=0XFF;//全部亮一遍之后再循环点亮
  217.               P1=0x7f;
  218.               P2=0xfe;
  219.               for(i=0;i<8;i++)
  220.               {
  221.                             P1=P1>>1;
  222.                             P2=P2<<1;
  223.                             delay(s1);            
  224.               }
  225.               P0=0x7f;
  226.               for(i=0;i<8;i++)
  227.               {
  228.                             P0=0x7f;
  229.                             delay(s1);            
  230.               }
  231.               }while(1);            
  232. }
复制代码

全部资料51hei下载地址:
单片机自主学习-心形灯的设计.7z (435.47 KB, 下载次数: 28)



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

使用道具 举报

沙发
ID:760854 发表于 2020-5-27 15:03 | 只看该作者
我想问一下最后的时钟模块是不需要了吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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