STM32单片机入门学习——第8节: [3-4] 按键控制LED光敏传感器控制蜂鸣器

news2025/4/11 21:08:40

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.04.02

STM32开发板学习——第8节: [3-4] 按键控制LED&光敏传感器控制蜂鸣器

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、按键控制LED
  • 二、光敏模块控制蜂鸣器
  • 问题
  • 总结

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始32单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习32单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技32单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。另外我也购买了江科大的学习套间。
   原理图如下
1、开发板原理图
在这里插入图片描述
2、STM32F103C6和51对比
在这里插入图片描述
3、STM32F103C6核心板
在这里插入图片描述

视频中的都用这个开发板来实现,如果有资源就利用起来。另外也计划实现江协科技的套件。

下图是实物图
在这里插入图片描述

引用

【STM32入门教程-2023版 细致讲解 中文字幕】
还参考了下图中的书籍:
STM32库开发实战指南:基于STM32F103(第2版)
在这里插入图片描述
数据手册

解答和科普

一、按键控制LED

在这里插入图片描述
按键是第一种接法,按键接地表示按键按下为低电平,GPIO配置为上拉输入,LED分别接在在PA1和PA2两个口上,LED一端接GPIO口,另一端接VCC,就是低电平点亮的接法,都是随意的看自己的。

如果把这两部分驱动代码都混在主函数里面,代码就太乱了,不容易移植,所以对于这种驱动代码,我们要封装起来,单独放在另外的.c和.h文件里,这就是模块化编程的方式。
在这里插入图片描述
LED.C用来存放驱动程序的主体代码;
LED.h用来存放这个驱动可以对外提供的函数或变量的声明。
在这里插入图片描述
注意空行结尾

CTRL+alt+空格:代码提示
在这里插入图片描述
注意空行结尾

在这里插入图片描述
在这里插入图片描述

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef   GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1| GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);	
	
	GPIO_SetBits(GPIOA,	GPIO_Pin_1 | GPIO_Pin_2);
	
}

void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);

}

void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_1);

}
void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);

}

void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_2);

}

也可以定义一个LEDset函数,然后定义两个参数,一个参数选择操作那个灯,另一个参数选择开还是关。

#ifndef		__LED_H
#define 	__LED_H

void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED2_ON(void);
void LED2_OFF(void);


#endif


main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"

int main(void)
{
	
	LED_Init();
	
	while(1)
	{
		 LED1_ON();
		 Delay_ms(500);
		 LED1_OFF();
		 Delay_ms(500);

	}
}

实验现象

封装后控制LED闪烁


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样看来应该是地址,GPIOA
Key初始化:
在这里插入图片描述

在这里插入图片描述

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

1、GPIO_ReadInputDataBit读取这里输入数据寄存器的某一位;
2、GPIO_ReadOutputDataBit读取输出数据寄存器的某一位
3、GPIO_ReadInputData 读取整个输入数据寄存器
4、GPIO_ReadOutputData 读取整个输出数据寄存器

按键控制LED
K3控制LED1亮,K4控制LED1灭
1.main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t		KeyNum;			//作用域不同

int main(void)
{
								//优先使用自己的局部变量
	LED_Init();
	Key_Init();
	
	while(1)
	{
		KeyNum=Key_GetNum();
		if(KeyNum==1)
		{
			LED1_ON();
		}
		if(KeyNum==2)
		{
			LED1_OFF();
		}
		

	}
}

2.LED.C和LED.H

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef   GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1| GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);	
	
	GPIO_SetBits(GPIOA,	GPIO_Pin_1 | GPIO_Pin_2);
	
}

void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);

}

void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_1);

}
void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);

}

void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_2);

}

#ifndef		__LED_H
#define 	__LED_H

void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED2_ON(void);
void LED2_OFF(void);


#endif

3、Key.c和Key.h

#include "stm32f10x.h"                  // Device header
#include "Delay.h"


void  Key_Init(void)
{
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef   GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;			//读取按键选择上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

}


uint8_t Key_GetNum(void)
{
	uint8_t KeyNum	=0;
	if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==0);
		Delay_ms(20);
		KeyNum=1;
	}
	
	if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)==0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11)==0);
		Delay_ms(20);
		KeyNum=2;
	}
	
	return  KeyNum;
}
#ifndef    __KEY_H
#define    __KEY_H

void  Key_Init(void);
uint8_t Key_GetNum(void);

#endif

实验现象

按键控制LED灯

按键控制LED状态取反

void LED1_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==0)		//读取当前端口输出状态如果为0.就给它置1,否则为1,就置0
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
		
	}
	
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);
		
	}

}
void LED2_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)==0)		//读取当前端口输出状态如果为0.就给它置1,否则为1,就置0
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_2);
		
	}
	
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
		
	}

}
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t		KeyNum;			//作用域不同

int main(void)
{
								//优先使用自己的局部变量
	LED_Init();
	Key_Init();
	
	while(1)
	{
		KeyNum=Key_GetNum();
		if(KeyNum==1)
		{
			LED1_Turn();
		}
		if(KeyNum==2)
		{
			LED2_Turn();
		}
		

	}
}

实验现象:

按键控制LED状态取反

二、光敏模块控制蜂鸣器

接线图
在这里插入图片描述
1.main

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "Buzzer.h"
#include  "LightSensor.h"




int main(void)
{
	Buzzer_Init();
	LightSensor_Init();
	

	while(1)
	{
		if(LightSensor_Get()==1)
		{
			Buzzer_ON();
		}
		else
		{
			Buzzer_OFF();
		}
	
	}
}

2、Buzzer.C和.H

#include "stm32f10x.h"                  // Device header



void Buzzer_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef   GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);	
	
	GPIO_SetBits(GPIOB,	GPIO_Pin_1 | GPIO_Pin_2);
	
}

void Buzzer_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12)==0)		//读取当前端口输出状态如果为0.就给它置1,否则为1,就置0
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_12);
		
	}
	
	else
	{
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);
		
	}

}

void Buzzer_ON(void)
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);

}

void Buzzer_OFF(void)
{
	GPIO_SetBits(GPIOB,GPIO_Pin_12);

}

#ifndef  __BUZZER_H
#define  __BUZZER_H


void Buzzer_Init(void);
void Buzzer_Turn(void);
void Buzzer_ON(void);
void Buzzer_OFF(void);

#endif

3、LightSensor.C和.H

#include "stm32f10x.h"                  // Device header

void LightSensor_Init(void)
{
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef   GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;			//读取按键选择上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}


uint8_t  LightSensor_Get(void)
{
	
	return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);
	
}
#ifndef  __LIGHT_SENSOR_H
#define  __LIGHT_SENSOR_H

void LightSensor_Init(void);
uint8_t  LightSensor_Get(void);
#endif

暂时没有实验现象

问题

1、怎么控制外接的AD模块

在这里插入图片描述

总结

本节课主要学习了GPIO的输入,首先是按键的控制LED灯,还有就是硬件的模块化,尽量把每个硬件的驱动函数单独提取出来,进行封装模块化编程;封装到.C.H文件中,在主函数完成更重要的。就是如何配置GPIO口为输入进行配置。

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

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

相关文章

【JavaScript】十三、事件监听与事件类型

文章目录 1、事件监听1.1 案例:击关闭顶部广告1.2 案例:随机点名1.3 事件监听的版本 2、事件类型2.1 鼠标事件2.1.1 语法2.1.2 案例:轮播图主动切换 2.2 焦点事件2.2.1 语法2.2.2 案例:模拟小米搜索框 2.3 键盘事件2.3.1 语法2.3.…

通过ansible+docker-compose快速安装一主两从redis+三sentinel

目录 示例主机列表 架构参考 文件内容 安装脚本 ansible变量,需修改 ansible配置文件和主机清单,需修改 运行方式 验证故障转移master 涉及redis镜像和完整的脚本文件 示例主机列表 架构参考 文件内容 安装脚本 #!/bin/bashset -e export pa…

mysql docker容器启动遇到的问题整理

好几个月没折腾mysql的部署,弄了下,又遇到不少问题 问题一:Access denied for user ‘root‘‘172.18.0.1‘ docker容器启动后,本地navicat 连接报这个错误 查到两个方案,一个貌似是要让root用户能在任意ip地址&…

长短期记忆神经网络(LSTM)基础学习与实例:预测序列的未来

目录 1. 前言 2. LSTM的基本原理 2.1 LSTM基本结构 2.2 LSTM的计算过程 3. LSTM实例:预测序列的未来 3.1 数据准备 3.2 模型构建 3.3 模型训练 3.4 模型预测 3.5 完整程序预测序列的未来 4. 总结 1. 前言 在深度学习领域,循环神经网络&…

C++多继承

可以用多个基类来派生一个类。 格式为: class 类名:类名1,…, 类名n { private: … ; //私有成员说明; public: … ; //公有成员说明; protected: … ; //保护的成员说明; }; class D: public A, protected B, private C { …//派…

【深度学习新浪潮】DeepSeek近期的技术进展及未来动向

一、近期技术进展 模型迭代与性能提升 DeepSeek-V3-0324版本更新:2025年3月24日发布,作为V3的小版本升级,参数规模达6850亿,采用混合专家(MoE)架构,激活参数370亿。其代码能力接近Claude 3.7,数学推理能力显著提升,且在开源社区(如Hugging Face)上线。DeepSeek-R1模…

工业4.0时代下的人工智能新发展

摘要:随着德国工业4.0时代以及中国制造2025的提出,工业智能化的改革的时代正逐渐到来,然而我国整体工业水平仍然处于工业2.0水平。围绕工业4.0中智能工厂、智能生产、智能物流这三大主题,结合国内外研究现状,对人工智能…

监控易一体化运维:高性能与易扩展,赋能运维新高度

在当今数字化时代,云技术、大数据、智慧城市等前沿科技蓬勃发展,企业和城市对 IT 基础设施的依赖程度与日俱增。在这样的大环境下,运维系统的高性能与易扩展性对于保障业务稳定运行和推动发展的关键意义。今天,为大家深入剖析监控…

机器学习stats_linregress

import numpy as np from scipy import stats# r stats.linregress(xs, ys) 是一个用于执行简单线性回归的函数,通常来自 scipy.stats 库。# 具体含义如下:# stats.linregress:执行线性回归分析,拟合一条最佳直线来描述两个变量 …

Linux系统01---指令

目录 学习的方法 Linux 系统介绍 2.1 Unix 操作系统(了解) 2.2 Linux 操作系统(了解) 2.3 Linux 操作系统的主要特性(重点) 2.4 Linux 与 Unix 的区别与联系 2.5 GUN 与 GPL(了解&#…

【蓝桥杯14天冲刺课题单】Day 8

1.题目链接:19714 数字诗意 这道题是一道数学题。 先考虑奇数,已知奇数都可以表示为两个相邻的数字之和,2k1k(k1) ,那么所有的奇数都不会被计入。 那么就需要考虑偶数什么情况需要被统计。根据打表,其实可以发现除了…

DeepSeek 开源的 3FS 如何?

DeepSeek 3FS(Fire-Flyer File System)是一款由深度求索(DeepSeek)于2025年2月28日开源的高性能并行文件系统,专为人工智能训练和推理任务设计。以下从多个维度详细解析其核心特性、技术架构、应用场景及行业影响&…

通过 Docker Swarm 集群探究 Overlay 网络跨主机通信原理

什么是Overlay网络, 用于解决什么问题 ? Overlay网络通过在现有网络之上创建一个虚拟网络层, 解决不同主机的容器之间相互通信的问题 如果没有Overlay网络,实现跨主机的容器通信通常需要以下方法: 端口映射使用宿主机网络模式 这些方法牺牲了容器网络…

HarmonyOS NEXT开发进阶(十四):HarmonyOS应用开发者基础认证试题集汇总及答案解析

文章目录 一、前言二、判断题(134道)三、单选题(210道)四、多选题(123道)五、拓展阅读 一、前言 鸿蒙原生技能学习阶段,通过官方认证的资格十分有必要,在项目实战前掌握基础开发理论…

MSVC编译遇到C2059、C2143、C2059、C2365、C2059等错误的解决方案

MSVC编译时,遇到如下错误: c:\program files (x86)\windows kits\10\include\10.0.18362.0\um\msxml.h(1842): error C2059: 语法错误:“常数” [D:\jenkins_home\workspace\xxx.vcxproj] c:\program files (x86)\windows kits\10\include\10.0.18362.0…

AI重塑云基础设施,亚马逊云科技打造AI定制版IaaS“样板房”

AI正在彻底重塑云基础设施。 IDC最新《2025年IDC MarketScape:全球公有云基础设施即服务(IaaS)报告》显示,AI正在通过多种方式重塑云基础设施,公有云IaaS有望继续保持快速增长,预计2025年全球IaaS的整体规…

Linux系统之systemctl管理服务及编译安装配置文件安装实现systemctl管理服务

目录 一.systemctl 管理服务 1.systemctl管理 2.设置服务卡机自启动或开机不启动 二.编译安装配置文件编写使得可以使用systemctl管理 1、编写配置文件原因 2、添加配置文件实现systemctl管理服务 一.systemctl 管理服务 1.systemctl管理 基本格式: systemc…

【NLP 52、多模态相关知识】

生活应该是美好而温柔的,你也是 —— 25.4.1 一、模态 modalities 常见: 文本、图像、音频、视频、表格数据等 罕见: 3D模型、图数据、气味、神经信号等 二、多模态 1、Input and output are of different modalities (eg: tex…

Element Plus 常用组件

2025/4/1 向全栈工程师迈进!!! 常见Element Plus组件的使用,其文章中“本次我使用到的按钮如下”是我自己做项目时候用到的,记录以加强记忆。阅读时可以跳过。 一、Button按钮 1.1基础按钮 在element plus中提供的按…

2025年优化算法:真菌生长优化算法(Fungal Growth Optimizer,FGO)

真菌生长优化算法(Fungal Growth Optimizer,FGO) 是发表在中科院一区期刊“ARTIFICIAL INTELLIGENCE REVIEW”(IF:6.7)的2025年3月智能优化算法 01.引言 Fungal Growth Optimizer (FGO) 是一种基于真菌生长行为的元启发式优化算法…