HC595级联原理及实例 - STM32

        74HC595的最重要的功能就是:串行输入,并行输出。其次,74HC595里面有2个8位寄存器:移位寄存器、存储寄存器。74HC595的数据来源只有一个口,一次只能输入一个位,那么连续输入8次,就可以积攒为一个字节了。

引脚图

14脚:DIN(SER),串行数据输入引脚

13脚:OE,  输出使能控制脚,它是低电才使能输出,所以接GND

12脚:RCK,存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。

11脚:SCK,移位寄存器时钟引脚,上升沿时,移位寄存器中的bit 数据整体后移,并接受新的bit(从SER输入)。

10脚:SCLR,低电平时,清空移位寄存器中已有的bit数据,一般不用,接高电平即可。

9 脚 :串行数据出口引脚。当移位寄存器中的数据多于8bit时,会把已有的bit“挤出去”,就是从这里出去的。用于595的级联。

Qx:并行输出引脚

使用参数

VCC:2V~6V,5V最好

I Qn:+- 35mA

移位寄存器

74HC595的14脚:DIN,是串行数据输入口。595的数据来源只有这一个口,一次只能输入一个位,那么连续输入8次,就可以积攒为一个字节了。

74HC595的11脚,(shift register clock input) 移位寄存器时钟引脚。上升沿有效。
首先我们要介绍这个引脚的作用,当一个新的位数据要进来时,已经进入的位数据就在移位寄存器时钟脉冲的控制下,整体后移,让出位置。

上升沿:电平从低到高的那个过程。移位寄存器时钟在上升沿这个过程中才起作用。

存储寄存器

595是怎么将移位寄存器的数据转移到存储寄存器。存储寄存器是直接和8个输出引脚相通的,将移位寄存器的数据转移到存储寄存器后,Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 就可以接收到我们开始输入的一个字节的数据。所谓存储寄存器,就是数据可以存在这个寄存器中,并不会随着一次输出就消失,只要595不断电,也没有新的数据从移位寄存器中过来,数据就一直不变且有效。新的数据过来后,存储寄存器中的数据就会被覆盖更新。

74HC595的12脚: (storage register clock input ) 存储寄存器时钟
数据从位移寄存器转移到存储寄存器,也是需要时钟脉冲驱动的,这就是12脚的作用。它也是上升沿有效。

74HC595级联

通过上面的介绍,见识到595的厉害了吧。138译码器通过3个输入口控制8个输出口,而且还只能是特定的8个输出值,而595只用了一个输入口就可以输任意的8位数据,可谓短小精悍。

你觉的1位控制8位输出还不够?

在上面的程序中用到的9脚,没用起作用,如果要让2个595串联起来的话,就需要它了。想一下,我们将移位寄存器的8个位填满后,再往移位寄存器中塞一个会怎么样?也许你想到了。对!移位寄存器的最后一个位数据会被挤出去,从哪里出去?就是从9脚输出的。如果我们把第一个595的9脚连接到第二个的串行数据输入脚SER,那么,就形成了595的级联。这样,如果我们用2个595组合成了一个新的超级595,这个超级595的移位寄存器和存储寄存器的容量都翻倍了,1口控制16口,有木有!你还可以继续级联下去!

74HC595级联实例

#ifndef __HC_595_H__
#define __HC_595_H__	#include "stm32h7xx_hal.h"// HC595的16位输出端定义位号
// Q0 - 0 .....Q15 -15
#define DIO_HC_A0           (6)
#define DIO_HC_B0           (7)
#define DIO_HC_C0           (0)
#define DIO_HC_A1           (15)
#define DIO_HC_B1           (8)
#define DIO_HC_C1           (1)
#define DIO_HC_A2           (10)
#define DIO_HC_B2           (13)
#define DIO_HC_C2           (14)
/* RLY */
#define DIO_RLY0            (5)
#define DIO_RLY1            (2)
/* S1 S2 */
#define DIO_S1              (11)
#define DIO_S2              (12)
/* CUR */
#define DIO_CUR             (9)/*----------------------------------------- HC595 引脚配置宏 -----------------------------------------------*/#define HC_595_DIN_ENABLE     		 __HAL_RCC_GPIOE_CLK_ENABLE()			// 使能DIN引脚时钟
#define HC_595_DIN_PORT   			 GPIOE                 					// DIN引脚端口
#define HC_595_DIN_PIN     		 	 GPIO_PIN_1  							// DIN引脚#define HC_595_RCK_ENABLE     		 __HAL_RCC_GPIOE_CLK_ENABLE()			// 使能RCK引脚时钟
#define HC_595_RCK_PORT   			 GPIOE                 					// RCK引脚端口
#define HC_595_RCK_PIN     		 	 GPIO_PIN_3  							// RCK引脚#define HC_595_SCK_ENABLE     		 __HAL_RCC_GPIOE_CLK_ENABLE()			// 使能SCK引脚时钟
#define HC_595_SCK_PORT   			 GPIOE                 					// SCK引脚端口
#define HC_595_SCK_PIN     		 	 GPIO_PIN_2  							// SCK引脚#define HC_595_SCLR_ENABLE     		 __HAL_RCC_GPIOC_CLK_ENABLE()			// 使能SCLR引脚时钟
#define HC_595_SCLR_PORT   			 GPIOC                 					// SCLR引脚端口
#define HC_595_SCLR_PIN     		 GPIO_PIN_4  								// SCLR引脚/*-------------------------------------------- IO口操作 ---------------------------------------------------*/   #define HC_595_DIN(a)	if (a)	\HAL_GPIO_WritePin(HC_595_DIN_PORT, HC_595_DIN_PIN, GPIO_PIN_SET); \else		\HAL_GPIO_WritePin(HC_595_DIN_PORT, HC_595_DIN_PIN, GPIO_PIN_RESET)	#define HC_595_RCK(a)	if (a)	\HAL_GPIO_WritePin(HC_595_RCK_PORT, HC_595_RCK_PIN, GPIO_PIN_SET); \else		\HAL_GPIO_WritePin(HC_595_RCK_PORT, HC_595_RCK_PIN, GPIO_PIN_RESET)	#define HC_595_SCK(a)	if (a)	\HAL_GPIO_WritePin(HC_595_SCK_PORT, HC_595_SCK_PIN, GPIO_PIN_SET); \else		\HAL_GPIO_WritePin(HC_595_SCK_PORT, HC_595_SCK_PIN, GPIO_PIN_RESET)	#define HC_595_SCLR(a)	if (a)	\HAL_GPIO_WritePin(HC_595_SCLR_PORT, HC_595_SCLR_PIN, GPIO_PIN_SET); \else		\HAL_GPIO_WritePin(HC_595_SCLR_PORT, HC_595_SCLR_PIN, GPIO_PIN_RESET)	// 函数声明
void HC_595_GPIO_Config(void);
void HC_595_Send_Byte(unsigned short Q15_Q0);
void HC595_Write_QX(unsigned short index,unsigned short sta);#endif
#include "hc595.h"static unsigned short Q0_Q15_S = 0;/*****************************************************************************************
*	函数名: HC595_Delay
*	入口参数: t - 延时时间,以时钟周期数为单位
*	返回值: 无
*	函数功能: 简单延时函数
*	说明: 为了移植的简便性且对延时精度要求不高,所以不需要使用定时器做延时
******************************************************************************************/
void HC595_Delay(unsigned int t)
{while(t--); // 简单的循环延时,延时时间由入口参数 t 决定
}/*****************************************************************************************
*	函数名: HC_595_GPIO_Config
*	入口参数: 无
*	返回值: 无
*	函数功能: 初始化移位寄存器的 GPIO 口
*	说明: 配置数据输入引脚(DIN)、存储寄存器时钟引脚(RCK)、移位寄存器时钟引脚(SCK)和清除引脚(SCLR)为推挽输出模式,
*		 不带上下拉,速度配置为低速。然后将这些引脚初始化,并设置初始电平状态。
******************************************************************************************/
void HC_595_GPIO_Config(void)
{	GPIO_InitTypeDef GPIO_InitStruct = {0};// 初始化IO口时钟HC_595_DIN_ENABLE;HC_595_RCK_ENABLE;HC_595_SCK_ENABLE;	HC_595_SCLR_ENABLE;	// 配置DIN引脚GPIO_InitStruct.Pin 			= HC_595_DIN_PIN;GPIO_InitStruct.Mode 			= GPIO_MODE_OUTPUT_PP;	// 推挽输出GPIO_InitStruct.Pull 			= GPIO_NOPULL;			// 不带上下拉GPIO_InitStruct.Speed 			= GPIO_SPEED_FREQ_LOW;	// 低速HAL_GPIO_Init(HC_595_DIN_PORT, &GPIO_InitStruct);// 配置RCK引脚GPIO_InitStruct.Pin 			= HC_595_RCK_PIN;HAL_GPIO_Init(HC_595_RCK_PORT, &GPIO_InitStruct);		// 配置SCK引脚GPIO_InitStruct.Pin			= HC_595_SCK_PIN;HAL_GPIO_Init(HC_595_SCK_PORT, &GPIO_InitStruct);				// 配置SCLR引脚GPIO_InitStruct.Pin 			= HC_595_SCLR_PIN;GPIO_InitStruct.Pull 			= GPIO_PULLUP;			// 上拉HAL_GPIO_Init(HC_595_SCLR_PORT, &GPIO_InitStruct);// 初始化引脚状态HAL_GPIO_WritePin(HC_595_RCK_PORT, HC_595_RCK_PIN, GPIO_PIN_RESET);	// RCK输出低电平HAL_GPIO_WritePin(HC_595_SCK_PORT, HC_595_SCK_PIN, GPIO_PIN_RESET);	// SCK输出低电平HAL_GPIO_WritePin(HC_595_SCLR_PORT, HC_595_SCLR_PIN, GPIO_PIN_SET);	// SCLR输出高电平
}/*****************************************************************************************
*	函数名: HC_595_Send_Byte
*	入口参数: Q15_Q0 - 要发送的16位数据
*	返回值: 无
*	函数功能: 向移位寄存器发送一个16位数据
*	说明: 首先设置移位寄存器的控制引脚为初始状态,然后逐位发送数据,最后将数据加载到移位寄存器中。
******************************************************************************************/
void HC_595_Send_Byte(unsigned short Q15_Q0)
{// 设置移位寄存器的控制引脚初始状态HC_595_DIN(0);HC_595_RCK(0);HC_595_SCK(0);HC595_Delay(10);	for( int i = 0 ; i < 16 ; i ++ ){// 逐位发送数据HC_595_SCK(0);if( Q15_Q0 & 0x8000 ){HC_595_DIN(1);}else{HC_595_DIN(0);}HC595_Delay(1);		HC_595_SCK(1);		// 移位寄存器输入一个字节数据HC595_Delay(1);Q15_Q0 <<= 1;}// 将数据加载到移位寄存器中HC_595_RCK(1);			// 存储寄存器输入,Q1-Q15输出HC595_Delay(1);HC_595_RCK(0);HC_595_SCK(0);
}/* w_gpio_sem */
static unsigned char w_gpio_sem = 0;/*****************************************************************************************
*	函数名: HC595_Write_QX
*	入口参数: index - 输出引脚的编号,sta - 输出状态,1为高电平,0为低电平
*	返回值: 无
*	函数功能: 控制移位寄存器的输出引脚状态
*	说明: 根据输入的输出引脚编号和状态,更新移位寄存器中对应引脚的状态,并发送更新后的状态到移位寄存器。
******************************************************************************************/
void HC595_Write_QX(unsigned short index,unsigned short sta)
{// 检查是否有其他操作在进行if( w_gpio_sem ){return;}// 锁定w_gpio_sem = 1;// 检查输出引脚编号是否合法if( index > 16 ){return;}// 根据状态设置输出引脚状态if( sta ){Q0_Q15_S |= ( 1 << index );}else{Q0_Q15_S &=~ ( 1 << index );}// 更新移位寄存器中的输出状态HC_595_Send_Byte(Q0_Q15_S);// 解锁w_gpio_sem = 0;	
}
  1. HC_595_GPIO_Config: 初始化HC595芯片的GPIO口,包括数据输入引脚(DIN)、存储寄存器时钟引脚(RCK)、移位寄存器时钟引脚(SCK)和清除引脚(SCLR)。配置这些引脚为推挽输出模式,并设置初始电平状态。

  2. HC_595_Send_Byte: 向HC595芯片发送一个16位数据,通过移位寄存器将数据加载到芯片中,控制输出引脚的状态。

  3. HC595_Write_QX: 根据输入的输出引脚编号和状态,更新移位寄存器中对应引脚的状态,并通过 HC_595_Send_Byte 函数发送更新后的状态到移位寄存器。

  4. HC595_Delay: 简单的延时函数,用于产生一定时间的延时,以时钟周期数为单位。

注意 

HC595的DIN输入端输出的数据会从Q0开始,继续输入,之前的Q0数据会移位至Q1,一直循环。

完整的输入一个字节数据,假设输入的是unsigned char Q_byte =(高)1011 1111(低) 。因为HC_595_Send_Byte程序中是从高位开始发送的,最高位的数据再经过完整的一个字节循环后就被push到了Q7(很像队列)

Q0 = 1;Q1=1;Q2=1;Q3=1;Q4=1;Q5=1;Q6=0;Q7=1;

我们要改变Q0-Q7中的某个位做法:

假设改变Q3位,则把 (高)1011 0111(低)重新写入HC595中。

Q_byte = Q_byte & ~ (1<<3)  = 1011 1111 & 1111 0111 = 1011 0111;

这是一个595的情况,级联情况下同理,代码,处理的就是级联情况。所以应用HC595_Write_QX函数就可以操作Q0-Q15任意一个输出位的电平了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2807606.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Guitar Pro8.2吉他乐谱软件功能测评评价

Guitar Pro 8.2吉他乐谱软件全面评价 Guitar Pro 8.2作为一款吉他乐谱软件&#xff0c;已经得到了广大吉他手和音乐制作人的认可。作为软件评价专家&#xff0c;我对这款软件进行了全面的体验和分析&#xff0c;以下是我在易用性、功能丰富性、用户界面设计、稳定性以及性价比…

从事通讯信息类职业岗位的任职资格

通讯信息工程师&#xff0c;主要是移动核心网和固网核心网的工程切割和维护网络安全的专业工作&#xff0c;主要负责IP数据、省网和地域网络的维护。一切跟互联网打交道的事情&#xff0c;都跟这个有关系&#xff0c;都是通讯信息类岗位的工作。从事这种工作&#xff0c;需要付…

AI:135-基于卷积神经网络的艺术品瑕疵检测与修复

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

高通XBL阶段读取分区

【需求】&#xff1a; 在某些场景下&#xff0c;需要在XBL阶段读取分区数据&#xff0c;需要验证xbl阶段方案 这里主要以裸分区为例&#xff0c;比如oem分区。 1、创建一个1MB大小的oem.img&#xff0c;写入内容“test oem partition” 创建方式&#xff1a; dd if/dev/null …

【Linux】部署单机项目(自动化启动)---(图文并茂详细讲解)

目录 一 准备工作 1.1 连接服务器拷贝文件 1.2 解压 二 JDK安装 2.1 配置坏境变量 2.2 查看版本 三 Tomcat(自启动) 3.1 复制启动命令的位置 3.2 添加命令相关配置文件 3.2.1 配置jdk及tomcat目录 3.2.2 添加优先级 3.3 设置自启动命令 3.4 开放端口 四 My…

浅析Linux设备驱动:DMA内存映射

文章目录 概述DMA与Cache一致性DMA映射类型一致性DMA映射dma_alloc_coherent 流式DMA映射dma_map_single数据同步操作dma_direct_sync_single_for_cpudma_direct_sync_single_for_device 相关参考 概述 现代计算机系统中&#xff0c;CPU访问内存需要经过Cache&#xff0c;但外…

16. BI - 推荐系统之 ALS 实现

本文为 「茶桁的 AI 秘籍 - BI 篇 第 16 篇」 文章目录 对 MovieLens 进行电影推荐 Hi,你好。我是茶桁。 前面两节课的内容中&#xff0c;我们从矩阵分解到 ALS 原理&#xff0c;依次给大家讲解了推荐系统中的一个核心概念。 矩阵分解中拆矩阵的背后其实是聚类。就说 k 等于几…

IT廉连看——C语言——操作符

IT廉连看—操作符 c语言中有许多操作符&#xff0c;可以用于对变量进行各种不同的操作 一、算术操作符 - * / % 除了 % 操作符之外&#xff0c;其他的几个操作符可以作用于整数和浮点数。 对于 / 操作符如果两个操作数都为整数&#xff0c;执行整数除法。而只要有浮点…

tinymce问题处理

Vite构建工具下Tinymce踩坑指南 解决方案是在路劲前面增加/&#xff0c;这个跟上面链接有些区别&#xff0c;区别原因应该是如果路由采用的是createWebHashHistory则应该去掉/&#xff0c;如果是createWebHistory则应该加上/ 页面引用,一种异步加载&#xff0c;一种同步加载&…

供应链大数据:穿越经济迷雾的指南针

随着经济形势的变幻莫测&#xff0c;企业运营面临着前所未有的挑战。在这个充满不确定性的时代&#xff0c;供应链大数据如同一盏明亮的指南针&#xff0c;为企业提供精准的方向指引。下面&#xff0c;我们将深入探讨供应链大数据如何帮助企业洞察市场趋势、优化库存管理、降低…

猫毛过敏却想养猫时?如何缓解猫毛过敏?宠物空气净化器推荐

作为一个新养猫的主人&#xff0c;一开始并没有发现对猫咪过敏。直到养了半年才意识到这个问题&#xff0c;而此时我已经和猫咪有了深厚的感情。我不想放弃我的猫咪&#xff0c;但是留着它的话&#xff0c;我经常会因为流眼泪、打喷嚏、眼睛发红等过敏症状而影响日常生活&#…

神经网络系列---归一化

文章目录 归一化批量归一化预测阶段 测试阶段γ和β&#xff08;注意&#xff09;举例 层归一化前向传播反向传播 归一化 批量归一化 &#xff08;Batch Normalization&#xff09;在训练过程中的数学公式可以概括如下&#xff1a; 给定一个小批量数据 B { x 1 , x 2 , … …

WPF真入门教程29--MVVM常用框架之MvvmLight

1、MVVM模式回顾 关于mvvm模式的基础知识&#xff0c;请看这2个文章&#xff1a; WPF真入门教程23--MVVM简单介绍 WPF真入门教程24--MVVM模式Command命令 做过VUE开发或微信小程序开发的伙伴&#xff0c;就知道MVVM模式&#xff0c;核心就是数据驱动控件&#xff0c;全栈开…

软考 系统分析师系列知识点之需求获取(1)

所属章节&#xff1a; 第11章. 软件需求工程 第2节. 需求获取 需求获取是一个确定和理解不同的项目干系人的需求和约束的过程。需求获取是一件看上去很简单、做起来却很难的事情。需求获取是否科学、准备是否充分&#xff0c;对获取出来的结果影响很大&#xff0c;这是因为大部…

弱引用与C++智能指针

笔试题遇到了弱引用&#xff0c;但是C标准库是没有这个概念的&#xff0c;学了智能指针但是没有听说过弱引用&#xff0c;因此总结一下两者 学习视频链接来自B站 https://www.bilibili.com/video/BV1gV4y1G7fH?p2&vd_sourcefa4ef8f26ae084f9b5f70a5f87e9e41b智能指针 C的…

C语言:指针的进阶讲解

目录 1. 二级指针 1.1 二级指针是什么&#xff1f; 1.2 二级指针的作用 2. 一维数组和二维数组的本质 3. 指针数组 4. 数组指针 5. 函数指针 6. typedef的使用 7. 函数指针数组 7.1 转移表 1. 二级指针 如果了解了一级指针&#xff0c;那二级指针也是可以很好的理解…

基于django的购物商城系统

摘要 本文介绍了基于Django框架开发的购物商城系统。随着电子商务的兴起&#xff0c;购物商城系统成为了许多企业和个人创业者的首选。Django作为一个高效、稳定且易于扩展的Python web框架&#xff0c;为开发者提供了便捷的开发环境和丰富的功能模块&#xff0c;使得开发购物商…

第三百六十五回

文章目录 1. 概念介绍2. 方法与信息2.1 获取方法2.2 详细信息 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取设备信息"相关的内容&#xff0c;本章回中将介绍如何获取App自身的信息.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本…

【mysql】1000w数据量的分页查询SQL,如何优化提升性能?

文章目录 优化场景特别注意&#xff01;&#xff01;&#xff01;有前提&#xff0c;谨慎使用 优化场景 当表数据量非常大时&#xff0c;需要进行分页查询如果慢的时候&#xff0c;可以考虑优化下。 假设一页展示10条&#xff0c;查询第10w条后面的数据时候变慢了… 优化思路&…

【Java程序设计】【C00284】基于Springboot的校园疫情防控管理系统(有论文)

基于Springboot的校园疫情防控管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园疫情防控系统 本系统分为系统功能模块、管理员功能模块以及学生功能模块。 系统功能模块&#xff1a;在系统首页可以查…