基于STM32通过SN74HC595驱动4位数码管详细解析

#哪个编程工具让你的工作效率翻倍?#

目录

1.  单位数码管概述

2.  对应编码

2.1  共阳数码管

2.2  共阴数码管

3.  SN74HC595驱动数码管

3.1  工作原理

3.2  使用步骤

3.2.1  数据传输

3.2.2  将数据移入移位寄存器

 3.2.3  将移位寄存器里的数据送入存储寄存器

3.2.4  数据锁存

3.3  运用

3.3.1  四位数码管模块使用

3.3.2  八位数码管模块使用

4.  STM32F103C8T6代码编写

4.1  宏定义相关

4.2  引脚初始化

4.3  数据写入移位寄存器

4.4  共阳极数码管编码

4.5  数据位选

4.6  主函数


1.  单位数码管概述

        数码管的内部基本单元是发光二极管,数码管是发光器件之一,内部由七个条形发光二极管(a、b、c、d、e、f、g)和一个圆点发光二极管(dp)构成。

        按照数码管的公共接线不同,数码管又可分类为共阴极数码管和共阳极数码管两种,共阴极数码管的公共端接地,而共阳极数码管的公共端接电源

2.  对应编码

2.1  共阳数码管

        数码管中所有的正极连接在一起,这个端口被称之为位选端口,其余的数码管引脚a-h都为段选端口2、共阳极数码管的编码(CA):

u8 code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //0-F

2.2  共阴数码管

        是数码管所有的负极连接在一起,这个端口被称之为位选端口,其余的数码管引脚a-h都为段选端口4、共阴极数码管的编码(CC/CK):

u8 code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0-F

3.  SN74HC595驱动数码管

3.1  工作原理

        74HC595是一个8位串行输入、平行输出的位移缓存器:平行输出为三态输出。

        在SCK的上升沿,单行数据由SDL输人到内部的8位位移缓存器,并由Q7`输出,而平行输出则是在LCK的上升沿将在8位位移缓存器的数据存入到8位平行输出缓存器

        当串行数据输入端OE的控制信号为低使能时,平行输出端的输出值等于平行输出缓存器所存储的值而当OE为高电位,也就是输出关闭时,平行输出端会维持在高阻抗状态。

管脚编号管脚名说明
1、2、3、4、5、6、7、15Q1、Q2、Q3、Q4、Q5、Q6、Q7、Q08位并行数据输出(三态输出管脚)
8GND电源地
9Q7’串行数据输出,级联输出端,接下一个595的DS端(串行数据输出管脚)
10MR(SCLR)低电平有效,清空移位寄存器中已有的数据,一般不用,接高电平即可(移位寄存器清零端)
11SH_CP(SCK)  移位寄存器时钟引脚,上升沿时,移位寄存器中的数据整体后移,并接受新的数据(从DS输入)(数据输入时钟线)
12ST_CP(RCK)存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器(输出存储器锁存时钟线)
13OE低电平有效,输出使能控制脚
14DS串行数据输入引脚(数据线)
16VCC电源端

3.2  使用步骤

        74HC595是将数据串转并的,也就是数据(8bit)串行输入,并行输出。

3.2.1  数据传输

        先把要传输的数据(8bit)从引脚14(DS)输入到74HC595。

3.2.2  将数据移入移位寄存器

        将从DS上的数据串行移入移位寄存器,需要时钟驱动,即引脚11 (SHCP)每产生一个上升沿, DS上的数据往移位寄存器送入一位,先送高位,后送低位,经过8个上升沿后, 8bit全部送入移位寄存器了。

 3.2.3  将移位寄存器里的数据送入存储寄存器

        将移位寄存器里的数据送入存储寄存器,引脚12 (STCP)产生一个上升沿后,该操作就完成了。

3.2.4  数据锁存

        引脚13 (OE)为低电平,则步骤3送入存储寄存器的8bit数据(一个字节)就在Q7-Q0并行输出,并输出的数据会被所存起来。

注意:数据并行输出后,只要没有数据更新进来,原输出的数据保持不变,就是所谓的锁存(数据被锁存住)。在完成步骤123后,只要步骤4还没使能,输出都是保持不变的,当OE一使能,新的数据就输出覆盖旧输出。

3.3  运用

3.3.1  四位数码管模块使用

四位数码管电路图:

3.3.2  八位数码管模块使用

        图中是8位数码管的电路图,与4位相似,都具有两片595驱动芯片,两片595级联在一起,第二片595(U4)是对数码管的8段码进行段码操作,第一片595(U3)是对8位数码管进行位选操作,即选择哪一个数码管进行显示操作。
        虽然595具有存储寄存器,但是只能对一位数码管的数据进行数据锁存。

4.  STM32F103C8T6代码编写

4.1  宏定义相关

        为了方便后续代码的更改,我们可以对所用引脚进行宏定义:

/************************************************************************************
接线
74HC595_4位数码管模块-------------------------STM32F103C8T6
VCC------------------------------------------3.3/5V
GND------------------------------------------GND
DIO------------------------------------------GPIOA_0
RCK------------------------------------------GPIOA_1
SCLK-----------------------------------------GPIOA_2
*****************************************************************************************/
#define DIO_GPIO_PORT    	GPIOA		            
#define DIO_GPIO_CLK 	    RCC_APB2Periph_GPIOA		
#define DIO_GPIO_PIN		GPIO_Pin_0			        

#define RCK_GPIO_PORT    	GPIOA			          
#define RCK_GPIO_CLK 	    RCC_APB2Periph_GPIOA		
#define RCK_GPIO_PIN		GPIO_Pin_1			        

#define SCLK_GPIO_PORT    	GPIOA			             
#define SCLK_GPIO_CLK 	    RCC_APB2Periph_GPIOA		
#define SCLK_GPIO_PIN		GPIO_Pin_2			 

#define DIO_1    	GPIO_SetBits(DIO_GPIO_PORT, DIO_GPIO_PIN)
#define DIO_0    	GPIO_ResetBits(DIO_GPIO_PORT, DIO_GPIO_PIN)

#define RCK_1    	GPIO_SetBits(RCK_GPIO_PORT, RCK_GPIO_PIN)
#define RCK_0    	GPIO_ResetBits(RCK_GPIO_PORT, RCK_GPIO_PIN)

#define SCLK_1      GPIO_SetBits(SCLK_GPIO_PORT, SCLK_GPIO_PIN)
#define SCLK_0      GPIO_ResetBits(SCLK_GPIO_PORT, SCLK_GPIO_PIN)

4.2  引脚初始化

        这里对PA0、PA1、PA2进行初始化,期间使用的宏定义,要想更改引脚只需更改宏定义引脚即可(注意:若是使用其他外设时钟例如PB,不要忘记对其进行使能)。

void HC595_GPIO_Config(void)
{		
	/*定义一个MAX7219_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure;

	/*开启LED相关的GPIO外设时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
	/*选择要控制的GPIO引脚*/
	GPIO_InitStructure.GPIO_Pin = DIO_GPIO_PIN;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(DIO_GPIO_PORT, &GPIO_InitStructure);	
	
	GPIO_InitStructure.GPIO_Pin = RCK_GPIO_PIN;
	GPIO_Init(RCK_GPIO_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = SCLK_GPIO_PIN;
	GPIO_Init(SCLK_GPIO_PORT, &GPIO_InitStructure);
}

4.3  数据写入移位寄存器

        将从DS上的数据串行移入移位寄存器,需要时钟驱动,即引脚11 (SHCP)每产生一个上升沿, DS上的数据往移位寄存器送入一位,先送高位,后送低位,经过8个上升沿后, 8bit全部送入移位寄存器了。

void Write_74HC595_byte(uint8_t DATA)         
{
    uint8_t i;    

    // 遍历每一位,从最高位到最低位
    for(i = 8; i > 0; i--)  // 修正循环条件
    {                                  
        // 设置数据线的电平
        if(DATA & 0x80)
        {
            DIO_1;  // 设置数据线为高电平
        }
        else
        {
            DIO_0;  // 设置数据线为低电平
        }

        // 左移数据以处理下一个比特
        DATA = DATA << 1;

        // 生成时钟脉冲
        SCLK_0;
        SCLK_1;                        
    }                                 
}

        对于以下代码为什么这样,可以先了解一下与运算符:

        // 设置数据线的电平
        if(DATA & 0x80)
        {
            DIO_1;  // 设置数据线为高电平
        }
        else
        {
            DIO_0;  // 设置数据线为低电平
        }

C语言菜鸟入门·运算符(算数运算符,关系运算符,逻辑运算符,位运算符,赋值运算符,三目运算符)详细介绍_算术运算符,逻辑运算符和关系运算符-CSDN博客

DATA & 0x80,这会将 DATA  的最高位与 0x80 进行按位与操作。

如果DATA 的最高位为 1,则结果会是 0x80 ,即10000000(非零值)。

如果DATA 的最高位为 0,则结果会是 0x00 (零值)。

4.4  共阳极数码管编码

unsigned char  LED_DIS[] = 
{// 0	 1	  2	   3	4	 5	  6	   7	8	 9	  A	   b	C    d	  E    F    -
	0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
};

4.5  数据位选

        首先,通过调用Write_74HC595_byte();函数,获取对应的要显示数据,然后通过Write_74HC595_byte(1 << (3 - Addr));生成一个位掩码,用于选择显示器的特定位置。

假设 Addr 的值是 0 到 3 之间的整数,它会生成一个 8 位值,其中只有一个位被设置为 1,其余为 0。例如,Addr 为 0 时生成的掩码是 00001000Addr 为 1 时生成的掩码是 00000100,以此类推。

//Addr:显示位置,Dat:显示的数据
void Nixie_Display (uint8_t Addr, uint8_t Dat)
{
    // 将数据转换为对应的七段显示器的编码
    Write_74HC595_byte(LED_DIS[Dat]);

    // 选择要显示的位,通过左移来选择对应的显示位置
    Write_74HC595_byte(1 << (3 - Addr)); 

    // 产生一个脉冲来更新显示
    RCK_0;
    RCK_1;
}

4.6  主函数

        此时数码管第1位显示1,第二位显示2以此类推:

#include "stm32f10x.h"
#include "74HC595.h" 
#include "delay.h"

int main(void)
{	
	uint8_t n;
	HC595_GPIO_Config();

	while (1)
	{
        Nixie_Display (0,1);
        Nixie_Display (1,2);
        Nixie_Display (2,3);
        Nixie_Display (3,4);
	}
}

完整代码: 

​​​​​​​STM32+74HC595驱动4位数码管显示0-3.zip资源-CSDN文库

STM32学习笔记_时光の尘的博客-CSDN博客

  • 42
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光の尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值