74HC595-串入/串并出带锁存的移位寄存器,实在是灰常magic,用它来驱动8段数码管太方便了!除了静态驱动可无限串联的一位数码管,它还能用来动态驱动4位段选数码管,而且由于串入/串并出和锁存特性,动态驱动也能够不闪烁显示并无限串联。

原理图
(两个74HC595分别做段选和段显,数码管为0.56寸4位共阳SR410561N)

PCB板

需不需要使用三极管?
74HC595的IO输出电流推荐为20mA,而数码管的限流电阻为1K欧姆时大概工作电流为10mA左右,因此使用74HC595的IO作为段选,提供数码管的阳极电流,不用再增加三极管了。74HC595的总电流不能超过70mA,所以这里只使用它驱动4个段选信号。 (好吧,由于动态显示是扫描的,每一时刻只点亮一个,所以驱动8个段选信号是没有问题的,74HC595的资源就全部利用了)

程序设计
动态驱动4位段选数码管的原理是,每个小间隔,使能一个段选信号,点亮它对应的段显。循环使能这4个段选信号,由于人的视觉停留,看起来就好像是同时点亮的。所以程序设计的时候,就需要每个小间隔对它操作一次,在主函数或者定时器中断里面都可以。

调试这个小模块的时候,我遇到了两个问题: 第一,显示有闪烁;第二,没用到的段会轻微点亮。

第一个问题解决的很快,闪烁是因为显示速度太慢,提高显示速度就可以;第二个问题是因为我的初版程序里面,每移位8bit就锁存一次,因此段选信号会在瞬间作为段显信号,所以明明不该亮起来的段会看起来微微亮,解决方法是段选和段显信号都发送完成之后再锁存。

/*************************************************
驱动4位段选数码管的方法:
HC595_single_4BIT的功能是,将段显信号byte发送,然后使能第byte_position个的段选信号;
发送完毕之后更新锁存(而不是每个for分别更新),实际显示的效果非常漂亮;
当多个这样的模块串联时,会发现它们都会显示“3210”;
get_square的功能是,计算2的3-byte_position次幂,并存放在byte_position_t中。
**************************************************/
void HC595_single_4BIT(int8_t byte, int8_t byte_position)
{
    int8_t i = 0, j = 0;
    uint32_t byte_position_t = 0;
    get_square(2, 3 - byte_position, &byte_position_t);

for (i = 0; i < 8; i++) {
        if (byte & 0x80)
            HC595_DAT_H_4BIT();
        else
            HC595_DAT_L_4BIT();
        HC595_SCK_L_4BIT();
        HC595_SCK_H_4BIT();
        byte = byte << 1;
    }
    for (i = 0; i < 8; i++) {
        if (byte_position_t & 0x80)
            HC595_DAT_H_4BIT();
        else
            HC595_DAT_L_4BIT();
        HC595_SCK_L_4BIT();
        HC595_SCK_H_4BIT();
        byte_position_t = byte_position_t << 1;
    }
    HC595_RCK_L_4BIT();
    HC595_RCK_H_4BIT();
}

int main (void)
{
    /*
    functions();
    */   
    while (1) {
        HC595_single_4BIT(LGBH38_HC595_DEC_4BIT[0], 0);Delay100Us_xt2_8MHz(1);
        HC595_single_4BIT(LGBH38_HC595_DEC_4BIT[1], 1);Delay100Us_xt2_8MHz(1);
        HC595_single_4BIT(LGBH38_HC595_DEC_4BIT[2], 2);Delay100Us_xt2_8MHz(1);
        HC595_single_4BIT(LGBH38_HC595_DEC_4BIT[3], 3);Delay100Us_xt2_8MHz(1);
    }   
    return 0;
}

/*************************************************
驱动多个4位段选数码管的方法一:
由于74HC595的串入/串并出特性,这个模块可以无限串联使用,但是使用上面的程序,没有办法单独点亮后级,因为后级的数据始终是前级推出来的,而前级始终处在4位段选的循环中。
所以程序需要做一些修改,使得在每个小间隔里面,能够对后级单独操作。
基本原理是,假如有len个模块串联使用,先将要显示的len_position之前的熄灭,然后发送byte和byte_position,再将len_position之后的熄灭;完成之后更新锁存器。
虽然它可以单独对任何段选和段显进行操作,但是随着串联个数的增加,亮度也会降低。
**************************************************/
void HC595_multi_4BIT(int8_t len, int8_t len_position, int8_t byte, int8_t byte_position)
{
    int8_t i = 0, j = 0;
    uint32_t byte_position_t = 0;
    get_square(2, 3 - byte_position, &byte_position_t);

for (j = 0; j < len - len_position - 1; j++) {
        HC595_DAT_H_4BIT();
        for (i = 0; i < 8; i++) {
            HC595_SCK_L_4BIT();
            HC595_SCK_H_4BIT();
        }
        HC595_DAT_L_4BIT();
        for (i = 0; i < 8; i++) {
            HC595_SCK_L_4BIT();
            HC595_SCK_H_4BIT();
        }
    }

for (i = 0; i < 8; i++) {
        if (byte & 0x80)
            HC595_DAT_H_4BIT();
        else
            HC595_DAT_L_4BIT();
        HC595_SCK_L_4BIT();
        HC595_SCK_H_4BIT();
        byte = byte << 1;
    }
    for (i = 0; i < 8; i++) {
        if (byte_position_t & 0x80)
            HC595_DAT_H_4BIT();
        else
            HC595_DAT_L_4BIT();
        HC595_SCK_L_4BIT();
        HC595_SCK_H_4BIT();
        byte_position_t = byte_position_t << 1;
    }

for (j = 0; j < len_position; j++) {
        HC595_DAT_H_4BIT();
        for (i = 0; i < 8; i++) {
            HC595_SCK_L_4BIT();
            HC595_SCK_H_4BIT();
        }
        HC595_DAT_L_4BIT();
        for (i = 0; i < 8; i++) {
            HC595_SCK_L_4BIT();
            HC595_SCK_H_4BIT();
        }
    }

HC595_RCK_L_4BIT();
    HC595_RCK_H_4BIT();
}

int main (void)
{
    /*
    functions();
    */
    while (1) { /*****会显示 76543210 *********/
        HC595_multi_4BIT(2, 0, LGBH38_HC595_DEC_4BIT[0], 0);Delay100Us_xt2_8MHz(1);
        HC595_multi_4BIT(2, 0, LGBH38_HC595_DEC_4BIT[1], 1);Delay100Us_xt2_8MHz(1);
        HC595_multi_4BIT(2, 0, LGBH38_HC595_DEC_4BIT[2], 2);Delay100Us_xt2_8MHz(1);
        HC595_multi_4BIT(2, 0, LGBH38_HC595_DEC_4BIT[3], 3);Delay100Us_xt2_8MHz(1);

HC595_multi_4BIT(2, 1, LGBH38_HC595_DEC_4BIT[4], 0);Delay100Us_xt2_8MHz(1);
        HC595_multi_4BIT(2, 1, LGBH38_HC595_DEC_4BIT[5], 1);Delay100Us_xt2_8MHz(1);
        HC595_multi_4BIT(2, 1, LGBH38_HC595_DEC_4BIT[6], 2);Delay100Us_xt2_8MHz(1);
        HC595_multi_4BIT(2, 1, LGBH38_HC595_DEC_4BIT[7], 3);Delay100Us_xt2_8MHz(1);
    }   
    return 0;
}

/*************************************************
驱动多个4位段选数码管的方法二:
动态驱动,每个小间隔只能使能其中一个段选,上面的程序是假如有12个段选,就在12个小间隔里面循环使能,优点是可以单独操作任何一段,缺点是亮度会降低。
其实可以仍然使用4个小间隔,在每个小间隔里面,发送bytex段显信号,使能所有串联模块的第byte_position个段选。
因为后级串联的模块个数不确定,所以使用变参函数会方便一些。
**************************************************/
void HC595_multi_dis_4BIT(int8_t len, int8_t byte_position, int8_t byte_h, ...)
{
    int8_t i = 0, j = 0, bytex = 0;
    uint32_t byte_position_t = 0, byte_position_save = 0;

get_square(2, 3 - byte_position, &byte_position_save);
    char *p = (char *)&byte_h;
   
    for (j = 0; j < len; j++) {
        bytex = *((int *)p);
        p += sizeof(int);
        for (i = 0; i < 8; i++) {
            if (bytex & 0x80)
                HC595_DAT_H_4BIT();
            else
                HC595_DAT_L_4BIT();
            HC595_SCK_L_4BIT();
            HC595_SCK_H_4BIT();
            bytex = bytex << 1;
        }
        byte_position_t = byte_position_save;
        for (i = 0; i < 8; i++) {
            if (byte_position_t & 0x80)
                HC595_DAT_H_4BIT();
            else
                HC595_DAT_L_4BIT();
            HC595_SCK_L_4BIT();
            HC595_SCK_H_4BIT();
            byte_position_t = byte_position_t << 1;
        }
    }
    HC595_RCK_L_4BIT();
    HC595_RCK_H_4BIT();   
}
int main (void)
{
     /*
    functions();
    */
    while (1) { /******会显示 222211110000 ***********/

HC595_multi_dis_4BIT(3, 0, LGBH38_HC595_DEC_4BIT[2], LGBH38_HC595_DEC_4BIT[1],
                LGBH38_HC595_DEC_4BIT[0]);
        DelayMs_xt2_8MHz(1);

HC595_multi_dis_4BIT(3, 1, LGBH38_HC595_DEC_4BIT[2], LGBH38_HC595_DEC_4BIT[1],
                LGBH38_HC595_DEC_4BIT[0]);
        DelayMs_xt2_8MHz(1);

HC595_multi_dis_4BIT(3, 2, LGBH38_HC595_DEC_4BIT[2], LGBH38_HC595_DEC_4BIT[1],
                LGBH38_HC595_DEC_4BIT[0]);
        DelayMs_xt2_8MHz(1);

HC595_multi_dis_4BIT(3, 3, LGBH38_HC595_DEC_4BIT[2], LGBH38_HC595_DEC_4BIT[1],
                LGBH38_HC595_DEC_4BIT[0]);
        DelayMs_xt2_8MHz(1);
    }   
    return 0;
}

最后,趁着某xx的单反相机还在这里,留一张渣图:

两个74HC595驱动共阳4位段选数码管相关推荐

  1. max7219驱动共阳点阵

    小白在共阳数码管上踩过的坑 工具 芯片max7219 共阳数码管 stm32精英版 首先要没有找到正确的资料,浪费一天时间,这种芯片手册有中文的,也很好找,在那个基础上开始搞. 在网上没有找到现成的驱 ...

  2. 【Multisim仿真】74LS47译码器驱动共阳数码管显示(0-8)数字显示

    [Multisim仿真]74LS47译码器驱动共阳数码管显示(0-8)数字显示 Multisim仿真演示 74ls47引脚功能 LT: 试灯输入,是为了检查数码管各段是否能正常发光而设置的.当LT=0 ...

  3. 51单片机通过两片74HC595级联,用8位LED数码管,分别显示当前日期,如:“2”、“0”、“-”、“0”、“5”、“-”、“2”、“6”,用Proteus仿真实现。

    1.先上仿真图,但这么连仿真图是不太正确的,要注意.展示的话能用就行. 2.从上到下依次放上数据手册上的引脚解释和逻辑功能和时序图 3.贴上代码:写了发送一字节数据函数,发送全部字节函数,加上一些写了 ...

  4. 74HC595驱动八段共阳数码管工程文件

    飞猫盘|文件加速传输工具|云盘|橘猫旗下新概念云平台 此文件是包括了protues文件仿真和keil文件以及cubemx文件配置 HARDWARE文件里面有关于74HC595的基本驱动代码,可移植 数 ...

  5. LED 数码管共阴共阳的区别+静态/动态显示

    51单片机--数码管动态显示 1.共阴共阳定义 LED 共阴极指的是LED共同的接点是GND(接地),而共阳极指的是LED共同的接点是电源.LED亮灯的条件是两端有电势差. 最后一段h/dp小数点在高 ...

  6. STM32F103C8T6 I/O口驱动4位共阳数码管

    STM32F103C8T6 I/O口驱动4位共阳数码管 看了网上很多的资料.很少有单独讲解STM32 I/O口直接驱动数码管的资料,有的网上还禁用了JTAG和SWD口,对很多刚入门的学者会造成不必要的 ...

  7. Arduino 驱动TM1638显示十位的共阳数码管

    Arduino 驱动TM1638显示十位的共阳数码管 二话不说先上图: 这个是电路图,下面我在上传TM1638的手册 哈哈太乱了先凑合着看吧!效果是实现了,画了板还没有发过来. 我也不多说什么了上代码 ...

  8. 共阴共阳数码管(及74HC595控制)

    一.共阳数码管 共阳数码管段表  0xc0,/*0*/                             0xF9,/*1*/                             0xA4, ...

  9. arduino用2个74HC595点亮2个4位共阳数码管

    arduino用2个74HC595点亮2个4位共阳数码管 原文:https://www.geek-workshop.com/forum.php?mod=viewthread&tid=7415 ...

最新文章

  1. 狼奔代码生成工具使用心得
  2. Conan and Agasa play a Card Game
  3. Java代码03-打印一个菱形
  4. DCMTK:OFCharacterEncoding的测试程序
  5. 狄斯奎诺算法 c语言,图的邻接表实现迪杰斯特拉算法(C语言).doc
  6. 2013年5月7日---JS中的正则
  7. Spring入门篇——第6章 Spring AOP的API介绍
  8. 【AI视野·今日NLP 自然语言处理论文速览 第五期】Thu, 10 Jun 2021
  9. 智能时代,企业如何“聚数为智”加速数字化转型?
  10. linux fork脚本,shell调度脚本的三种不同方法(fork, exec, source)
  11. 使用单例时的三种单例写法
  12. GoldenGate实施参考
  13. 怎样看pytorch源码最有效?
  14. android视频播放器ui,Android史上最强视频音频播放器 精美UI Fragment实现
  15. YApi接口平台-接口挡板
  16. 大数据计算技术架构解析
  17. 再看健康码和随申码,对比健康码和身份证,想想延展
  18. 博弈论、竞价机制和AI
  19. 手机话费充值页面HTMLcss3+html5模板
  20. 眼睛中的密码-虹膜识别

热门文章

  1. 亚马逊开店时间需要多久?
  2. 51单片机(4)-------单片机开发板
  3. 计算机应用基础考试制作表格,网教统考《计算机应用基础》电子表格以及操作系统应用部分专项训练题...
  4. War3更新相关问题
  5. 详解 Spring 框架的依赖注入
  6. Z3 Solver中Tactic的使用
  7. U盘格式的区别有哪些?
  8. 微软对OpenAI投资10亿美元欲开发AI技术;华晨宝马宣布建成全球首个5G汽车生产基地;传苹果将收购英特尔调制解调器芯片业务...
  9. Linux的关机命令详解
  10. Ubunto搭建web服务器