找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机74HC595循环点亮LED 运行起来会有不止一个LED亮起来?

[复制链接]
跳转到指定楼层
楼主
单片机通过74HC595控制8个LED循环点亮,按照D16-D15-D14......D9依次循环,每次亮一个。仿真看着没问题,实物运行起来会有不止一个LED亮起来,学艺不精,找了很久没找到问题根源,还请大佬指点迷津。 单片机型号STC89C52,晶振12MHz。电路、程序、现象还请看一下附件,先谢过了。







单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. sbit RCK=P3^5;  // Pin12        输出锁存控制脉冲
  4. sbit SER=P3^4;  // Pin14  串行数据输入
  5. sbit SCK=P3^6;        // Pin11        移位脉冲

  6. void HC595_Send(unsigned char byte);
  7. void Delay();

  8. void main()
  9. {
  10.         unsigned char i;
  11.         unsigned char buffer[8]={0X7F,0XBF,0XDF,0XEF,0XF7,0XFB,0XFD,0XFE};
  12.         
  13.         while(1)
  14.         {
  15.                 for(i=0;i<8;i++)                //循环点亮单个LED
  16.                 {
  17.                         HC595_Send(buffer[i]);
  18.                         Delay();
  19.                 }
  20.         }
  21. }

  22. /*驱动HC595*/
  23. void HC595_Send(unsigned char byte)
  24. {
  25.         unsigned char i;
  26.         for(i=0;i<8;i++)                //写入移位寄存器
  27.         {
  28.                 SCK=0;
  29.                 SER=byte>>7;
  30.                 byte<<=1;
  31.                 SCK=1;
  32.         }
  33.         
  34.         RCK=0;        //锁存时钟产生上升沿更新输出
  35.         _nop_();
  36.         RCK=1;
  37. }

  38. /*延时*/
  39. void Delay()                //@12.000MHz
  40. {
  41.         unsigned char i, j, k;

  42.         _nop_();
  43.         i = 8;
  44.         j = 154;
  45.         k = 122;
  46.         do
  47.         {
  48.                 do
  49.                 {
  50.                         while (--k);
  51.                 } while (--j);
  52.         } while (--i);
  53. }
复制代码


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

使用道具 举报

沙发
ID:213173 发表于 2023-5-30 16:40 | 只看该作者
程序没有什么明显问题,仿真成功不等于实物就能成功。把595驱动代码调整一下试试。
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. sbit RCK=P3^5;  // Pin12  输出锁存控制脉冲
  4. sbit SER=P3^4;  // Pin14  串行数据输入
  5. sbit SCK=P3^6;  // Pin11  移位脉冲

  6. void HC595_Send(unsigned char byte);
  7. void Delay();

  8. void main()
  9. {
  10.         unsigned char i;
  11.         unsigned char buffer[8]={0X7F,0XBF,0XDF,0XEF,0XF7,0XFB,0XFD,0XFE};
  12.         SCK=0;       
  13.         RCK=0;
  14.         while(1)
  15.         {
  16.                 for(i=0;i<8;i++)                //循环点亮单个LED
  17.                 {
  18.                         HC595_Send(buffer[i]);
  19.                         Delay();
  20.                 }
  21.         }
  22. }

  23. /*驱动HC595*/
  24. void HC595_Send(unsigned char byte)
  25. {
  26.         unsigned char i;
  27.         for(i=0;i<8;i++)//写入移位寄存器
  28.         {
  29.                 SER=byte>>7;
  30.                 SCK=1;
  31.                 _nop_();
  32.                 SCK=0;
  33.                 byte<<=1;
  34.         }       
  35.         RCK=1;        //锁存时钟产生上升沿更新输出
  36.         _nop_();
  37.         RCK=0;
  38. }

  39. /*延时*/
  40. void Delay()                //@12.000MHz
  41. {
  42.         unsigned char i, j, k;
  43.         _nop_();
  44.         i = 8;
  45.         j = 154;
  46.         k = 122;
  47.         do
  48.         {
  49.                 do
  50.                 {
  51.                         while (--k);
  52.                 } while (--j);
  53.         } while (--i);
  54. }
复制代码
回复

使用道具 举报

板凳
ID:1080867 发表于 2023-5-30 22:55 | 只看该作者
wulin 发表于 2023-5-30 16:40
程序没有什么明显问题,仿真成功不等于实物就能成功。把595驱动代码调整一下试试。

你好,我照着你的改了下代码,进入HC595_Send()函数时就将RCK拉低,八位写完后在拉高RCK,能正常运行了。 修改前HC595_Send()这个函数里面,写入八位后RCK给一个上升沿这种做法为啥不对呢?l两者看起来差不多啊,存在什么问题。

void HC595_Write(unsigned char dat)
{
    unsigned char i;
    RCK=0;
    for(i=0;i<8;i++)
    {
        SCK=0;
        SER=dat>>7;
        dat<<=1;
        SCK=1;
        _nop_();
    }
    RCK=1;
}
回复

使用道具 举报

地板
ID:245053 发表于 2023-5-31 09:43 | 只看该作者
本帖最后由 pcf2000 于 2023-5-31 09:51 编辑

SER=byte>>7;    这句代码是什么意思,串行输出不该是一位一位输出的吗,你移动7位,高位的数据直接出位,就用0补位了,就出现LED灯亮了,
记住,你的电路是0电平点亮LED灯,要实现每次只一只LED点亮,595的输出每次必须只有一位输出为0
改为 :SER=byte>>1;    即可
回复

使用道具 举报

5#
ID:123289 发表于 2023-5-31 10:37 | 只看该作者
1、要点,先关闭OE,这样数据的切换就不会闪动,因为这时不显示(暗,消影)。
2、给出串行数据;
3、要点:等数据稳定后,再给出移位脉冲信号上沿。
4、待输出稳定后,打开OE,放出数据。
所谓稳定,也就是插入几个NOP指令的事。
硬件上要注意,CLK信号,复位信号要做防护,不能受到干扰。

回复

使用道具 举报

6#
ID:1081090 发表于 2023-5-31 13:51 | 只看该作者
提醒楼主一个冷知识:不同厂家的595芯片,对锁存和ENABLE的逻辑要求不完全相同,你看下你使用的595芯片对应的手册就明白了。
回复

使用道具 举报

7#
ID:1080867 发表于 2023-5-31 14:47 | 只看该作者
pcf2000 发表于 2023-5-31 09:43
SER=byte>>7;    这句代码是什么意思,串行输出不该是一位一位输出的吗,你移动7位,高位的数据直接出位, ...

数据是串入并出的,这句是在往移位寄存器里面写入的
回复

使用道具 举报

8#
ID:624769 发表于 2023-5-31 17:20 | 只看该作者
Cqzm 发表于 2023-5-30 22:55
你好,我照着你的改了下代码,进入HC595_Send()函数时就将RCK拉低,八位写完后在拉高RCK,能正常运行了。 ...

存在的问题是,你还没完成下降,就开始上升了。不知道你用的什么单片机,如果1T 的单片机, RCLK = 0; 到 RCLK =1; 之间,你最少要插入 5个 _nop_();   如果你的 595是 3V供电的话,你甚至需要 插入12个_nop_(); 才够。
回复

使用道具 举报

9#
ID:1080867 发表于 2023-5-31 23:10 | 只看该作者
188610329 发表于 2023-5-31 17:20
存在的问题是,你还没完成下降,就开始上升了。不知道你用的什么单片机,如果1T 的单片机, RCLK = 0; 到 ...

在 RCK=0;  RCK=1之间插入多个_nop_()也不起作用; 单片机是STC89C52,595供电电压是5V,万用表实际测下来是4.97V
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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