STM32三线检测八个按键(74HC165)

STM32三线检测八个按键是典型的IO扩展应用(并转串),思路和学习51单片机时一致,下面直接上图和代码!
在这里插入图片描述
按键为检测低电平
在这里插入图片描述
简述:

1.74HC165使用1、2、9脚,15脚可直接接地
2.按键低电平为按下
PA1-> SL 并行数据加载
PA2-> CLK 时钟
PA3-> DAT 串行数据输出

代码:

#include "74HC165.h"
#include "delay.h"

void Init_74HC165(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 

	GPIO_InitStructure.GPIO_Pin   = SL_PIN|CLK_PIN;				 
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; 		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
	GPIO_Init(PORT_74HC165, &GPIO_InitStructure);	
	
	GPIO_InitStructure.GPIO_Pin   = DAT_PIN;				 
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU; 		
	GPIO_Init(PORT_74HC165, &GPIO_InitStructure);	

}

u8 ReadByte_165(void)
{
	u8 i,dat=0;
	CLK=1;
	Latch_165();
	for(i=0;i<8;i++)
	{
		dat=dat<<1;
		if(DAT==1)
			dat=dat+1;
		CLK=0;
		delay_us(1);
		CLK=1;
	}
	CLK=0;
	return ~dat;
}

void Latch_165(void)
{
	SL=0;
	delay_us(1);
	SL=1;	
}

u8 Scan_Key(void)  //该函数仅支持1次按下1个按键
{
	u8 key;
	key=ReadByte_165();
	if(key==0)
		;
	else
		{
			switch(key)
			{
				case 1:
					key=1;
				break;
				case 2:
					key=2;
				break;
				case 4:
					key=3;
				break;
				case 8:
					key=4;
				break;
				case 16:
					key=5;
				break;
				case 32:
					key=6;
				break;
				case 64:
					key=7;
				break;
				case 128:
					key=8;
				break;
				default:
					key=0;
				break;
			}
		}
		return key;
}

头文件:

#ifndef __74HC165_H
#define __74HC165_H	 
#include "sys.h"

#define PORT_74HC165 GPIOA
#define SL PAout(1)						//SL
#define SL_PIN GPIO_Pin_1

#define CLK PAout(2)					 //CLK
#define CLK_PIN GPIO_Pin_2		

#define DAT_PIN GPIO_Pin_3		
#define DAT GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)//DAT

void Init_74HC165(void);
u8 ReadByte_165(void)
void Latch_165(void);
u8 Scan_Key(void);
#endif


STM32 使用2个 74HC595 级联控制6位共阳极数码管显示时钟,74HC595三个引脚SH-CP,DS,ST-CP分别连接STM32103C8T6,PAO,PAI,PA2;蜂鸣器电路使用PA10(GPIO口),高电平(5V)截止,低电平(0V)导通;DS1302实时时钟电路通过SPI接口与STM32通信,SCLK、IO、RST引脚分别连接至PC2、PC1、PC0;确保断电后时间数据持续保存。按键电路GPIO口使用PA12,PA13,PA14,NRST(4个独立按键(MODE、ADJ、SET,IWDG)连接至PA12,PA13,PA14,NRST采用10kΩ上拉电阻与0.1μF电容构成硬件消抖电路。功能扩展设计 模式切换与功能分配 短按MODE键:循环切换显示模式(时间 → 日历 → 闹钟时间 → 时间)。 长按MODE键(>1s):进入闹钟开关状态,数码管显示“On”或“Off”,通过ADJ键切换开关。 短按ADJ键:在校时或闹钟设置模式下切换调整位(时→分→秒)。 长按ADJ键(>0.5s):快速递增当前选中位数值。 短按SET键:确认当前设置并退出至正常模式。 长按IWDG键:按下按键电容充电产生低电平脉冲触发复位,按下时强制拉低NRST电平。硬件复位逻辑结合看门狗定时器(IWDG) 闹钟设置流程 步骤1:短按MODE键切换至“闹钟时间”显示模式(显示“AL-HH:MM”)。 步骤2:长按ADJ键进入闹钟时间编辑状态,数码管当前调整位(小时或分钟)闪烁。 步骤3:短按ADJ键切换调整位,长按ADJ键快速调整数值(0-23小时,0-59分钟)。 步骤4:短按SET键保存闹钟时间至DS1302的RAM区域(地址0x10-0x11),退出编辑模式。 时间校准增强 进入校时:长按ADJ键3秒,进入时间校准模式,数码管显示“CAL”提示。 调整逻辑: 短按ADJ键循环选择调整项:年 → 月 → 日 → 时 → 分 → 秒。 长按ADJ键以10为单位快速递增(如月份从1→12循环)。 保存退出:短按SET键将调整后的时间写入DS1302并同步系统时间。 硬件电路实现 按键接口:PA0(MODE)、PA1(ADJ)、PA2(SET)配置为上拉输入,硬件消抖电路(10kΩ上拉电阻 + 0.1μF电容)。 状态指示:通过数码管闪烁(500ms周期)提示当前编辑状态,如闹钟设置时小时位闪烁。
03-31
<think>好的,我现在要帮用户解决关于如何使用STM32控制两个74HC595级联驱动6位共阳极数码管显示时钟,同时集成蜂鸣器、DS1302实时时钟模块和按键功能的问题。首先,我需要理清用户的需求,然后逐步分析各个模块的实现方法。 首先,用户的需求是使用STM32控制两个74HC595级联驱动6位数码管显示时钟,同时还要集成蜂鸣器、DS1302实时时钟模块,以及四个按键(MODE/ADJ/SET/IWDG)的功能分配和硬件消抖电路。这需要综合考虑硬件连接和软件设计。 先从硬件设计开始。用户提到的是共阳极数码管,所以每个数码管的公共端需要接高电平,而段选信号则由74HC595控制。因为要驱动6位数码管,可能需要两个74HC595级联,一个负责段选,另一个负责位选?或者两个级联后共同处理段选和位选?需要确认。通常级联两个74HC595可以扩展输出位数,每个芯片有8位输出,两个级联就是16位。6位数码管需要6个位选信号和8个段选信号(假设是7段加小数点),所以可能需要使用其中一个74HC595控制段选,另一个控制位选?或者将两个级联后的16位输出分为段选和位选?例如,每个数码管的段选需要8位,6位的话需要8*6=48位?这显然不现实,所以通常采用动态扫描的方式,即每次只点亮一个数码管,快速切换,利用视觉暂留效果。这时候,位选信号控制哪个数码管被点亮,而段选信号控制显示的内容。所以,假设使用两个74HC595,一个用于输出段选信号(8位),另一个用于输出位选信号(6位中的某几位,可能需要译码),或者两个级联后的16位输出,其中高8位作为段选,低6位作为位选?或者可能更复杂。 接下来是DS1302实时时钟模块的SPI接口通信。DS1302通常使用三线接口(CE、I/O、SCLK),而STM32需要模拟这个时序,或者使用硬件SPI?需要查阅DS1302的数据手册,确认通信协议。DS1302的接口不是标准的SPI,可能需用GPIO模拟时序。 蜂鸣器部分比较简单,使用PA10作为GPIO输出,通过高低电平控制蜂鸣器的开关。需要确认蜂鸣器是有源还是无源的,决定是否需要PWM驱动。 按键部分有四个按键:MODE、ADJ、SET、IWDG。需要分配对应的GPIO输入,同时实现硬件消抖电路,比如RC滤波电路或者使用施密特触发器。软件部分也需要去抖动处理,但用户要求硬件消抖,所以重点在电路设计。 然后是软件设计,包括主程序流程、各模块的驱动函数、中断处理等。需要考虑如何通过74HC595级联输出数据,如何动态扫描数码管,如何读取DS1302的时间数据,处理按键输入,以及蜂鸣器控制。 现在需要分模块详细分析: 1. 74HC595级联驱动数码管: - 级联方式:两个74HC595级联,通过串行数据输入(SER),移位时钟(SRCLK)和锁存时钟(RCLK)控制。数据先输入到第一个595,再传到第二个。每个595有8位输出,级联后共有16位输出。假设用其中8位作为段选(a-g和dp),另外6位作为位选(选择6位数码管中的一个)。但这样的话,需要每个位选信号对应一个数码管的公共阳极,因为是共阳,所以位选信号应为高电平有效。但595的输出是灌电流还是拉电流?需要确认数码管的连接方式。例如,位选通过PNP三极管驱动,当595输出高电平时,三极管导通,数码管公共端接VCC,此时段选信号为低电平点亮对应的段。因此,段选信号需要低电平有效,而位选信号通过595输出高电平选通对应的数码管。 2. DS1302接口: - DS1302需要CE、SCLK、I/O三个引脚。STM32需要用GPIO模拟其时序。DS1302的通信协议包括单字节读写和多字节读写,需按照时序图编写读写函数。 3. 按键硬件消抖: - 每个按键连接到GPIO输入,并加上RC低通滤波电路(如10k电阻和0.1uF电容),在按键两端并联电容,或者使用施密特触发器芯片,如74HC14,以消除抖动。硬件消抖后,软件中可能仍需简单延时检测。 4. 蜂鸣器控制: - PA10配置为推挽输出,控制蜂鸣器的通断。如果是无源蜂鸣器,可能需要PWM产生不同频率的声音,但用户需求中未明确,可能只需开关控制。 5. 独立看门狗(IWDG): - 用户提到IWDG键,可能是指通过按键触发喂狗,或者配置独立看门狗功能,需要在软件中初始化IWDG,并定期刷新,否则系统复位。但具体如何与按键关联需要明确。 接下来,需要将这些模块整合到STM32的程序设计中,包括初始化各个外设,编写驱动函数,主循环中的任务调度(如读取时间、更新显示、扫描按键、处理蜂鸣器等)。 可能的难点包括: - 74HC595级联的数据传输,确保数据正确移位到两个芯片中。 - 动态扫描数码管的刷新频率,避免闪烁。 - DS1302的时序模拟,确保时间数据正确读取和写入。 - 按键处理,包括消抖和功能分配(如MODE切换显示模式,ADJ调整时间,SET确认设置等)。 另外,需要确认STM32的时钟配置,确保各模块的时序要求得到满足,如SPI通信速率、动态扫描的频率等。 总结,整个设计需要分硬件连接和软件驱动两部分,逐步实现各个模块的功能,然后整合测试。可能需要多次调试,特别是级联的74HC595和数码管动态显示部分,容易出现显示错乱或亮度不均的问题,需调整扫描频率和延时。</think>以下是基于STM32控制74HC595级联驱动共阳极数码管显示时钟的完整设计方案,包含DS1302实时时钟、蜂鸣器及按键功能的实现: ### 一、硬件设计方案 #### 1. 74HC595级联驱动电路 $$ \begin{aligned} &\text{级联配置:} \\ &\text{STM32 SPI1\_MOSI(PA7)} \rightarrow 第一片595(SER) \\ &\text{第一片595(QH')} \rightarrow 第二片595(SER) \\ &\text{公共时钟SCK(PA5)} \rightarrow 两片595(SRCLK) \\ &\text{锁存信号RCK(PA6)} \rightarrow 两片595(RCLK) \\ &\text{共阳极数码管位选端接595输出,段选端需串联220Ω电阻} \end{aligned} $$ #### 2. DS1302接口电路 采用三线制连接: - **CE** -> PB0 - **I/O** -> PB1 - **SCLK** -> PB2 - **VCC**连接3.3V备份电池[^2] #### 3. 蜂鸣器电路 - **PA10** -> NPN三极管基极 - 三极管集电极接5V有源蜂鸣器 - 发射极接地 #### 4. 按键电路 采用RC硬件消抖设计: ``` VCC | 10kΩ | 按键--|--> GPIO | 100nF | GND ``` - **MODE** -> PC0 - **ADJ** -> PC1 - **SET** -> PC2 - **IWDG** -> PC3 ### 二、软件设计方案 #### 1. 主程序流程图 ```mermaid graph TD A[系统初始化] --> B[外设初始化] B --> C[读取DS1302时间] C --> D[数码管动态显示] D --> E{按键扫描} E -->|MODE| F[模式切换] E -->|ADJ| G[数值调整] E -->|SET| H[确认设置] E -->|IWDG| I[喂狗操作] F --> C G --> C H --> C I --> C ``` #### 2. 关键代码实现 **74HC595驱动代码:** ```c void HC595_SendData(uint16_t data) { HAL_GPIO_WritePin(RCK_GPIO_Port, RCK_Pin, GPIO_PIN_RESET); for(uint8_t i=0; i<16; i++){ HAL_GPIO_WritePin(SER_GPIO_Port, SER_Pin, (data & 0x8000)?GPIO_PIN_SET:GPIO_PIN_RESET); HAL_GPIO_WritePin(SRCLK_GPIO_Port, SRCLK_Pin, GPIO_PIN_SET); data <<= 1; HAL_GPIO_WritePin(SRCLK_GPIO_Port, SRCLK_Pin, GPIO_PIN_RESET); } HAL_GPIO_WritePin(RCK_GPIO_Port, RCK_Pin, GPIO_PIN_SET); } ``` **DS1302驱动代码:** ```c uint8_t DS1302_ReadByte(void) { uint8_t data = 0; for(uint8_t i=0; i<8; i++){ HAL_GPIO_WritePin(DS1302_SCLK_GPIO_Port, DS1302_SCLK_Pin, GPIO_PIN_RESET); if(HAL_GPIO_ReadPin(DS1302_IO_GPIO_Port, DS1302_IO_Pin)) data |= (1<<i); HAL_GPIO_WritePin(DS1302_SCLK_GPIO_Port, DS1302_SCLK_Pin, GPIO_PIN_SET); } return data; } ``` ### 三、功能分配 1. **MODE键**:切换显示模式(时/分/秒、年月日) 2. **ADJ键**:在设置模式下调整数值 3. **SET键**:进入/退出设置模式 4. **IWDG键**:手动触发独立看门狗喂狗操作 ### 四、硬件优化建议 1. 数码管位选端增加三极管驱动电路 2. 在74HC595输出端加入74HC245总线驱动器提升驱动能力 3. DS1302时钟线并联100pF滤波电容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值