第2课【CMSIS和标准库开发】标准库 CMSIS 分层

目录

  • 基本知识框架
  • 课堂笔记
    • CMSIS
      • CMSIS的分层关系和作用
      • CMSIS层文件结构
        • 内核函数层文件
        • 外设函数访问层文件
    • 标准库开发
      • 标准库开发 LED-GPIO
      • 标准库开发 KEY-GPIO
      • 标准库开发 位带操作
        • 位带
          • 位带
          • 位带别名区
          • 位带区和位带别名区的地址转换
        • 通过位带操作点亮LED灯
  • 基本知识框架Xmind文件下载

基本知识框架

第2课【CMSIS和标准库开发】标准库 CMSIS 分层_第1张图片

课堂笔记

CMSIS

由于有众多外设厂商为Cortex内核提供外设,不同的外设带来的差异,导致软件在编写或移植时会出现很大困难,所以Arm公司同芯片厂商共同协作推出了CMSIS标准。全称是Cortex MicroController Software Interface Standard【Cortex微控制器软件接口标准】

CMSIS的分层关系和作用

CMSIS标准规定了APPLICATION层CMSIS层MCU层,层与层之间的关系如下图
第2课【CMSIS和标准库开发】标准库 CMSIS 分层_第2张图片
CMSIS标准最重要的作用就是在用户层和硬件层之间建立硬件抽象层,从而屏蔽硬件层差异,并向用户层提供处理器软件接口

CMSIS层文件结构

根据CMSIS标准,ST官方提供了内核寄存器相关文件(CMSIS相关)外设寄存器相关文件(CMSIS以外的,外设标准库),它们的关系如下
第2课【CMSIS和标准库开发】标准库 CMSIS 分层_第3张图片
从文件结构可以看出,CMSIS层的核心主要分为内核函数层外设函数访问层

  • 内核函数层:其中文件主要由Arm公司提供,文件内容包括内核寄存器的的名称,地址定义
  • 外设函数访问层:其中文件主要由芯片生产商提供,文件内容包括外设寄存器和中断的名称,地址定义

内核函数层文件

内核函数层的文件主要的作用是时钟配置与操作内核寄存器,一般来说很少会使用

  • system_stm32f10x.h / .c:操作RCC时钟,实现系统时钟的配置。系统上电时,会首先执行startup文件,startup文件会调用SystemInit函数,这个函数就是在本文件中定义的,默认状态下调用完成后会将系统时钟初始化为72MHz
  • core_cm3.h / .c:实现内核寄存器的名称地址定义,操作寄存器的函数

外设函数访问层文件

外设函数访问层的文件主要作用是实现外设地址映射,操作外设寄存器,这里的文件会经常用到

  • stm32f10x_xxxx.h / .c:xxxx指的是gpio,adc等等,每个外设都有对应src驱动源文件和inc定义相关头文件。是外设标准库的主要部分
  • stm32f10x.h:实现了片上外设的所有寄存器映射

标准库开发

在之前的第1课中,已经实现了基础的库函数,并通过它点亮了LED灯。在学习了标准库后,可以尝试通过标准库来实现点亮LED的功能,并加上其他进阶的其他功能

标准库开发 LED-GPIO

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-GPIO

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)

  • 前半部分0xF000 000 * A + 0x0200 0000 :计算的是位带别名区的起始地址,并根据地址判断到底是外设位带别名区还是sRam位带别名区
  • 后半部分(A * 0x00FF FFFF * 8 + n) * 4:计算的是位对于位带别名区起始地址的偏移量,(A * 0x00FF FFFF * 8 + n)首先计算出位带区中给,A的第n位相对于起始地址的偏移量,单位为位,最后*4是将这个偏移量转换成对应位带别名区偏移量

通过位带操作点亮LED灯

位带操作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****/

基本知识框架Xmind文件下载

链接:资源下载

你可能感兴趣的:(STM32,stm32)