找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用单片机定时器方式驱动2块74HC595实现16只LED流水灯程序

  [复制链接]
跳转到指定楼层
楼主
定时器的代码风格参考了金沙滩宋老师的写法,74HC595的驱动代码参考了B站up主金善愚的写法(他没用到定时器去实现流水灯,只是不停的用延时)我看了一下论坛好像没有这个方面的东西,我想分享出来给大家参考参考。也希望大家能提供一些改善代码的建议。

test2.rar

70.95 KB, 下载次数: 41

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:624769 发表于 2021-12-31 22:44 | 只看该作者
假定,你是真的想知道更好的写法,
如果,仅仅只是流水灯的话,HC595 应该这样用:

void InterruptTimer0() interrupt 1
{
        static uint cnt = 0;
        static uchar j = 0;
        uchar        i;
        TH0 = T0RH;
        TL0 = T0RL;
        if(++cnt>=500)
        {
                cnt = 0;
                for(i=0;i<16;i++)
                {
                        if(i == j)        HC595_DS = 1;       
                        else        HC595_DS = 0;       
                        HC595_SH_CP = 1;
                        HC595_SH_CP = 0;
                }
                HC595_ST_CP = 1;
                HC595_ST_CP = 0;
                j++;
                j &= 0x0f;
        }
}
回复

使用道具 举报

板凳
ID:1032740 发表于 2022-6-20 09:26 | 只看该作者
如果一次亮两个灯,一直往前亮应该怎么写,比如32个灯,第一次亮1,2。第二次亮2,3。第三次亮3,4。。。。一直往前亮怎么写比较合理
回复

使用道具 举报

地板
ID:332444 发表于 2022-6-20 20:49 | 只看该作者
shuisherr 发表于 2022-6-20 09:26
如果一次亮两个灯,一直往前亮应该怎么写,比如32个灯,第一次亮1,2。第二次亮2,3。第三次亮3,4。。。。 ...

简单得很,如果能通常IO实现,595也一样道理,不过就是把数据发送而已。简述:sl=3;P3=sl;if((sl*=2)==128)sl=3;
回复

使用道具 举报

5#
ID:1032740 发表于 2023-2-9 23:51 | 只看该作者
xianfajushi 发表于 2022-6-20 20:49
简单得很,如果能通常IO实现,595也一样道理,不过就是把数据发送而已。简述:sl=3;P3=sl;if((sl*=2)==12 ...

你这个逻辑没看懂,初学者
回复

使用道具 举报

6#
ID:332444 发表于 2023-2-10 08:55 | 只看该作者
shuisherr 发表于 2023-2-9 23:51
你这个逻辑没看懂,初学者

很简单,IO组送值3则引脚1和2高电平类推送6则引脚2和3高电平...
回复

使用道具 举报

7#
ID:332444 发表于 2023-2-10 08:58 | 只看该作者
shuisherr 发表于 2023-2-9 23:51
你这个逻辑没看懂,初学者

修改一下sl=3;P3=sl;if((sl*=2)>128)sl=3;这个计算公式就实现循环点亮相邻2个灯了.
回复

使用道具 举报

8#
ID:332444 发表于 2023-2-10 09:09 | 只看该作者
shuisherr 发表于 2023-2-9 23:51
你这个逻辑没看懂,初学者

就写一个运行验证过的荔枝
  1. #include "reg52.h"
  2. void main()
  3. {
  4.         unsigned char y=0,y1=0,y2=0,d=3;P1=0;
  5.         while(1)
  6.         {
  7.                 if(++y==0)if(++y1==0)if(++y2>7){P1=d;if((d*=2)==128)d=3;y2=0;}
  8.         }
  9. }
复制代码
回复

使用道具 举报

9#
ID:332444 发表于 2023-2-10 09:14 | 只看该作者
shuisherr 发表于 2023-2-9 23:51
你这个逻辑没看懂,初学者

我写的一组荔枝扩展就是3组4组都可以的如法炮制.
回复

使用道具 举报

10#
ID:332444 发表于 2023-2-10 09:20 | 只看该作者
回复

使用道具 举报

11#
ID:69038 发表于 2023-2-10 17:25 | 只看该作者
shuisherr 发表于 2022-6-20 09:26
如果一次亮两个灯,一直往前亮应该怎么写,比如32个灯,第一次亮1,2。第二次亮2,3。第三次亮3,4。。。。 ...

用环移指令啊: _crol_
int LED_data=0x0003;
while(1)
{
hc595_sent_data(LED_data&0xff);
hc595_sent_data(LED_data>>8);
hc595_LE_on();
LED_data= _irol_(LED_data,1);
}
回复

使用道具 举报

12#
ID:67199 发表于 2023-2-10 19:12 | 只看该作者
我用两只595驱动过8位数码管,就是动态扫描。
回复

使用道具 举报

13#
ID:1032740 发表于 2023-2-10 20:25 | 只看该作者
xianfajushi 发表于 2023-2-10 09:09
就写一个运行验证过的荔枝

感谢老师的回复,我用数组和switch写出来了,现在碰到新的问题了,就是595怎么输出pwm信号,595是串输入并输出,那么应该一次输出一个波形,如果占空比50%就应该前16个灯亮,后16个灯灭。这个怎么用代码输出的?找遍了全网没找到。。。
回复

使用道具 举报

14#
ID:332444 发表于 2023-2-10 20:52 | 只看该作者
shuisherr 发表于 2023-2-10 20:25
感谢老师的回复,我用数组和switch写出来了,现在碰到新的问题了,就是595怎么输出pwm信号,595是串输入 ...

不知道玩什么需要那么多输出,而且还要占空比,2片串联595就有时差,2片并联可以消除时差;
要595弄占空比频率允许的话可以实现,就是发送的时间时空比,是要荔枝?
回复

使用道具 举报

15#
ID:491577 发表于 2023-2-19 11:57 | 只看该作者
这个问题太简单,其实只是控制16个LED1一片595就可以了,更简单一点直接用8个IO口控制也行(4*4=16)
回复

使用道具 举报

16#
ID:996773 发表于 2023-2-28 15:20 | 只看该作者
能达到目的就用延时好了,干嘛非得给自己找难题用定时器,就这么简单的程序等定时器定时的时候

单片机不也是在空转白费力气吗,不要为了问题给自己找麻烦。编程是个循序渐进的修炼过程,

等真正需要定时器时候再说
回复

使用道具 举报

17#
ID:76044 发表于 2023-6-8 16:45 | 只看该作者
各位前辈大虾,能不能给个 2块74HC595实现16只LED流水灯  程序是汇编的,本人只会汇编,C有些看不了,麻烦一下
回复

使用道具 举报

18#
ID:161164 发表于 2023-6-10 15:28 来自手机 | 只看该作者
lxm41577 发表于 2023-6-8 16:45
各位前辈大虾,能不能给个 2块74HC595实现16只LED流水灯  程序是汇编的,本人只会汇编,C有些看不了,麻烦 ...

先把你懂的写出来
回复

使用道具 举报

19#
ID:76044 发表于 2023-6-12 11:41 | 只看该作者
lkc8210 发表于 2023-6-10 15:28
先把你懂的写出来

我这个程序在运行时,2片的灯同时运行一样的结果,2片同时在流水,不会是第1片运行完,第1片不运行,第2片运行

SDATA_595 EQU   P1.0 ;串行数据输入
SCLK_595  EQU   P1.2 ;移位时钟脉冲
RCK_595   EQU   P1.1 ;输出锁存器控制脉冲

;================================================

ORG 0000H
LJMP MAIN
ORG 0030H

;================================================

MAIN:MOV SP,#60H
     MOV R0,#0FEH

MAIN1:
CALL OUT_595
CALL DELAY
MOV A,R0
RL A
MOV R0,A
JMP MAIN1

;---------------------------------------------------------------
;输出锁存器输出数据子程序
;---------------------------------------------------------------

OUT_595:

       MOV R4,#08H
       MOV A,R0
WR_LOOP:
RLC A
MOV SDATA_595,C
SETB SCLK_595        ;上升沿发生移位
NOP
NOP
CLR SCLK_595
DJNZ R4,WR_LOOP


CLR RCK_595
NOP
NOP
SETB RCK_595         ;上升沿将数据送到输出锁存器
NOP
NOP
NOP
CLR RCK_595
RET
;--------------------------------------------------------------
;延时子程序
;--------------------------------------------------------------
DELAY:MOV R5,#03H
DEL0:MOV R6,#0FFH
DEL1:MOV R7,#0FFH
DJNZ R7,$
DJNZ R6,DEL1
DJNZ R5,DEL0
RET
;---------------------------------------------------------------
END
回复

使用道具 举报

20#
ID:76044 发表于 2023-7-2 14:59 | 只看该作者
lkc8210 发表于 2023-6-10 15:28
先把你懂的写出来

大虾帮帮忙看看,指导指导一下
回复

使用道具 举报

21#
ID:161164 发表于 2023-7-3 10:00 | 只看该作者
lxm41577 发表于 2023-6-12 11:41
我这个程序在运行时,2片的灯同时运行一样的结果,2片同时在流水,不会是第1片运行完,第1片不运行,第2片运行 ...

原理图呢?
按你的代码推断
单片机每次只输出8位数据
以你的描述来看
你用了并联的接线方法
应改用串联的接线方法并在代码中输出16位数据

  1. SDATA_595 EQU   P1.0 ;串行数据输入
  2. SCLK_595  EQU   P1.2 ;移位时钟脉冲
  3. RCK_595   EQU   P1.1 ;输出锁存器控制脉冲

  4. ;================================================

  5. ORG 0000H
  6. LJMP MAIN
  7. ORG 0030H

  8. ;================================================

  9. MAIN:MOV SP,#60H
  10.      MOV R0,#0FEH
  11.      MOV R1,#0FFH
  12.         CLR SCLK_595
  13. MAIN1:
  14. CALL OUT_595
  15. CALL DELAY
  16. CLR C
  17. MOV A,R1
  18. RLC A
  19. MOV R1,A
  20. MOV A,R0
  21. RLC A
  22. MOV R0,A
  23. JNC MAIN1
  24. ORL 01H, #01H;地址01H即R1
  25. JMP MAIN1

  26. ;---------------------------------------------------------------
  27. ;输出锁存器输出数据子程序
  28. ;---------------------------------------------------------------

  29. OUT_595:

  30. MOV R4,#08H
  31. MOV A,R1;//输出高八位
  32. WR_LOOP1:
  33. RLC A
  34. MOV SDATA_595,C
  35. SETB SCLK_595        ;上升沿发生移位
  36. NOP
  37. NOP
  38. CLR SCLK_595
  39. DJNZ R4,WR_LOOP1

  40. MOV R4,#08H
  41. MOV A,R0//输出低八位
  42. WR_LOOP2:
  43. RLC A
  44. MOV SDATA_595,C
  45. SETB SCLK_595        ;上升沿发生移位
  46. NOP
  47. NOP
  48. CLR SCLK_595
  49. DJNZ R4,WR_LOOP2


  50. CLR RCK_595
  51. NOP
  52. NOP
  53. SETB RCK_595         ;上升沿将数据送到输出锁存器
  54. NOP
  55. NOP
  56. NOP
  57. CLR RCK_595
  58. RET
  59. ;--------------------------------------------------------------
  60. ;延时子程序
  61. ;--------------------------------------------------------------
  62. DELAY:MOV R5,#03H
  63. DEL0:MOV R6,#0FFH
  64. DEL1:MOV R7,#0FFH
  65. DJNZ R7,$
  66. DJNZ R6,DEL1
  67. DJNZ R5,DEL0
  68. RET
  69. ;---------------------------------------------------------------
  70. END
复制代码



回复

使用道具 举报

22#
ID:76044 发表于 2023-7-7 10:59 | 只看该作者
lkc8210 发表于 2023-7-3 10:00
原理图呢?
按你的代码推断
单片机每次只输出8位数据

测试可以用,非常感谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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