找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机圆形led灯流水灯,自己做来玩的(附代码、pcb、原理图)

  [复制链接]
跳转到指定楼层
楼主
我用了一个20脚的芯片,用16个io口扫描60个led灯,
6个com,10个seg,等于是数码管扫描的原理。

可以切换全灭-->计时模式-->流水灯模式
流水灯模式是递增全亮然后递减全灭
我做的板子很小没有做按键,可以自行修改加上按键。

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


制作出来的实物图在本文最后

代码部分:
  1. #include "单片机头文件"//自行修改
  2. #include <string.h>


  3. typedef unsigned char u8;
  4. typedef unsigned int u16;


  5. //IO口宏定义,根据自己用的单片机来修改
  6. //6个com口,10个seg口,共16个IO口控制60个led灯
  7. #define        COM0        RB0
  8. #define        COM1        RB1
  9. #define        COM2        RB2
  10. #define        COM3        RB3
  11. #define        COM4        RB4
  12. #define        COM5        RB5
  13. #define        COM_ALL(x)        (COM0 = COM1 = COM2 = COM3 = COM4 = COM5 = x)

  14. #define        LED0        RB6
  15. #define        LED1        RB7
  16. #define        LED2        RA0
  17. #define        LED3        RA1
  18. #define        LED4        RA2
  19. #define        LED5        RA3
  20. #define        LED6        RA4
  21. #define        LED7        RA7
  22. #define        LED8        RD0
  23. #define        LED9        RD1
  24. #define        LED_ALL(x)        (LED0 = LED1 = LED2 = LED3 = LED4 = LED5 = LED6 = LED7 = LED8 = LED9 = x)

  25. #define        KEY_IO        (RD6)


  26. void Kscan();
  27. void Off_Clr();
  28. void Led_Mode();


  29. //全局变量
  30. bit        B_MainLoop = 0;
  31. u16 Led_Bit[6] = {0};
  32. u16 Count_500ms = 0;
  33. u8 Status = 0;
  34. u8 d_m = 0;
  35. u8 d_n = 0;
  36. bit Change_Flag = 0;
  37. u8 Minute = 0;
  38. u16 Minute_Bit[6] = {0};
  39. u8 Move_Bit = 0;



  40. /***********************************************************
  41. 中断服务函数
  42. ***********************************************************/
  43. void 中断服务函数()//自行修改,我设置的中断时间为62.5us
  44. {//62.5us
  45.         static u8 Dig_Count = 0;
  46.         static u8 n = 0;
  47.         static u16 m = 0x200;
  48.         static u16 Get_Bit = 0;
  49.         static u8 MainTime = 0;
  50.         
  51.         //有些定时器不是判断标志位,而是重装载值的,根据自己使用的单片机手册来写
  52.         if(标志位)
  53.         {
  54.                 标志位 = 0;
  55.                 if(++MainTime >= 32)        //25
  56.                 {//主循环:125us*32=4ms
  57.                         MainTime = 0;
  58.                         B_MainLoop = 1;
  59.                 }
  60.                
  61.                 Count_500ms++;
  62.                 //led灯扫描
  63.                 Dig_Count++;
  64.                 if(Dig_Count >= 2)
  65.                 {
  66.                         Dig_Count = 0;
  67.                         LED_ALL(0);
  68.                         
  69.                         
  70.                         if(Led_Bit[0] & m)        {COM0 = 0;}
  71.                         else                                {COM0 = 1;}
  72.                         if(Led_Bit[1] & m)        {COM1 = 0;}
  73.                         else                                {COM1 = 1;}
  74.                         if(Led_Bit[2] & m)        {COM2 = 0;}
  75.                         else                                {COM2 = 1;}
  76.                         if(Led_Bit[3] & m)        {COM3 = 0;}
  77.                         else                                {COM3 = 1;}
  78.                         if(Led_Bit[4] & m)        {COM4 = 0;}
  79.                         else                                {COM4 = 1;}
  80.                         if(Led_Bit[5] & m)        {COM5 = 0;}
  81.                         else                                {COM5 = 1;}
  82.                         
  83.                         switch(n++)
  84.                         {
  85.                                 case 0:
  86.                                                 LED0 = 1;
  87.                                                 m = 0x100;
  88.                                                 break;
  89.                                 case 1:
  90.                                                 LED1 = 1;
  91.                                                 m = 0x80;
  92.                                                 break;
  93.                                 case 2:
  94.                                                 LED2 = 1;
  95.                                                 m = 0x40;
  96.                                                 break;
  97.                                 case 3:
  98.                                                 LED3 = 1;
  99.                                                 m = 0x20;
  100.                                                 break;
  101.                                 case 4:
  102.                                                 LED4 = 1;
  103.                                                 m = 0x10;
  104.                                                 break;
  105.                                 case 5:
  106.                                                 LED5 = 1;
  107.                                                 m = 0x8;
  108.                                                 break;
  109.                                 case 6:
  110.                                                 LED6 = 1;
  111.                                                 m = 0x4;
  112.                                                 break;
  113.                                 case 7:
  114.                                                 LED7 = 1;
  115.                                                 m = 0x2;
  116.                                                 break;
  117.                                 case 8:
  118.                                                 LED8 = 1;
  119.                                                 m = 0x1;
  120.                                                 break;
  121.                                 case 9:
  122.                                                 LED9 = 1;
  123.                                                 m = 0x200;
  124.                                                 break;
  125.                                 case 10:n = 0;break;
  126.                         }                                
  127.                         
  128.                 }
  129.         }
  130. }



  131. void Kscan()
  132. {
  133.         static unsigned char Count = 0;
  134.         static volatile bit Key_Task_Flag = 0;//松开标志位
  135.         
  136.         
  137.         if(!KEY_IO)//按键按下
  138.         {
  139.                 if(!Key_Task_Flag)//当前松开,则判断按键
  140.                 {
  141.                         Count++;
  142.                         if(Count >= 3)//消抖次数3
  143.                         {
  144.                                 Count = 0;
  145.                                 Key_Task_Flag = 1;//松开标志位
  146.                                 //按下执行:
  147.                                 Status++;//切换显示模式
  148.                                 if(Status > 2)
  149.                                 {Status = 0;}
  150.                         }
  151.                 }
  152.         }
  153.         else
  154.         {//按键抖动或松开,计数清零,松开标志位清零
  155.                 Count = 0;
  156.                 Key_Task_Flag = 0;//松开标志位
  157.         }
  158.                
  159.         
  160. }



  161. /***********************************************************
  162. 主循环
  163. ***********************************************************/
  164. void main()
  165. {
  166.         Status = 0;//灯模式
  167.         while(1)
  168.         {
  169.                 asm("clrwdt");
  170.                 if(B_MainLoop)
  171.                 {//4ms
  172.                         B_MainLoop = 0;
  173.                         Kscan();
  174.                         Led_Mode();
  175.                 }
  176.                
  177.         }
  178. }


  179. void Off_Clr()
  180. {//关机清理
  181.         memset(Led_Bit,0,sizeof(Led_Bit));
  182.         d_m = 0;d_n = 0;
  183.         Change_Flag = 0;
  184.         Minute = 0;
  185.         Count_500ms = 0;
  186.         memset(Minute_Bit,0,sizeof(Minute_Bit));
  187.         Move_Bit = 0;
  188. }


  189. void Led_Mode()
  190. {
  191.         static volatile u8 i = 0;
  192.         static volatile u8 n = 0;
  193.         switch(Status)
  194.         {
  195.                 case 0://关机模式
  196.                                 Off_Clr();
  197.                                 n = i = 0;
  198.                                 break;
  199.                 case 1:
  200.                                 /*
  201.                                 计时模式
  202.                                 点亮1个led灯,转一圈为1分钟,每1分钟增加一个固定亮的led灯,
  203.                                 当秒led灯经过固定亮的led灯时,当前led灯熄灭,
  204.                                 若无经过固定亮的led灯,led灯点亮
  205.                                 */
  206.                                 n = i = 0;
  207.                                 if(Count_500ms >= 16000)
  208.                                 {//62.5us*16000=1秒
  209.                                         Count_500ms = 0;
  210.                                         if(d_n > 9)
  211.                                         {
  212.                                                 d_n = 0;
  213.                                                 Led_Bit[d_m] = 0;
  214.                                                 d_m++;
  215.                                                 if(d_m >= 6)
  216.                                                 {
  217.                                                         d_m = 0;
  218.                                                         
  219.                                                         if(Minute)
  220.                                                         {
  221.                                                                 Move_Bit++;
  222.                                                                 if(Move_Bit > 9)
  223.                                                                 {Move_Bit = 0;}
  224.                                                         }
  225.                                                         
  226.                                                         Minute++;
  227.                                                         if(Minute >= 60)
  228.                                                         {
  229.                                                                 Minute = 0;Move_Bit = 0;
  230.                                                                 memset(Minute_Bit,0,sizeof(Minute_Bit));
  231.                                                                 memset(Led_Bit,0,sizeof(Led_Bit));
  232.                                                         }
  233.                                                 }
  234.                                                 
  235.                                         }
  236.                                         Led_Bit[d_m] = (u16)(0x200 >> d_n);
  237.                                        
  238.                                        
  239.                                         Minute_Bit[(Minute-1)/10] |= (u16)(0x200 >> Move_Bit);
  240.                                                                                 
  241.                                         if(Minute)                {Led_Bit[0] |= Minute_Bit[0];}
  242.                                         if(Minute > 10)        {Led_Bit[1] |= Minute_Bit[1];}
  243.                                         if(Minute > 20)        {Led_Bit[2] |= Minute_Bit[2];}
  244.                                         if(Minute > 30)        {Led_Bit[3] |= Minute_Bit[3];}
  245.                                         if(Minute > 40)        {Led_Bit[4] |= Minute_Bit[4];}
  246.                                         if(Minute > 50)        {Led_Bit[5] |= Minute_Bit[5];}
  247.                                        
  248.                                        
  249.                                         if(                (Led_Bit[d_m] == Minute_Bit[d_m]) && \
  250.                                                         !((d_m == 0) && (d_n == 0)) && \
  251.                                                         !((d_m == (Minute-1)/10) && (d_n == Move_Bit))\
  252.                                         )
  253.                                         {Led_Bit[d_m] &= (u16)(~(0x200 >> d_n));}
  254.                                        
  255.                                         d_n++;
  256.                                 }
  257.                                 
  258.                                 
  259.                                 break;
  260.                 case 2://流水灯
  261.                                 if(Count_500ms >= 267)
  262.                                 {//62.5us*267=16.687毫秒        16.687*60盏led灯,约等于1秒转1圈
  263.                                         Count_500ms = 0;
  264.                                         if(!Change_Flag)
  265.                                         {
  266.                                                 if(d_n > 9)
  267.                                                 {
  268.                                                         d_n = 0;
  269.                                                         d_m++;
  270.                                                         if(d_m >= 6)
  271.                                                         {d_m = 0;Change_Flag^=1;}//切换全亮流水或全灭流水灯
  272.                                                 }
  273.                                                 Led_Bit[d_m] |= (u16)(0x200 >> d_n);d_n++;
  274.                                         }
  275.                                         else
  276.                                         {
  277.                                                 if(d_n > 9)
  278.                                                 {
  279.                                                         d_n = 0;
  280.                                                         d_m++;
  281.                                                         if(d_m >= 6)
  282.                                                         {d_m = 0;Change_Flag^=1;}//切换全亮流水或全灭流水灯
  283.                                                 }
  284.                                                 Led_Bit[d_m] &= (u16)~(0x200 >> d_n);d_n++;
  285.                                         }
  286.                                 }
  287.                                 break;
  288.         }
  289. }









复制代码

效果:流水灯模式


计时模式

51hei.png (13.23 KB, 下载次数: 106)

51hei.png

圆形led灯小玩意(包含pcb、原理圖、代碼).rar

308.67 KB, 下载次数: 76, 下载积分: 黑币 -5

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:230742 发表于 2021-5-8 01:40 | 只看该作者
非常漂亮。支持一下。
回复

使用道具 举报

板凳
ID:207943 发表于 2021-5-10 11:11 | 只看该作者
很漂亮,支持一下。用彩色LED是不是还要大一些才行。单色分不出时分秒
回复

使用道具 举报

地板
ID:718766 发表于 2021-12-18 16:09 | 只看该作者
这PCB画得真漂亮,支持
回复

使用道具 举报

5#
ID:384552 发表于 2022-1-15 17:31 | 只看该作者
增加数字音量电位器组合一起,调节音量大小,LED跟着旋转
回复

使用道具 举报

6#
ID:962536 发表于 2022-3-7 14:05 | 只看该作者
PCB 电路板 同步下 ;;;开源共享啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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