当前位置:   article > 正文

STM32入门(cubeMX)_stm32cubemx

stm32cubemx

目录

一、开发环境的安装、工程搭建和烧录

1.Keil5

2.ST-Link

烧录测试

STlink接线

STM32F1 模板工程

Keil烧录

3.STM32CubeMX

安装

快速搭建工程

 二、STM32简介

单片机

STM系列单片机命名规则

STM32F103C8T6:

​编辑STM32F103C8T6单片机简介

寄存器和各种库的对比

1. 寄存器

2. 标准库

3. HAL库

4.LL库

 三、通用输入输出端口GPIO

1.简介

定义

命名规则

内部框架图

推挽输出与开漏输出

2.简单实现亮灯交替闪烁效果(GPIO写、HAL_Delay) 

3.按键点灯(GPIO读、轮询法)

多此一举的宏定义和函数:

四、复位、时钟、中断

复位

系统复位

电源复位

备份区复位

时钟控制

什么是时钟?

时钟来源

如何使用CubeMX配置时钟

五、中断和事件

中断概述

什么是中断?

什么是EXTI?

什么是优先级?

抢占优先级和响应优先级的区别:

什么是优先级分组?

什么是NVIC?

什么是中断向量表?

五、按键点亮LED灯(中断法)

1. 配置时钟

2. 配置GPIO口

3. 使能中断

4. 配置工程

按键点亮LED灯

加上消抖


 个人情况:

已经有C语言、C51基础,并玩过各种外设,现需要快速上手使用STM32,所以选择了学习cubeMX+HAL库开发。

一、开发环境的安装、工程搭建和烧录

软件: Keil5 和 STM32CubeMX

1.Keil5

使用 Keil4 写 STM32 代码其实也是可以,但需要很复杂的配置,不建议新手操作。比较推荐 Keil5 编写 STM32 ,只需要一些简单的设置就可以上手,对新手友好。

等待下载固件包,漫长的过程,也可以用已有的固件包直接导入。

十几块买一个,插上电脑,打开设备管理器查看:

可以看到已经连接,点更新驱动程序。选择驱动程序所在文件夹,完成更新 

驱动官网下载(慢)https://www.st.com/en/development-tools/stsw-link009.html

 

 在Keil中配置

 

 更新一下,device connect如果不成功,重新插拔一下

 

烧录测试

STlink接线

STM32F1 模板工程

可以找个模板程序,用STlink烧录测速一下。

Keil烧录

在Keil里点击编译,烧录,成功后,板子复位一下就可以看到效果 

 

3.STM32CubeMX

安装

作用:通过界面的方式,快速生成工程文件。

下载:官网(慢)https://www.st.com/zh/development-tools/stm32cubemx.html#overview

安装:一路下一步,建议不要安装在C盘

配置:更新固件包位置(比较大,默认在C盘,可以更改到其它盘)

 help ---> update settings --> Firmware Repository

快速搭建工程

按图走

 

根据原理图可知LED1、2分别对应PB8、PB9

 

 

 设置PB8、PB9为GPIO输出口,默认低电平,灯会亮

 

 

 

 debug方式修改为串口

可以看到串口会自动配置 

 

 

 只取需要的库

 生成文件

 

打开Keil烧录即可 

 

 二、STM32简介

单片机

单片机(Single-Chip Microcomputer)是一种集成电路芯片,把具有数据处理能力的中央处
理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功
能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成
到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。

STM系列单片机命名规则

ST -- 意法半导体

M -- Microelectronics 微电子

32 -- 总线宽度

STM32F103C8T6:

F103 -- STM32 基础型

C -- 48引脚(&49)

8 -- 64kb闪存

T -- QFP封装

6 -- 温度范围-40 ~ 85

STM32F103C8T6单片机简介

项目介绍
内核Cortex-M3
Flash64K x 8bit
SRAM20K x 8bit
GPIO37个GPIO,分别为PA0-PA15、PBO-PB15、PC13-PC15、PDO-PD1
ADC2个12bit ADC合计12路通道,外部通道: PAO到PA7+PBO到PB1内部通道: 温度传感器通道ADC Channel 16和内部参考电压通道ADC Channel 17
定时
器/计
数器
4个16bit定时器/计数器,分别为TIM1、TIM2、TIM3、TIM4TM1带死区插入,常用于产生PWM控制电机

看门狗定时器

2个看门狗定时器 (独立看门狗IWDG、窗口看门狗WWDG)
滴答定时器1个24bit向下计数的滴答定时器systick
工作电压、温度2V3.6V、-40°C85°C
通信串
2 * IIC,2 * SPI,3 * USART,1 * CAN
系统时钟内部8MHz时钟HSI最高可倍频到64MHZ,外部8MHZ时钟HSE最高可倍频到
72MHZ

寄存器和各种库的对比

1. 寄存器

寄存器众多,需要经常翻阅芯片手册,费时费力;

更大灵活性,可以随心所欲达到自己的目的;

深入理解单片机的运行原理,知其然更知其所以然。

2. 标准库

将寄存器底层操作都封装起来,提供一整套接口(API)供开发者调用

每款芯片都编写了一份库文件,也就是工程文件里stm32F1xx…之类的;

配置结构体变量成员就可以修改外设的配置寄存器,从而选择不同的功能;

大大降低单片机开发难度,但是在不同芯片间不方便移植。

3. HAL库

ST公司目前主力推的开发方式,新的芯片已经不再提供标准库;

为了实现在不同芯片之间移植代码;

为了兼容所有芯片,导致代码量庞大,执行效率低下。

4.LL库

弥补了HAL库效率低的问题。

 三、通用输入输出端口GPIO

1.简介

定义

GPIO是通用输入输出端口的简称,简单来说就是STM32可控制的引脚STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。

简单来说我们可以控制GPIO引脚的电平变化,达到我们的各种目的。

命名规则

组编号+引脚编号

组编号:GPIOA, GPIOB, GPIOC, GPIOD .. GPIOG

引脚编号:0,1,2,3,4...15

组合起来:

PA0, PA1, PA2 .. PA15

PB0, PB1, PB2 .. PB15

PC0, PC1, PC2 .. PC15

...

有一些特殊功能的引脚是不能用作IO的。

内部框架图

下图来源于官方参考手册,了解即可。

推挽输出与开漏输出

内部结构图

推挽输出: 可以真正能真正的输出高电平和低电平

开漏输出: 开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动

2.简单实现亮灯交替闪烁效果(GPIO写、HAL_Delay) 

在生成的代码中可以看看大概都是什么内容

Keil5中按F12可以溯源(要先编译)

主函数中找到

 找到cubeMXGPIO初始化函数,

里面有HAL库的GPIO写函数,阅读得知前两个参数是选择IO口,

第三个RESET表示低电平,而SET表示高电平

在main函数while循环里就可以复制并改写这段代码,

用HAL的delay函数延时500ms,两口SET、RESET交替,两LED交替闪烁

 

  1. while (1)
  2. {
  3. /* USER CODE END WHILE */
  4. /*Configure GPIO pin Output Level */
  5. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
  6. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
  7. HAL_Delay(500);
  8. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
  9. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
  10. HAL_Delay(500);
  11. /* USER CODE BEGIN 3 */
  12. }

继续溯源,可以看一些GPIO相关源码 

常用的GPIO HAL库函数:

  1. void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
  2. void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinStatePinState);
  3. void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
  4. GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

 结构体 GPIO_InitTypeDef 定义:

  1. typedef struct
  2. {
  3. uint32_t Pin;
  4. uint32_t Mode;
  5. uint32_t Pull;
  6. uint32_t Speed;
  7. } GPIO_InitTypeDef;

3.按键点灯(GPIO读、轮询法)

位于A0、A1,

 按下变为低电平。

设置GPIO_Input,其它配置一样,生成 

 

 HAL_GPIO_ReadPin 源码:

  1. GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
  2. {
  3. GPIO_PinState bitstatus;
  4. /* Check the parameters */
  5. assert_param(IS_GPIO_PIN(GPIO_Pin));
  6. if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
  7. {
  8. bitstatus = GPIO_PIN_SET;
  9. }
  10. else
  11. {
  12. bitstatus = GPIO_PIN_RESET;
  13. }
  14. return bitstatus;
  15. }

 根据 HAL_GPIO_ReadPin 函数,写代码,添加一个 while() 用于软件消抖。

  1. while (1)
  2. {
  3. /* USER CODE END WHILE */
  4. //循环检测A0是否低电平
  5. if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
  6. {
  7. //软件按钮消抖:检测如果一直按住,直到松手再继续
  8. while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET);
  9. //B8状态翻转
  10. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
  11. }
  12. //循环检测A1是否低电平
  13. if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_RESET)
  14. {
  15. //软件按钮消抖:检测如果一直按住,直到松手再继续
  16. while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_RESET);
  17. //B9状态翻转
  18. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
  19. }
  20. /* USER CODE BEGIN 3 */
  21. }

多此一举的宏定义和函数:

或者也可以定义一个返回按钮状态的函数,用 unsigned char 型,查看源码可知为 uint8_t

  1. /* 7.18.1.1 */
  2. /* exact-width signed integer types */
  3. typedef signed char int8_t;
  4. typedef signed short int int16_t;
  5. typedef signed int int32_t;
  6. typedef signed __INT64 int64_t;
  7. /* exact-width unsigned integer types */
  8. typedef unsigned char uint8_t;
  9. typedef unsigned short int uint16_t;
  10. typedef unsigned int uint32_t;
  11. typedef unsigned __INT64 uint64_t;

 宏定义、函数:

注意宏定义结尾不能+“ ; ” ,

函数只有一个return,这是一种规范形式

  1. /* Private macro -------------------------------------------------------------*/
  2. /* USER CODE BEGIN PM */
  3. #define KEY_ON 0
  4. #define KEY_OFF 1
  5. /* Private user code ---------------------------------------------------------*/
  6. /* USER CODE BEGIN 0 */
  7. uint8_t Key_scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
  8. {
  9. uint8_t Key_Status;
  10. if (HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET)
  11. {
  12. while(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET);
  13. Key_Status = KEY_ON;
  14. }
  15. else
  16. {
  17. Key_Status = KEY_OFF;
  18. }
  19. return Key_Status;
  20. }
  21. /* USER CODE END 0 */
  22. int main(void)
  23. {
  24. /* USER CODE BEGIN 1 */
  25. /* USER CODE END 1 */
  26. /* MCU Configuration--------------------------------------------------------*/
  27. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  28. HAL_Init();
  29. /* USER CODE BEGIN Init */
  30. /* USER CODE END Init */
  31. /* Configure the system clock */
  32. SystemClock_Config();
  33. /* USER CODE BEGIN SysInit */
  34. /* USER CODE END SysInit */
  35. /* Initialize all configured peripherals */
  36. MX_GPIO_Init();
  37. /* USER CODE BEGIN 2 */
  38. /* USER CODE END 2 */
  39. /* Infinite loop */
  40. /* USER CODE BEGIN WHILE */
  41. while (1)
  42. {
  43. /* USER CODE END WHILE */
  44. if (Key_scan(GPIOA, GPIO_PIN_0) == KEY_ON)
  45. {
  46. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
  47. }
  48. if (Key_scan(GPIOA, GPIO_PIN_1) == KEY_ON)
  49. {
  50. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
  51. }
  52. /* USER CODE BEGIN 3 */
  53. }
  54. /* USER CODE END 3 */
  55. }

四、复位、时钟、中断

复位

系统复位

当发生以下任一事件时,产生一个系统复位:

1. NRST引脚上的低电平(外部复位)

2. 窗口看门狗计数终止(WWDG复位)

3. 独立看门狗计数终止(IWDG复位)

4. 软件复位(SW复位)

5. 低功耗管理复位

电源复位

当以下事件中之一发生时,产生电源复位:

1. 上电/掉电复位(POR/PDR复位)

2. 从待机模式中返回

备份区复位

备份区域拥有两个专门的复位,它们只影响备份区域。

当以下事件中之一发生时,产生备份区域复位。

1. 软件复位,备份区域复位可由设置备份域控制寄存器 (RCC_BDCR)(见6.3.9节)中的

BDRST位产生。

2. 在VDD和VBAT两者掉电的前提下,VDD或VBAT上电将引发备份区域复位。

时钟控制

什么是时钟?

时钟打开,对应的设备才会工作。

时钟来源

三种不同的时钟源可被用来驱动系统时钟(SYSCLK)

HSI振荡器时钟(高速内部时钟)

HSE振荡器时钟(高速外部时钟)

PLL时钟(锁相环倍频时钟)

二级时钟源:

40kHz低速内部RC(LSIRC)振荡器

32.768kHz低速外部晶体(LSE晶体)

如何使用CubeMX配置时钟

 72MHz为最高

 

五、中断和事件

中断概述

什么是中断?

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的

程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。

什么是EXTI?

外部中断/事件控制器(EXTI)管理了控制器的 23 个中断/事件线。每个中断/事件线都对应有一

个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。 EXTI 可以实现对每个中断/事

件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

 EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所不
同。
产生中断线路目的是把输入信号输入到 NVIC,进一步会运行中断服务函数,实现功能,这样是软
件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号传
输,属于硬件级的。

EXTI初始化结构体:

  1. typedef struct
  2. {
  3. uint32_t Line; /*!< The Exti line to be configured. This parameter
  4. can be a value of @ref EXTI_Line */
  5. uint32_t Mode; /*!< The Exit Mode to be configured for a core.
  6. This parameter can be a combination of @ref EXTI_Mode */
  7. uint32_t Trigger; /*!< The Exti Trigger to be configured. This parameter
  8. can be a value of @ref EXTI_Trigger */
  9. uint32_t GPIOSel; /*!< The Exti GPIO multiplexer selection to be configured.
  10. This parameter is only possible for line 0 to 15. It
  11. can be a value of @ref EXTI_GPIOSel */
  12. } EXTI_ConfigTypeDef;

中断/事件线:

  1. #define EXTI_LINE_0 (EXTI_GPIO | 0x00u) /*!< External interrupt line 0 */
  2. #define EXTI_LINE_1 (EXTI_GPIO | 0x01u) /*!< External interrupt line 1 */
  3. #define EXTI_LINE_2 (EXTI_GPIO | 0x02u) /*!< External interrupt line 2 */
  4. #define EXTI_LINE_3 (EXTI_GPIO | 0x03u) /*!< External interrupt line 3 */
  5. #define EXTI_LINE_4 (EXTI_GPIO | 0x04u) /*!< External interrupt line 4 */
  6. #define EXTI_LINE_5 (EXTI_GPIO | 0x05u) /*!< External interrupt line 5 */
  7. #define EXTI_LINE_6 (EXTI_GPIO | 0x06u) /*!< External interrupt line 6 */
  8. #define EXTI_LINE_7 (EXTI_GPIO | 0x07u) /*!< External interrupt line 7 */
  9. #define EXTI_LINE_8 (EXTI_GPIO | 0x08u) /*!< External interrupt line 8 */
  10. #define EXTI_LINE_9 (EXTI_GPIO | 0x09u) /*!< External interrupt line 9 */
  11. #define EXTI_LINE_10 (EXTI_GPIO | 0x0Au) /*!< External interrupt line 10 */
  12. #define EXTI_LINE_11 (EXTI_GPIO | 0x0Bu) /*!< External interrupt line 11 */
  13. #define EXTI_LINE_12 (EXTI_GPIO | 0x0Cu) /*!< External interrupt line 12 */
  14. #define EXTI_LINE_13 (EXTI_GPIO | 0x0Du) /*!< External interrupt line 13 */
  15. #define EXTI_LINE_14 (EXTI_GPIO | 0x0Eu) /*!< External interrupt line 14 */
  16. #define EXTI_LINE_15 (EXTI_GPIO | 0x0Fu) /*!< External interrupt line 15 */
  17. #define EXTI_LINE_16 (EXTI_CONFIG | 0x10u) /*!< External interrupt line 16 Connected to the PVD Output */
  18. #define EXTI_LINE_17 (EXTI_CONFIG | 0x11u) /*!< External interrupt line 17 Connected to the RTC Alarm event */
  19. #if defined(EXTI_IMR_IM18)
  20. #define EXTI_LINE_18 (EXTI_CONFIG | 0x12u) /*!< External interrupt line 18 Connected to the USB Wakeup from suspend event */
  21. #endif /* EXTI_IMR_IM18 */
  22. #if defined(EXTI_IMR_IM19)
  23. #define EXTI_LINE_19 (EXTI_CONFIG | 0x13u) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
  24. #endif /* EXTI_IMR_IM19 */

 EXTI模式:产生中断、产生事件

  1. #define EXTI_MODE_NONE 0x00000000u
  2. #define EXTI_MODE_INTERRUPT 0x00000001u
  3. #define EXTI_MODE_EVENT 0x00000002u

 触发类型:上升沿、下降沿

  1. #define EXTI_TRIGGER_NONE 0x00000000u
  2. #define EXTI_TRIGGER_RISING 0x00000001u
  3. #define EXTI_TRIGGER_FALLING 0x00000002u
  4. #define EXTI_TRIGGER_RISING_FALLING (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING)

EXTI控制:

使能 EXTI ,一般都是使能, ENABLE

什么是优先级?

抢占优先级和响应优先级的区别:

高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行

什么是优先级分组?

Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:

第0组:所有4位用于指定响应优先级

第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级

第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级

第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级

第4组:所有4位用于指定抢占式优先级

什么是NVIC?

STM32通过中断控制器NVIC(Nested Vectored Interrupt Controller)进行中断的管理 。

NVIC是属于Cortex内核的器件,不可屏蔽中断(NMI)和外部中断都由它来处理,但是SYSTICK不是由NVIC控制的。

什么是中断向量表?

每个中断源都有对应的处理程序,这个处理程序称为中断服务程序,其入口地址称为中断向量。所有中断的中断服务程序入口地址构成一个表,称为中断向量表;也有的机器把中断服务程序入口的跳转指令构成一张表,称为中断向量跳转表。

五、按键点亮LED灯(中断法)

1. 配置时钟

同上

2. 配置GPIO口

A0、A1 设置为 EXIT0、EXIT1,

B0、B1 改为默认高电平 GPIO_Output

3. 使能中断

下降沿触发

 使能中断

4. 配置工程

同上

生成的代码:

  1. void MX_GPIO_Init(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStruct = {0};
  4. /* GPIO Ports Clock Enable */
  5. __HAL_RCC_GPIOD_CLK_ENABLE();
  6. __HAL_RCC_GPIOA_CLK_ENABLE();
  7. __HAL_RCC_GPIOB_CLK_ENABLE();
  8. /*Configure GPIO pin Output Level */
  9. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);
  10. /*Configure GPIO pins : PA0 PA1 */
  11. GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  12. GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  13. GPIO_InitStruct.Pull = GPIO_NOPULL;
  14. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  15. /*Configure GPIO pins : PB8 PB9 */
  16. GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
  17. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  18. GPIO_InitStruct.Pull = GPIO_NOPULL;
  19. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  20. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  21. /* EXTI interrupt init*/
  22. HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  23. HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  24. HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
  25. HAL_NVIC_EnableIRQ(EXTI1_IRQn);
  26. }

 

溯源可以找到一个虚函数(weak) 可以重写它

 

按键点亮LED灯

  1. /* Private user code ---------------------------------------------------------*/
  2. /* USER CODE BEGIN 0 */
  3. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  4. {
  5. switch(GPIO_Pin)
  6. {
  7. case GPIO_PIN_0:
  8. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
  9. break;
  10. case GPIO_PIN_1:
  11. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
  12. }
  13. }
  14. /* USER CODE END 0 */

加上消抖

  1. /* Private user code ---------------------------------------------------------*/
  2. /* USER CODE BEGIN 0 */
  3. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  4. {
  5. switch(GPIO_Pin)
  6. {
  7. HAL_Delay(20);//延时再判断,排除抖动
  8. case GPIO_PIN_0:
  9. //消抖:检测A0是否低电平
  10. if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
  11. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);//B8状态翻转
  12. break;
  13. case GPIO_PIN_1:
  14. //消抖:检测A1是否低电平
  15. if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_RESET)
  16. HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);//B9状态翻转
  17. break;
  18. }
  19. }
  20. /* USER CODE END 0 */

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/684938
推荐阅读
相关标签
  

闽ICP备14008679号