标准库以及HAL库——按键控制LED灯代码

按键控制LED本质还是控制GPIO,和点亮一个LED灯没什么区别

点亮一个LED灯:是直接控制输出引脚,GPIO初始化推挽输出即可

按键控制LED:是按键输入信号从而控制输出引脚,GPIO初始化推挽输出一个引脚以外还得加一个GPIO上拉输入

但是控制GPIO本质还是1.RCC时钟使能  2.结构体配置GPIO寄存器  3.控制GPIO

标准库写法

led.c

1.RCC时钟使能  2.结构体配置GPIO寄存器  3.控制GPIO(我们这里封装成函数ON;OFF;swtich)

#include "stm32f10x.h"                  // Device header
#include "delay.h"
void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//1.RCC时钟使能
	
	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);			 	//2.结构体配置GPIO寄存器
	
	GPIO_SetBits (GPIOA,GPIO_Pin_1 | GPIO_Pin_2);			//3.控制GPIO值为1
}

/**
  * @brief  LED1灯亮
  * @param  无
  * @retval 无
  */
void LED1_ON(void)
{
	GPIO_ResetBits (GPIOA,GPIO_Pin_1);			//控制LED1亮
}

/**
  * @brief  LED2灯亮
  * @param  无
  * @retval 无
  */
void LED2_ON(void)
{
	GPIO_ResetBits (GPIOA,GPIO_Pin_2);			//控制LED2亮
}

/**
  * @brief  LED灭
  * @param  无
  * @retval 无
  */
void LED1_OFF(void)
{
	GPIO_SetBits (GPIOA,GPIO_Pin_1);			//控制LED1灭
}

/**
  * @brief  LED灭
  * @param  无
  * @retval 无
  */
void LED2_OFF(void)
{
	GPIO_SetBits (GPIOA,GPIO_Pin_2);			//控制LED2灭
}

/**
  * @brief  LED1灯状态切换
  * @param  无
  * @retval 无
  */
void LED1_switch(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 1)
	{
		GPIO_ResetBits (GPIOA,GPIO_Pin_1);
	}
	else
	{
		GPIO_SetBits (GPIOA,GPIO_Pin_1);
	}
}

/**
  * @brief  LED2灯状态切换
  * @param  无
  * @retval 无
  */
void LED2_switch(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) == Bit_SET)
	{
		GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);
	}
	else
	{
		GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);
	}
}

led.h

#ifndef __LED_H
#define __LED_H

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

#endif

key.c

这里按键获取函数采用的是delay检测,是阻塞式的函数,这不好等学到定时器中断我们再用定时器定时检测

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
    {
        Delay_ms(20);    //按下消抖
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
        Delay_ms(20);    //松开消抖
        keynum = 1;
    }

#include "stm32f10x.h"                  // Device header
#include "DELAY.h"
void KEY_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//1.RCC时钟使能
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);			 	//2.结构体配置GPIO寄存器
	
}

/**
  * @brief  按键获取函数
  * @param  无
  * @retval 按键值1->PB1,2->pb11
  */
uint8_t KEY_Getstate(void)
{
	uint8_t keynum = 0;
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
	{
		Delay_ms(20);	
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
		Delay_ms(20);
		keynum = 1;
	}
	
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
	{
		Delay_ms(20);	
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0);
		Delay_ms(20);	
		keynum = 2;
	}		
	return keynum;
}

key.h

#ifndef __KEY_H
#define __KEY_H

void KEY_Init(void);
uint8_t KEY_Getstate(void);
#endif

main()

定义一个变量把按键状态接收,通过不同按键值来控制LED状态

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

uint8_t keynum;
int main ()
{

	KEY_Init();
	LED_Init();
	while(1)
	{
		keynum = KEY_Getstate();
		if(keynum == 1)
		{
			LED1_switch();
		}
		else if(keynum == 2)
		{
			LED2_switch();
		}
		

	}
}
 

标准库写完了,接下来我们写HAL库

HAL库分三步

1.建工程

2.设配置

3.写代码

HAL库写法

一. 关于建工程请参考:江科大学习笔记之——HAL库点亮一个LED灯-CSDN博客在里面有详细步骤,简单易懂

二.配置设置

这里我设置错了应该是PB11,你们自己注意一下

ctrl+s生成代码

三.写代码

为了方便我们把LED,KEY单独拿出来放在System文件夹下

在cubeIDE里面想建立自己的.C.H文件步骤如下

1.建立文件夹

2.

 鼠标右键点击文件名–Properties

3. 进入Includes 添加文件的路径

同时还要增加源文件的路径

好准备工作做完了,上面cube ide的模块化是我自己在网上找半天才找到的方法:

STM32CubemxIDE 导入自定义的.c和.h文件_stm32cubeide添加源文件-CSDN博客

本想问别人但是想想还是提高自己解决问题的能力吧,所以我就花了更多时间去自己搜索解决方法。

现在开始写代码

模块代码的逻辑都一样只是把标准库的函数我就不多赘述了,换成了HAL库的函数

led.c

这里LED灯的熄灭与点亮有,电平翻转函数HAL_GPIO_TogglePin,关于HAL库的函数可以看:

HAL库函数合集-CSDN博客


#include "gpio.h"

/**
  * @brief  LED1灯亮
  * @param  无
  * @retval 无
  */
void LED1_ON(void)
{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);//控制LED1亮
}

/**
  * @brief  LED2灯亮
  * @param  无
  * @retval 无
  */
void LED2_ON(void)
{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);	//控制LED2亮
}

/**
  * @brief  LED灭
  * @param  无
  * @retval 无
  */
void LED1_OFF(void)
{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);//控制LED1灭
}

/**
  * @brief  LED灭
  * @param  无
  * @retval 无
  */
void LED2_OFF(void)
{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);//控制LED2灭
}

/**
  * @brief  LED1灯状态切换
  * @param  无
  * @retval 无
  */
void LED1_switch(void)
{
	HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
}

/**
  * @brief  LED2灯状态切换
  * @param  无
  * @retval 无
  */
void LED2_switch(void)
{
	HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_2);
}


led.h

#ifndef __LED_H
#define __LED_H


void LED1_ON(void);
void LED2_ON(void);
void LED1_OFF(void);
void LED2_OFF(void);
void LED1_switch(void);
void LED2_switch(void);


#endif

key,c


#include "gpio.h"
/**
  * @brief  按键获取函数
  * @param  无
  * @retval 按键值1->PB1,2->pb11
  */
uint8_t KEY_Getstate(void)
{
	uint8_t keynum = 0;
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0)
	{
		HAL_Delay(20);
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0);
		HAL_Delay(20);
		keynum = 1;
	}
	
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == 0)
	{
		HAL_Delay(20);
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == 0);
		HAL_Delay(20);
		keynum = 2;
	}		
	return keynum;
}

key.h

#ifndef __KEY_H
#define __KEY_H

uint8_t KEY_Getstate(void);
#endif

main()

这里就定义了uint8_t keynum;

然后写了while,其他都是生产的代码

  while (1)
  {

		keynum = KEY_Getstate();
		if(keynum == 1)
		{
			LED1_switch();
		}
		else if(keynum == 2)
		{
			LED1_OFF();
		}
}
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t keynum;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

		keynum = KEY_Getstate();
		if(keynum == 1)
		{
			LED1_switch();
		}
		else if(keynum == 2)
		{
			LED1_OFF();
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

编译烧入现象和标准库一致

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rabbitmq追问2

分析rabbitmq 默认使用姿势是什么 direct fanout还是什么 public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException { this.send(exchange, routingKey, this.convertMessageIfNecessary(obje…

vue+js+Java在分页的el-table里实现上移、下移;置顶

这里写目录标题 一、上移、下移二、置顶 一、上移、下移 实现&#xff1a;上移到第一行后不能再上移&#xff0c;下移到最后一行不能下移&#xff0c;以及分页后能上移到前一页&#xff0c;下移能移到后一页&#xff1b;&#xff08;新增sort排序字段&#xff09; <el-tabl…

计算机因进程结束导致白屏

问题场景&#xff1a; 计算机卡顿利用&#xff08;右击计算机桌面底部任务栏->打开任务管理器->结束任务->或进程被意外结束导致白屏&#xff09; 问题描述 白屏 原因分析&#xff1a; 在结束进程时&#xff0c;导致 文件资源管理器 进程崩溃。 解决方案&#xf…

【YashanDB知识库】如何在备机节点上做备份和恢复

本文内容来自YashanDB官网&#xff0c;原文内容请见 https://www.yashandb.com/newsinfo/7817898.html?templateId1718516 问题现象 一主一备情况下&#xff0c;主机需要支持常规业务&#xff0c;为了不影响业务&#xff0c;在备机做备份恢复的场景。 问题的风险及影响 1、…

【Linux-多线程】线程互斥(锁和它的接口等)

一、线程互斥 我们把多个线程能够看到的资源叫做共享资源&#xff0c;我们对共享资源进行保护&#xff0c;就是互斥 1.多线程访问问题 【示例】见一见多线程访问问题&#xff0c;下面是一个抢票的代码&#xff0c;共计票数10000张&#xff0c;4个线程去抢 之前我们展示过封…

Kafka中的Topic和Partition有什么关系?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka中的Topic和Partition有什么关系&#xff1f;】面试题。希望对大家有帮助&#xff1b; Kafka中的Topic和Partition有什么关系&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Apache Kafka 中&#…

leetcode108:将有序数组转化为二叉搜索树

给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被视为正确…

MyBatis执行一条sql语句的流程(源码解析)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MyBatis执行一条sql语句的流程&#xff08;源码解析&#xff09; MyBatis执行sql语句的流程加载配置文件加载配置文件的流程 创建sqlsessionFactory对象解析Mapper创建sqlses…

python23-常用的第三方库01:request模块-爬虫

requests 模块是 Python 中的一个第三方库&#xff0c;用于发送 HTTP 请求。 它提供了一个简单且直观的 API&#xff0c;使得发送网络请求和解析响应变得非常容易。requests 模块支持各种 HTTP 方法&#xff0c;如 GET、POST、PUT、DELETE 等&#xff0c;并且具有处理 cookies…

TTL 传输中过期问题定位

问题&#xff1a; 工作环境中有一个acap的环境&#xff0c;ac的wan口ip是192.168.186.195/24&#xff0c;ac上lan上有vlan205&#xff0c;其ip子接口地址192.168.205.1/24&#xff0c;ac采用非nat模式&#xff0c;而是路由模式&#xff0c;在上级路由器上有192.168.205.0/24指向…

前端超大缓存IndexDB、入门及实际使用

文章目录 往期回顾项目实战初始化表获取列表新增表的数据项获取详情根据ID获取详情根据其他字段获取详情 删除数据 总结 往期回顾 在之前的文章中&#xff0c;我们介绍了IndexDB vs Cookies vs Session这几个的对比&#xff0c;但是没有做实际项目的演示&#xff0c;今天我们用…

vue3学习笔记(11)-组件通信

1.props 父传子 子传夫 父传子 接收用defineProps([]) 空字符串也是假 2.自定义事件 $event:事件对象 ref定义的数据在模板里面引用的时候可以不用.value 3.子传父 宏函数 触发事件 声明事件 defineEmits() 挂载之后3s钟触发 4.命名 肉串命名 5.任意组件通信 mitt pubs…

【高阶数据结构】红黑树封装map、set

红黑树封装map、set 1.源码及框架分析2.模拟实现map和set1.支持 insert 的实现2.支持 iterator 的实现3.map支持 operator [] 的实现 3.总代码1.RBTree.h2.Myset.h3.Mymap.h4.Test.cpp 1.源码及框架分析 SGI-STL30版本源代码&#xff0c;map和set的源代码在map/set/stl_map.h/…

多模态论文笔记——Coca

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍多模态模型Coca&#xff0c;在DALLE 3中使用其作为captioner基准模型的原因和优势。 文章目录 ALBEF论文模型结构组成训练目标 CoCa​论文模型结构CoCa…

WebGL之Tree.js

tree基于WebGL的库绘制展示3D图形使用场景包括: 网页游&#xff1a;创建交互式的3D游戏&#xff0c;提供沉浸式的游戏体验。数据可视&#xff1a;将复杂的数据以3D形式展示&#xff0c;便于用户理解和分析。产品展&#xff1a;在电商网站上展示产品的3D模型&#xff0c;提供更…

基于PyQt5的UI界面开发——图像与视频的加载与显示

介绍 这里我们的主要目标是实现一个基于PyQt5和OpenCV的图像浏览和视频播放应用。用户可以选择本地的图像或视频文件夹&#xff0c;进行图像自动播放和图像切换以及视频播放和调用摄像头等操作&#xff0c;并且支持图像保存功能。项目的核心设计包括文件路径选择、图像或视频的…

数据结构与算法之动态规划: LeetCode 62. 不同路径 (Ts版)

不同路径 https://leetcode.cn/problems/unique-paths/description/ 描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “…

java自定义注解对枚举类型参数的校验

目录 1.前提准备条件 1.1 pom.xml文件依赖: 1.2 枚举类&#xff1a; 1.3 controller接口&#xff1a; 1.4 实体参数&#xff1a; 1.5 knife4j的配置 2.实现要求 3.实现步骤 3.1 自定义注解类&#xff1a; 3.2 使用注解&#xff1a; 3.3 添加注解校验类&#xff1a; …

Type c系列接口驱动电路·内置供电驱动电路使用USB2.0驱动电路!!!

目录 前言 Type c常见封装类型 Type c引脚功能详解 Type c常见驱动电路详解 Type c数据手册 ​​​​​​​ ​​​​​​​ 编写不易&#xff0c;仅供学习&#xff0c;请勿搬运&#xff0c;感谢理解 常见元器件驱动电路文章专栏连接 LM7805系列降压芯片驱动电路…

Mybatis 01

JDBC回顾 select 语句 "select *from student" 演示&#xff1a; 驱动包 JDBC 的操作流程&#xff1a; 1. 创建数据库连接池 DataSource 2. 通过 DataSource 获取数据库连接 Connection 3. 编写要执⾏带 ? 占位符的 SQL 语句 4. 通过 Connection 及 SQL 创建…