由于有众多外设厂商为Cortex内核提供外设,不同的外设带来的差异,导致软件在编写或移植时会出现很大困难,所以Arm公司同芯片厂商共同协作推出了CMSIS标准。全称是Cortex MicroController Software Interface Standard【Cortex微控制器软件接口标准】
CMSIS标准规定了APPLICATION层、CMSIS层和MCU层,层与层之间的关系如下图
CMSIS标准最重要的作用就是在用户层和硬件层之间建立硬件抽象层,从而屏蔽硬件层差异,并向用户层提供处理器软件接口
根据CMSIS标准,ST官方提供了内核寄存器相关文件(CMSIS相关)和外设寄存器相关文件(CMSIS以外的,外设标准库),它们的关系如下
从文件结构可以看出,CMSIS层的核心主要分为内核函数层和外设函数访问层:
内核函数层的文件主要的作用是时钟配置与操作内核寄存器,一般来说很少会使用
外设函数访问层的文件主要作用是实现外设地址映射,操作外设寄存器,这里的文件会经常用到
在之前的第1课中,已经实现了基础的库函数,并通过它点亮了LED灯。在学习了标准库后,可以尝试通过标准库来实现点亮LED的功能,并加上其他进阶的其他功能
LED功能 头文件bsp_led.h代码主体部分实现
#ifndef __BSP_LED_H__
#define __BSP_LED_H__
#include "stm32f1xx_hal.h"
// GPIO输出高、低以及反转电平
#define digitalHi(Port, Pin) ((Port)->BSRR = Pin)
#define digitalLi(Port, Pin) ((Port)->BRR = Pin)
#define digitalRev(Port,Pin) ((Port)->ODR ^= Pin)
// RGB灯的开、关以及反转
#define LED1_ON digitalLi(LED1_GPIO_Port, LED1_Pin)
#define LED1_OFF digitalHi(LED1_GPIO_Port, LED1_Pin)
#define LED1_REV digitalRev(LED1_GPIO_Port, LED1_Pin)
#define LED2_ON digitalLi(LED2_GPIO_Port, LED2_Pin)
#define LED2_OFF digitalHi(LED2_GPIO_Port, LED2_Pin)
#define LED2_REV digitalRev(LED2_GPIO_Port, LED2_Pin)
#define LED3_ON digitalLi(LED3_GPIO_Port, LED3_Pin)
#define LED3_OFF digitalHi(LED3_GPIO_Port, LED3_Pin)
#define LED3_REV digitalRev(LED3_GPIO_Port, LED3_Pin)
// RGB灯以及其它衍生颜色的灯
#define LED_RED \
LED1_ON;\
LED2_OFF;\
LED3_OFF;
#define LED_GREEN \
LED1_OFF;\
LED2_ON;\
LED3_OFF;
#define LED_BLUE \
LED1_OFF;\
LED2_OFF;\
LED3_ON;
#define LED_YELLOW \
LED1_ON;\
LED2_ON;\
LED3_OFF;
#define LED_PURPLE \
LED1_ON;\
LED2_OFF;\
LED3_ON;
#define LED_CYAN \
LED1_OFF;\
LED2_ON;\
LED3_ON;
#define LED_WHITE \
LED1_ON;\
LED2_ON;\
LED3_ON;
#define LED_BLACK \
LED1_OFF;\
LED2_OFF;\
LED3_OFF;
void LED_GPIO_Config(void);
#endif
LED功能 源文件bsp_key.c代码主体部分实现
#ifndef BSP_LED_C_
#define BSP_LED_C_
#include "bsp_led.h"
#include "main.h"
// LED相关GPIO口初始化
void LED_GPIO_Config(void)
{
// 使能GPIOB的时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
// 定义并补充结构体信息
GPIO_InitTypeDef* GPIO_LED_Structure;
GPIO_LED_Structure->Pin = LED1_Pin;
GPIO_LED_Structure->Mode = GPIO_MODE_OUTPUT_PP;
GPIO_LED_Structure->Speed = GPIO_SPEED_FREQ_HIGH;
// 初始化GPIO口
HAL_GPIO_Init(LED1_GPIO_Port, GPIO_LED_Structure);
GPIO_LED_Structure->Pin = LED2_Pin;
HAL_GPIO_Init(LED2_GPIO_Port, GPIO_LED_Structure);
GPIO_LED_Structure->Pin = LED3_Pin;
HAL_GPIO_Init(LED3_GPIO_Port, GPIO_LED_Structure);
// 输出高电平
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
}
#endif
main.c代码主体部分实现
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* © Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_led.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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);
static void MX_GPIO_Init(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 */
LED_GPIO_Config();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
LED1_ON;
/* 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_NONE;
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_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED2_Pin|LED3_Pin|LED1_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : KEY2_Pin */
GPIO_InitStruct.Pin = KEY2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : KEY1_Pin */
GPIO_InitStruct.Pin = KEY1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LED2_Pin LED3_Pin LED1_Pin */
GPIO_InitStruct.Pin = LED2_Pin|LED3_Pin|LED1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* 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 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
KEY功能 头文件bsp_key.h代码主体部分实现
#ifndef __BSP_LED_H__
#define __BSP_LED_H__
#include "stm32f1xx_hal.h"
void KEYScan(void);
void LED_GPIO_Config(void);
#endif
KEY功能 源文件bsp_key.c代码主体部分实现
#ifndef BSP_LED_C_
#define BSP_LED_C_
#include "bsp_led.h"
#include "main.h"
void KEYScan(void)
{
if (GPIO_PIN_SET == HAL_GPIO_WritePin(KEY_GPIO_Port, KEY_Pin))
while(GPIO_PIN_SET == HAL_GPIO_WritePin(KEY_GPIO_Port, KEY_Pin));
return GPIO_PIN_SET;
else
return GPIO_PIN_RESET;
}
// KEY相关GPIO口初始化
void KEY_GPIO_Config(void)
{
// 使能GPIOC的时钟
__HAL_RCC_GPIOC_CLK_ENABLE();
// 定义并补充结构体信息
GPIO_InitTypeDef* GPIO_LED_Structure;
GPIO_LED_Structure->Pin = KEY_Pin;
GPIO_LED_Structure->Mode = GPIO_Mode_IN_FLOATING;
// 初始化GPIO口
HAL_GPIO_Init(LED1_GPIO_Port, GPIO_LED_Structure);
}
#endif
main.c代码主体部分实现
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* © Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_led.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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);
static void MX_GPIO_Init(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 */
KEY_GPIO_Config();
LED_GPIO_Config();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if (GPIO_PIN_SET == KEYScan())
LED1_ON;
/* 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_NONE;
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_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED2_Pin|LED3_Pin|LED1_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : KEY2_Pin */
GPIO_InitStruct.Pin = KEY2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : KEY1_Pin */
GPIO_InitStruct.Pin = KEY1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LED2_Pin LED3_Pin LED1_Pin */
GPIO_InitStruct.Pin = LED2_Pin|LED3_Pin|LED1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* 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 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
位操作指的是可以对单独某个位进行读写操作,当需要对某些位进行频繁读写操作时,通过位操作可以轻松便捷的实现。但Cortex内核的寻址能力仅能达到字节级别,如果要进行位操作,就只能通过位带
位带指的是STM32中可以进行位操作的地址区域。但这里的位操作不是直接对位带中的地址进行位操作,而是要通过访问位带区的“替身”:位带别名区
位带别名区是STM32中服务于位带区的特殊地址范围。对于位带别名区的所有操作,都会体现到位带区上
STM32中可以实现位带的地址区域有两个外设位带区和sRam位带区
外设位带区 | sRam位带区 |
---|---|
地址范围:0X4000 0000~0X4010 0000 | 地址范围:0X2000 0000~X2010 0000 |
大小:1MB | 大小:1MB |
外设位带别名区 | sRam位带别名区 |
地址范围:0X4200 0000~0X43FF FFFF | 地址范围:0X2200 0000~0X23FF FFFF |
大小:32MB | 大小:32MB |
访问的原理:将位带区的每1个位【bit】一一映射到位带别名区对应的4个字节【Byte】。而位带别名区地址对应的内容是LSB,也就是最低位有效,这意味着只要读写位带别名区那四个字节的最低位,就等效于读写位带区的对应位
位带区和位带别名区大小的联系
由于将位带区的1个位映射到位带别名区的4个字节,1字节=8位,所以位带别名区的大小是位带区的32倍
为什么要将1个位映射到4个字节
由于STM32内部的数据总线是32位的,CPU进行32位数据的处理是最高效的,所以将1位映射成4字节,是一种用空间换取时间的做法,原理类似于C语言结构体中的成员大小对齐
根据位带区与位带别名区的映射原理,要想得到位带区中地址A对应字节的第n位,对应位带别名区地址。
计算公式:位带别名区地址 = (0xF000 000 * A + 0x0200 0000) + ((A * 0x00FF FFFF * 8 + n) * 4)
位带操作LED功能 头文件bsp_bitband.h代码主体部分实现
/*
* bsp_bitband.h
*
* Created on: Sep 16, 2021
* Author: 67566
*/
#ifndef BSP_BITBAND_H_
#define BSP_BITBAND_H_
#include "stm32f1xx_hal.h"
// 计算位带区对应位带别名区地址
#define BITBAND(addr,bit) ((addr & 0xF0000000)+0x02000000+((addr & 0x000FFFFF)<<5)+(bit<<2))
// 强转地址,其中volatile不能省略,否则编译器会进行参数优化
#define MEM_ADDR(addr) (*(volatile unsigned long*)(addr))
#define BIT_ADDR(addr,bit) MEM_ADDR(BITBAND(addr,bit))
// GPIO对应ODR\IDR地址
#define GPIOA_ODR_ADDR GPIOA_BASE + 0x0c
#define GPIOB_ODR_ADDR GPIOB_BASE + 0x0c
#define GPIOC_ODR_ADDR GPIOC_BASE + 0x0c
#define GPIOD_ODR_ADDR GPIOD_BASE + 0x0c
#define GPIOE_ODR_ADDR GPIOE_BASE + 0x0c
#define GPIOF_ODR_ADDR GPIOF_BASE + 0x0c
#define GPIOG_ODR_ADDR GPIOG_BASE + 0x0c
#define GPIOA_IDR_ADDR GPIOA_BASE + 0x08
#define GPIOB_IDR_ADDR GPIOB_BASE + 0x08
#define GPIOC_IDR_ADDR GPIOC_BASE + 0x08
#define GPIOD_IDR_ADDR GPIOD_BASE + 0x08
#define GPIOE_IDR_ADDR GPIOE_BASE + 0x08
#define GPIOF_IDR_ADDR GPIOF_BASE + 0x08
#define GPIOG_IDR_ADDR GPIOG_BASE + 0x08
// GPIO引脚输出\输入
#define GPIOA_OUT(bit) BIT_ADDR(GPIOA_ODR_ADDR,bit)
#define GPIOA_IN(bit) BIT_ADDR(GPIOA_IDR_ADDR,bit)
#define GPIOB_OUT(bit) BIT_ADDR(GPIOB_ODR_ADDR,bit)
#define GPIOB_IN(bit) BIT_ADDR(GPIOB_IDR_ADDR,bit)
#define GPIOC_OUT(bit) BIT_ADDR(GPIOC_ODR_ADDR,bit)
#define GPIOC_IN(bit) BIT_ADDR(GPIOC_IDR_ADDR,bit)
#define GPIOD_OUT(bit) BIT_ADDR(GPIOD_ODR_ADDR,bit)
#define GPIOD_IN(bit) BIT_ADDR(GPIOD_IDR_ADDR,bit)
#define GPIOE_OUT(bit) BIT_ADDR(GPIOE_ODR_ADDR,bit)
#define GPIOE_IN(bit) BIT_ADDR(GPIOE_IDR_ADDR,bit)
#define GPIOF_OUT(bit) BIT_ADDR(GPIOF_ODR_ADDR,bit)
#define GPIOF_IN(bit) BIT_ADDR(GPIOF_IDR_ADDR,bit)
#define GPIOG_OUT(bit) BIT_ADDR(GPIOG_ODR_ADDR,bit)
#define GPIOG_IN(bit) BIT_ADDR(GPIOG_IDR_ADDR,bit)
#endif /* BSP_BITBAND_H_ */
main.c代码主体部分实现
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* © Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_led.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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);
static void MX_GPIO_Init(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 */
LED_GPIO_Config();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
GPIOB_OUT(5) = GPIO_PIN_RESET;
/* 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_NONE;
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_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED2_Pin|LED3_Pin|LED1_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : KEY2_Pin */
GPIO_InitStruct.Pin = KEY2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY2_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : KEY1_Pin */
GPIO_InitStruct.Pin = KEY1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LED2_Pin LED3_Pin LED1_Pin */
GPIO_InitStruct.Pin = LED2_Pin|LED3_Pin|LED1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* 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 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
链接:资源下载