STM32入门开发操作记录(三)——按键控制LED

news2024/9/21 10:48:55

目录

  • 一、模块化
  • 二、LED交替闪烁
    • 1. LED.c
    • 2. LED.h
    • 3. 主函数
  • 三、按键控制LED
    • 1. Key.c
    • 2. Key.h
    • 3. LED.c
    • 4. LED.h
    • 5. 主函数

一、模块化

  前篇介绍了如何向项目添加模块,本篇将进一步介绍模块的编写与封装。随着模块的增加,需要用到Manage Project Items,以便于快速新建目录、添加已有文件和调整目录次序请添加图片描述
  新建模块Hardware,与第一篇创建主函数文件同理,在目录下新建两组C语言源代码文件和头文件,拓展名分别为.c.h,并在Path Include完成路径添加
请添加图片描述

二、LED交替闪烁

  通过构建LED驱动模块简化灯控程序的代码。在A1A2端口接入LED,完成模块构建后运行主函数。

1. LED.c

#include "stm32f10x.h"

// LED端口初始化
void LED_Init(void)
{
	// 使能/失能APB2的外设时钟 -> 开启IO端口A时钟
	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;	// PA1和PA2引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 最大速度50MHz
	
	// 配置端口模式 -> 初始化GPIOA外设时钟
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

// 点亮A1灯
void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}

// 熄灭A1灯
void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
}

// 点亮A2灯
void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);			// 低电平:点亮LED2
}

// 熄灭A2灯
void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_2);			// 高电平:熄灭LED2
}

2. LED.h

#ifndef __LED_H		// 如果__LED_H未被定义,则执行关键字#define与#endif之间的命令
#define __LED_H

// 对模块外部声明以下函数可被调用
int main(void);		
void LED1_ON(void);
void LED1_OFF(void);
void LED2_ON(void);
void LED2_OFF(void);

#endif

3. 主函数

#include "stm32f10x.h"	// 器件模块
#include "Delay.h"		// 延时模块
#include "LED.h"		// LED驱动模块

// 双灯交替闪烁
int main(void)
{
	LED_Init();		// LED端口初始化
	
	while(1)
	{
		LED1_ON();
		LED2_OFF();
		Delay_ms(200);
		LED1_OFF();
		LED2_ON();
		Delay_ms(200);
	}
}

三、按键控制LED

  通过两个按键分别控制两个LED的亮灭,在A1A2端口接入LEDB1B11端口与零线之间接入按键。(除了上篇提过的J-Link调试端口,其他GPIO均可随意使用)
请添加图片描述

  按下按键时,开关闭合,电流导入零线B端输入低电平0松开按键时,开关断开,B端输入高电平1。由图可见,按键端口在常态下输入高电平,而在按键按下与松开的过程中存在电流波动,称为按键抖动,需要进行延时消除处理。
请添加图片描述

1. Key.c

  根据上文分析,按键按下一次产生的电平变化可被程序检测,并向LED驱动模块发出控制信号,其数据类型为uint8_t,即unsigned char.

#include "stm32f10x.h"
#include "Delay.h"

// 按键端口初始化
void Key_Init(void)
{
	// 使能/失能APB2的外设时钟 -> 开启IO端口B时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 配置结构体参数
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;			// 上拉输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;	// PBA1和PB11引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 最大速度50MHz
	
	// 配置端口模式 -> 初始化GPIOB外设时钟
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

// 监控按键信号
uint8_t Key_GetNum(void)
{
	// 初始化信号:松开
	uint8_t KeyNum = 0;
	
	// 检测到B1输入低电平
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==0)
	{
		Delay_ms(20);	// 消除按键抖动:按下
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==0);	// 持续按下,直至松开
		Delay_ms(20);	// 消除按键抖动:松开
		KeyNum = 1;		// B1端按键被按下了一次
	}
	
	// 检测到B11输入低电平
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==0)
	{
		Delay_ms(20);	// 消除按键抖动:按下
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==0);	// 持续按下,直至松开
		Delay_ms(20);	// 消除按键抖动:松开
		KeyNum = 2;		// B11端按键被按下了一次
	}

	return KeyNum;	// 发送按键信号
}

2. Key.h

#ifndef __KEY_H		// 如果__KEY_H未被定义,则执行关键字#define与#endif之间的命令
#define __KEY_H

// 对模块外部声明以下函数可被调用
void Key_Init(void);
uint8_t Key_GetNum(void);

#endif

3. LED.c

#include "stm32f10x.h"

// LED端口初始化
void LED_Init(void)
{
	// 使能/失能APB2的外设时钟 -> 开启IO端口A时钟
	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;	// PA1和PA2引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 最大速度50MHz
	
	// 配置端口模式 -> 初始化GPIOA外设时钟
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 端口电平初始化:高电平,熄灭
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);
}

// LED1开关:切换电平输入
void LED1_Turn(void)
{
	// A1端LED输出低电平:点亮
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);	// 熄灭
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	}
}

// LED2开关:切换电平输入
void LED2_Turn(void)
{
	// A1端LED输出低电平:点亮
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2)==0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_2);	// 熄灭
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);
	}
}

4. LED.h

#ifndef __LED_H		// 如果__LED_H未被定义,则执行关键字#define与#endif之间的命令
#define __LED_H

// 对模块外部声明该函数可被调用
void LED_Init(void);		
void LED1_Turn(void);
void LED2_Turn(void);

#endif

5. 主函数

#include "stm32f10x.h"	// 器件模块
#include "Delay.h"		// 延时模块
#include "LED.h"		// LED驱动模块
#include "Key.h"		// 按键监控模块

uint8_t KeyNum;		// 定义全局变量:按键信号

// 按键控制LED![请添加图片描述](https://i-blog.csdnimg.cn/direct/ab1af9a1642b4efea4369bcebdbb7544.jpeg)

int main(void)
{
	// 端口初始化
	LED_Init();
	Key_Init();
	
	while(1)
	{
		// 监控并接收按键端口信号
		KeyNum = Key_GetNum();
		
		// B1按键控制A1灯:按下一次切换亮灭
		if (KeyNum == 1)
		{
			LED1_Turn();
		}
		
		// B11按键控制A2灯:按下一次切换亮灭
		if (KeyNum == 2)
		{
			LED2_Turn();
		}
	}
}

请添加图片描述

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

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

相关文章

多终端文件互传

LocalSend - 下载下载LocalSend适用于Windows、macOS、Linux、Android和iOS。https://localsend.org/zh-CN/download

C语言 ——— 输入两个正整数,求出最小公倍数

目录 何为最小公倍数 题目要求 代码实现 方法一:暴力求解法(不推荐) 方法二:递乘试摸法(推荐) 何为最小公倍数 最小公倍数是指两个或者多个正整数(除了0以外)的最小的公共倍数…

浅谈RLHF---人类反馈强化学习

浅谈RLHF(人类反馈强化学习) RLHF(Reinforcement Learning fromHuman Feedback)人类反馈强化学习 RLHF是[Reinforcement Learning from Human Feedback的缩写,即从人类反馈中进行强化学习。这是一种结合了机器学习中…

Android Toast

Toast Toast是Android常用的简单控件,主要用来进行简短的信息提示,如图1所示。 图1 Toast效果图 Toast的基本用法很简单,不需要设置layout,只需要在程序中调用即可。Toast调用makeText()方法设置需要显示的界面、显示的内容、显…

简洁实用的原创度检测工具AntiPlagiarism NET 4.132

AntiPlagiarism NET是一个适用于Windows的程序,它允许您检查文本的唯一性和从不同Internet来源借用的存在。使用AntiPlagiarism NET,您可以: 将程序用于不同的目的该程序适用于学生、教师、记者、文案作者和其他需要检查其文本或其他作者文本…

SpringBoot实战:多表联查

1. 保存和更新公寓信息 请求数据的结构 Schema(description "公寓信息") Data public class ApartmentSubmitVo extends ApartmentInfo {Schema(description"公寓配套id")private List<Long> facilityInfoIds;Schema(description"公寓标签i…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 游乐园门票 (200分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 最新华为O…

4000厂商默认账号密码、默认登录凭证汇总.pdf

获取方式&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1F8ho42HTQhebKURWWVW1BQ?pwdy2u5 提取码&#xff1a;y2u5

C语言 ——— 调试的时候如何查看当前程序的变量信息

目录 调试前/后的调试窗口 ​编辑 调试窗口 --- 监视 调试窗口 --- 内存 调试窗口 --- 调用堆栈 调试前/后的调试窗口 调试前的调试窗口&#xff1a; 调试前的调试窗口是没有显示的&#xff0c;只有在调试的时候才会有相对应的调试窗口 调试后的调试窗口&#xff1a…

头歌资源库(31)象棋中马遍历棋盘的问题

一、 问题描述 二、算法思想 这是一个典型的深度优先搜索问题。 首先&#xff0c;我们创建一个mn的棋盘&#xff0c;并初始化所有的点为未访问状态。 然后&#xff0c;我们从(0, 0)位置开始进行深度优先搜索。 在每一步中&#xff0c;我们先标记当前位置为已访问&#xff0…

垃圾收集篇

文章目录 垃圾收集算法垃圾的概念对象存活的判断引用计数器法可达性分析算法 算法标记清除算法复制算法标记压缩算法 垃圾收集的相关概念STW安全点安全区域 垃圾收集器重要指标吞吐量停顿时间 垃圾收集器的分类Serial 收集器&#xff1a;串行回收ParNew 收集器&#xff1a;并行…

数据结构——查找(线性表的查找与树表的查找)

目录 1.查找 1.查找的基本概念 1.在哪里找&#xff1f; 2.什么查找&#xff1f; 3.查找成功与否&#xff1f; 4.查找的目的是什么&#xff1f; 5.查找表怎么分类&#xff1f; 6.如何评价查找算法&#xff1f; 7.查找的过程中我们要研究什么&#xff1f; 2.线性表…

【周末闲谈】Stable Diffusion会魔法的绘画师

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言Stable Diffusion介绍 使用ComfyUI 和 WebUIComfyUIWebUI 配置需求 Stable Diffusion资源分享吐司AiAUTOMATIC1111Civitai绘世整合包Nenly同学stability.ai 前言 在很早之前&…

2-33 基于matlab的用于计算无故障的斜齿轮对啮合时接触线长度随时间的变化

基于matlab的用于计算无故障的斜齿轮对啮合时接触线长度随时间的变化&#xff0c;根据需求设置斜齿轮对的相应参数&#xff0c;得到结果。程序已调通&#xff0c;可直接运行。 2-33 斜齿轮对啮合时接触线长度 齿轮参数 - 小红书 (xiaohongshu.com)

【笔记】nginx命令

查看 启动 通过./nginx启动nginx之后 可以在虚拟机中进入/usr/local/nginx/html 去查看cat index.html 也就是此页面的源代码 进入vim /etc/profile 配置完之后保存退出 source /etc/profile 手动重载资源 随后就可以在任意位置重载资源了 nginx -s reload 部署静态资源就把静…

【Linux】进程程序替换 + 模拟实现简易shell

前言 上一节我们介绍了 **进程终止**和 **进程等待**等一系列问题&#xff0c;并做了相应的验证&#xff0c;本章将继续对进程控制进行介绍&#xff0c;重点学习进程程序替换&#xff0c;并进行相应验证&#xff0c;在此基础上&#xff0c;自己模拟实现一个shell&#xff0c;该…

前端web性能统计

前端web性能统计 1. 背景2. 业界方案2.1 腾讯2.2 蚂蚁金服2.3 字节跳动2.4 美团 3. 相关观念3.1 RAIL模型3.2 性能指标3.3 真实用户监控3.4 performance 4. 性能监控工具介绍5. 推荐采用方案 1. 背景 在如今的数字时代&#xff0c;网站和应用程序的性能对用户体验至关重要。用…

机器人相关工科专业课程体系

机器人相关工科专业课程体系 前言传统工科专业机械工程自动化/控制工程计算机科学与技术 新兴工科专业智能制造人工智能机器人工程 总结Reference: 前言 机器人工程专业是一个多领域交叉的前沿学科&#xff0c;涉及自然科学、工程技术、社会科学、人文科学等相关学科的理论、方…

FOC(笔记二)

接上篇文章&#xff1a;FOC算法(笔记一)_马鞍波和三角波调制合成-CSDN博客 前面已经对FOC的开环控制进行了介绍&#xff0c;下面对FOC的闭环控制进行介绍。 本次使用的电机参数如下图所示&#xff1a; 一、HALL传感器 1.1、霍尔传感器的角度、速度计算 因为本次使用的是120安…

SpringCloud02_consul概述、功能及下载、服务注册与发现、配置与刷新

文章目录 ①. Euraka为什么被废弃②. consul简介、如何下载③. consul功能及下载④. 服务注册与发现 - 8001改造⑤. 服务注册与发现 - 80改造⑥. 服务配置与刷新Refresh ①. Euraka为什么被废弃 ①. Eureka停更进维 ②. Eureka对初学者不友好,下图为自我保护机制 ③. 阿里巴巴…