找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机洞洞板心形流水灯制作

[复制链接]
跳转到指定楼层
楼主
本帖最后由 chinayanhui 于 2020-2-23 00:07 编辑

学习单片机的小学生第一次发帖,不足之处还请高人指正。


这期间,实再无聊,在网上看一些电子制作的视频。看了一个群主自己做了一个心形流水灯,效果实再不错,但是看到他写的代码,就是觉得太乱。不成系统,一大堆的数组组织起来的代码,没有注释,看的让人着实不爽。

频中的代码片段:







是不是看得有点晕?

正好家里还有几块洞洞板和LED灯,用了两天时间,加上代码总算是搞定了。旨当给孩子的玩具了,孩子也比较喜欢。

先看一个效果视频:
视频.7z (5.26 MB, 下载次数: 5)

相关图片:















由于手头只有7*9的板子,用了26个LED,光拼这个心形就用了近一个半小时的时间。看似简单,拼起来要考虑线的走向等等问题。



手头还有几只STC98C52RC,占用了P1, P2, P3和ALE(4.5)以及4.6管脚。为啥不用P0脚?因为想起了要接上拉电阻,手头又没有,所以干脆没有用。虽然我的LED是共阳接法。。。其实是为了以后扩展用的


因为是用3节1.5V的电池带动,为了能亮一些,所以限流电阻接了100欧的。


流水灯嘛就是一堆IO口的输出,没啥复杂的,是51单片机初学者的Hello World,复杂之处在于设计led流水灯的算法。笔者因为是从软件转过来的,虽然在PC端有一大堆的内存可以使用,但是学习单片机,面对只有几百之字的内存和几K的存储空间。但是从算法上节约程序空间是笔者的习惯。另外程序看得也明白。主要是不想用一大堆数组,一堆看的头疼的循环加套循环,只想设计几个函数,解决问题。最终编译出来,程序代码686字节,占用内存23.0,我自己还能接受。


还有一些效果有些思路,但是真是没有时间写了,有兴趣的坛友可以在我的思路上完善。因为LED较多,代码中没有使用循环左右移的代码。觉得用unsign long左右移动就足够了。当然程序中也注释了一段笔者参考网上的uint32的循环左右移的代码,供有兴趣的坛友参考。

另外由于不需要精确定时也为了写程序方便,没有使用定时器,仅用了一个软件延时。有兴趣的坛友可以使用定时器试一下哈。

单片机代码如下:
  1. #include "STC89C5xRC.H"

  2. #define int8 char
  3. #define uint8 unsigned char
  4. #define uint16 unsigned short
  5. #define uint32 unsigned long
  6.         
  7. #define FUNJMP        79                // 函数跳转延时
  8. #define TIME         100                // 语句间延时

  9. /**********************************
  10. 函数功能:软件延时
  11. 入口参数:
  12.         count uint16 软件延时的毫秒数

  13. 返    回:无
  14. 备    注:无
  15. **********************************/
  16. void Delay(uint16 count)
  17. {
  18.         uint16 i;
  19.         uint8 j;
  20.         for(i = count; i > 0; i--)
  21.                 for(j = 110; j > 0; j--);
  22. }

  23. /**********************************
  24. 函数功能:全亮闪烁
  25. 入口参数:
  26.         count uint8  闪烁次数
  27.         ms          uint16 闪烁时停留的毫秒数

  28. 返    回:无
  29. 备    注:无
  30. **********************************/
  31. void Flash(uint8 count, uint16 ms)
  32. {
  33.         uint8 i;
  34.         
  35.         for(i = 0; i < count * 2; i++)
  36.         {
  37.                 P1 = ~P1;
  38.                 P2 = ~P2;
  39.                 P3 = ~P3;
  40.                 P4 = ~P4;
  41.                
  42.                 Delay(ms);
  43.         }
  44. }

  45. /**********************************
  46. 函数功能:
  47.         循环移动无符号数

  48. 入口参数:
  49.         uint32 val                待移动的数
  50.         uint8  count        移动的位数

  51. 返    回:移动的结果
  52. 备    注:
  53.         count < 0,左移
  54.         count > 0, 右移
  55. **********************************/
  56. //uint32 CycleShift(uint32 val, int8 count)
  57. //{
  58. //        uint32 temp = 0;
  59. //        
  60. //        if(count == 0)
  61. //                return val;
  62. //        
  63. //        temp |= val;
  64. //        
  65. //        if(count < 0)
  66. //        {
  67. //                val <<= -count;
  68. //                temp >>= (32 + count);
  69. //        }
  70. //        else
  71. //        {
  72. //                val >>= count;
  73. //                temp <<= (32 - count);
  74. //        }
  75. //        
  76. //        return val | temp;
  77. //}

  78. /**********************************
  79. 函数功能:根据参数设定LED的亮灯
  80. 入口参数:
  81.         value uint32 设定led亮灯的数据
  82.         
  83. 返    回:无
  84. 备    注:无
  85. **********************************/
  86. void LED(uint32 value)
  87. {
  88.         P1 = value & 0xFF;
  89.         P3 = (value & 0xFF00) >> 8;
  90.         P2 = (value & 0xFF0000) >> 16;
  91.         P44 = (value & 0x1000000) >> 24;
  92.         P45 = (value & 0x2000000) >> 25;
  93. }

  94. /**********************************
  95. 函数功能:流水灯
  96. 入口参数:
  97.         value uint8        流水灯初值(0.逆时针  1.顺时针)
  98.         isOff uint8 是否关闭流过的灯(1.关闭  0.不关闭)
  99.         
  100. 返    回:无
  101. 备    注:无
  102. **********************************/
  103. void Assembly(uint32 value, uint8 style)
  104. {
  105.         uint8 i;

  106.         for(i = 0; i < 26; i++)
  107.         {
  108.                 LED(value);
  109.                
  110.                 // 第7位为1,则为顺时针,否则为逆时针
  111.                 if((style & 0x80) == 0x80)
  112.                         value <<= 1;
  113.                 else
  114.                         value >>= 1;
  115.                
  116.                 // 第0位为1则为单个流水灯(为0则是亮过的不再熄灭)
  117.                 if((style & 1) == 1)
  118.                         value++;
  119.                
  120.                 // 第1位为1则为顺时针逐个灭灯
  121.                 if((style & 2) == 2)
  122.                         value |= 1;
  123.                
  124.                 // 第5位为1则为逆时针单个灯
  125.                 if((style & 0x10) == 0x10)
  126.                         value |= 0x2000000;
  127.                
  128.                 Delay(TIME);
  129.         }
  130. }

  131. /**********************************
  132. 函数功能:双向流水灯
  133. 入口参数:
  134.         dir uint8 0.双向点亮(从上到下)  1.双向熄灭(从上到下)

  135. 返    回:无
  136. 备    注:无
  137. **********************************/
  138. void Assembly2(uint8 dir)
  139. {
  140.         uint8 i;
  141.         uint16 clockwise;
  142.         uint16 anticlockwise;
  143.         
  144.         Delay(TIME);
  145.         
  146.         clockwise = 0x1FFE;
  147.         anticlockwise = 0x1FFF;
  148.         for(i = 0; i < 14; i++)
  149.         {
  150.                 uint32 temp = anticlockwise;
  151.                 temp = temp << 13;
  152.                 temp = temp | (clockwise & 0x1FFE);
  153.                
  154.                 if(dir)
  155.                         temp = ~temp;
  156.                
  157.                 LED(temp);
  158.                
  159.                 clockwise = clockwise << 1;
  160.                 anticlockwise = anticlockwise >> 1;
  161.                 Delay(TIME);
  162.         }
  163. }

  164. void main()
  165. {
  166.         while(1)
  167.         {
  168.                                 
  169.                 //Delay(FUNJMP);
  170.                
  171.                
  172.                
  173.                 // 全灭的状态下顺时针逐个流水亮灯
  174.                 Assembly(0xFFFFFFFE, 0x81);
  175.                
  176.                 // 全灭的状态下顺时针堆积亮灯
  177.                 Delay(FUNJMP);
  178.                 Assembly(0xFFFFFFFE, 0x80);
  179.                
  180.                 // 全亮状态下顺时针逐个堆积灭灯
  181.                 //P1 = 0xFF;
  182.                 Delay(FUNJMP);
  183.                 Assembly(1, 0x82);
  184.                
  185.                 // 全灭状态下逆时针逐个流水亮灯
  186.                 Delay(FUNJMP);
  187.                 Assembly(0x1FFFFFF, 0x10);
  188.                
  189.                 // 逆时针逐个堆积亮灯
  190.                 Delay(FUNJMP);
  191.                 Assembly(0x1FFFFFF, 0x00);
  192.                
  193.                 // 全亮的状态下逆时针堆积灭灯
  194.                 Delay(FUNJMP);
  195.                 Assembly(0x2000000, 0x10);
  196.                
  197.                 // 两边点亮
  198.                 Delay(FUNJMP);
  199.                 Assembly2(0);
  200.                
  201.                 // 两边收缩
  202.                 Delay(FUNJMP);
  203.                 Assembly2(1);
  204.                
  205.                 // 闪烁
  206.                 Delay(FUNJMP);
  207.                 Flash(3, FUNJMP - 10);
  208.                
  209.                 Delay(3000);
  210.         }
  211. }
复制代码



洞洞板的设计比较简单,为了美观,用了两块洞洞板,一个板子上是共阳的26根LED,另一块板子放单片机,晶振,然后是一堆插针。



洞洞板的设计:










51hei.png (300.03 KB, 下载次数: 52)

51hei.png

3.png (192.21 KB, 下载次数: 39)

3.png

2.png (210.73 KB, 下载次数: 46)

2.png

1.png (436.99 KB, 下载次数: 32)

1.png

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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