STM32hal库创建+LED控制演示+中断概念

1 如何使用STM32CubeMX创建ZET6项目

引言

大家好,今天我们将一起学习如何使用STM32CubeMX来创建一个基于ZET6的项目。如果你已经有一定的基础,那么这篇文章将帮助你快速回顾和深入理解创建项目的步骤。

准备工作

在开始之前,请确保你已经安装了STM32CubeMX软件,并且你的电脑可以连接到互联网,因为我们需要下载支持的单片机数据库。

创建项目的步骤

1. 打开STM32CubeMX

首先,打开STM32CubeMX界面。你应该会看到中间右半部分有三个创建项目的方式。由于我们使用的是非ST官方认证的开发板,我们将选择第一种方式:从单片机开始创建项目。

2. 访问MCU Selector

直接点击Access to MCU selector,这将打开单片机选择器。由于需要联网下载支持的单片机数据库,如果你的电脑没有联网,可能会出现报错,但不用担心,直接点击OK,我们仍然可以继续操作。

3. 搜索STM32F103VET6

在搜索框中输入STM32,然后按下回车。如果你使用的是中文输入法,可能会一次性出现两个芯片,这是正常的。我们需要找到STM32F103VET6芯片。

4. 选择正确的芯片

在搜索结果中,你会看到两个选项:一个带有TR后缀,一个没有。由于我们的芯片系列是ZET6,没有TR,所以我们选择第一个。

5. 收藏芯片

点击芯片旁边的星星,将其添加到收藏夹,这样下次可以直接在收藏夹中找到,无需再次搜索。

6. 开始创建项目

点击右上角的Start Project按钮,从这个单片机开始创建项目。

7. 操作STM32CubeMX

现在,你可以开始操作STM32CubeMX,让它显示创建项目的界面。

结语

好了,同学们,现在你们可以按照这些步骤去操作STM32CubeMX,创建自己的ZET6项目了。希望这篇文章能帮助你更好地理解和回顾今天的课程内容。

2 STM32内部架构的粗浅讲解

引言

大家好,今天我们将一起探讨STM32的内部架构。如果你已经有一定的基础,那么这篇文章将帮助你快速回顾和深入理解STM32的内部结构。

STM32CubeMX操作逻辑

首先,我们来看STM32CubeMX的操作逻辑。你会发现整个操作就是不停地“点点点”。比如每个引脚的功能,你可以看到整个芯片有144个引脚,每个引脚的功能都可以直接通过点击的方式进行配置。过去我们需要背计存器,但现在只要点一点,代码就自动生成了。

生成代码

完成配置后,我们可以看到右上角有一个按钮叫做“Generate Code”,意思是生成代码。这个工具的作用就是让你做一些配置,然后它自动帮你生成代码。

理解STM32架构的重要性

要想用好STM32CubeMX,你需要对我们的STM32架构和底层原理有所了解。如果不了解,面对这些配置可能会感到困惑。

STM32内部架构介绍

现在,我们先回来,把STM32的整体架构给大家做一下介绍。

CPU和外设

最左上角是我们的CPU,是我们的Cortex-M3内核。右下角这些都是我们的外设。

被动单元和主动单元

  • 被动单元:在整个架构里面,这个单元或部分硬件不会主动做事情。比如U盘,如果不插到电脑上,它不可能自己去删除文件或装载文件。
  • 主动单元:可以主动执行程序,比如电脑。

内部存储器

  • 内部Flash:相当于存储设备,用来存放代码。
  • 内部SRAM:相当于电脑的内存条,用来在运行时存放变量。

总线架构

  • AHB到APB的桥:AHB是高级高性能总线,分叉出两个总线,一个是APB2,一个是APB1,接的都是我们的外设。

总线矩阵

总线矩阵把所有的总线都集成在一起。它相当于转接员,CPU要找到某个外设,需要先把地址和数据报给总线矩阵,然后总线矩阵根据地址去找相应的外设。

结语

好了,同学们,今天的课程就到这里。你只需要对我们当前的架构有一个粗浅的位就可以了。后面等到我们每一次去讲某个硬件的时候,会回来看这个图的。

3. 内部架构与电脑主板类比

引言

大家好,今天我们将通过一个有趣的类比来理解STM32的内部架构。如果你已经对STM32有一定的了解,这篇文章将帮助你从一个新的角度来审视STM32的内部结构。

STM32的时钟树

在我们深入之前,先来回顾一下STM32的一个重要特性:AHB的主频是72兆,而APB2的主频也是72兆,APB1的主频是36兆。今天,我们将探讨这些频率之间的关系。

理解STM32内部架构

为了更好地理解STM32的内部架构,我们将把它与电脑主板进行类比。

主板与STM32框架

就像电脑主板一样,STM32的框架上也集成了各种组件。主板上装有CPU、GPU、内存条等,而STM32框架上则集成了Cortex-M3内核CPU、Flash(相当于固态硬盘)和SRAM(相当于内存条)。

外设与扩展

电脑需要外设,如移动硬盘、摄像头、麦克风、鼠标等。STM32也需要外设,这就需要我们通过类似于PCIE插槽的接口来扩展。在电脑主板上,我们可以通过PCIE插槽来扩展更多的设备,STM32也有类似的总线来连接外设。

AHB总线与PCIE插槽

AHB总线就像电脑主板上的PCIE插槽,速度非常快,但是直接连接的设备有限。因此,我们需要像扩展PCIE插槽一样,将AHB总线扩展为更多的APB总线,以连接更多的外设。

APB总线与USB接口

APB总线可以类比为电脑主板上的USB接口。有些外设对速度要求高,就像USB 3.0接口一样,我们可以将它们连接到APB2总线上。而对速度要求较低的外设,比如鼠标和键盘,可以连接到USB 2.0接口,对应STM32中的APB1总线。

结语

通过这种类比,我们可以看到STM32的内部架构与电脑主板有着惊人的相似性。这种理解方式可以帮助我们更好地把握STM32的工作原理和架构设计。

4. 为什么需要时钟信号

引言

大家好,今天我们将探讨一个在数字电路设计中非常基础但又至关重要的问题:为什么需要时钟信号。如果你已经对数字电路有所了解,这篇文章将帮助你深入理解时钟信号的作用。

时钟信号的必要性

在我们深入探讨之前,让我们先回顾一下STM32的架构。我们有AHB总线、APB2总线和APB1总线,它们的速度分别是72兆、72兆和36兆。接下来,我们将讨论时钟信号的重要性。

数字电路中的运算与存储

在数字电路中,我们有运算电路和存储电路。运算电路,如加法器,不需要时钟信号。但是,当我们涉及到存储电路,如D触发器和寄存器时,时钟信号变得必不可少。

时钟信号与存储电路

D触发器是基本的存储单元,它需要时钟信号来同步数据的存储。当我们将D触发器组合成寄存器时,时钟信号的作用变得更加明显。寄存器可以存储多个比特,每个比特都由一个D触发器控制,都需要时钟信号。

时钟信号与外设配置

在STM32中,每个外设都有配置寄存器。如果不打开时钟信号,这些寄存器就无法写入,外设也就无法工作。这就是为什么在编写代码时,我们需要先打开时钟。

节能考虑

STM32设计了一个专门的模块RCC(Reset and Clock Controller),用来控制哪些外设可以获得时钟信号。这种设计主要是为了省电。如果默认打开所有外设的时钟信号,将会消耗更多的能量。

结语

通过今天的学习,我们了解到时钟信号在数字电路中的重要性,特别是在存储电路和外设配置中。时钟信号不仅确保了数据的正确存储,还帮助我们节省能源。

4. 为什么需要时钟信号

引言

大家好,今天我们将探讨一个在数字电路设计中非常基础但又至关重要的问题:为什么需要时钟信号。如果你已经对数字电路有所了解,这篇文章将帮助你深入理解时钟信号的作用。

时钟信号的必要性

在我们深入探讨之前,让我们先回顾一下STM32的架构。我们有AHB总线、APB2总线和APB1总线,它们的速度分别是72兆、72兆和36兆。接下来,我们将讨论时钟信号的重要性。

数字电路中的运算与存储

在数字电路中,我们有运算电路和存储电路。运算电路,如加法器,不需要时钟信号。但是,当我们涉及到存储电路,如D触发器和寄存器时,时钟信号变得必不可少。

时钟信号与存储电路

D触发器是基本的存储单元,它需要时钟信号来同步数据的存储。当我们将D触发器组合成寄存器时,时钟信号的作用变得更加明显。寄存器可以存储多个比特,每个比特都由一个D触发器控制,都需要时钟信号。

时钟信号与外设配置

在STM32中,每个外设都有配置寄存器。如果不打开时钟信号,这些寄存器就无法写入,外设也就无法工作。这就是为什么在编写代码时,我们需要先打开时钟。

节能考虑

STM32设计了一个专门的模块RCC(Reset and Clock Controller),用来控制哪些外设可以获得时钟信号。这种设计主要是为了省电。如果默认打开所有外设的时钟信号,将会消耗更多的能量。

结语

通过今天的学习,我们了解到时钟信号在数字电路中的重要性,特别是在存储电路和外设配置中。时钟信号不仅确保了数据的正确存储,还帮助我们节省能源

5. 内部、外部、高速、低速时钟源之分

引言

大家好,今天我们将讨论STM32中的时钟源,特别是内部和外部时钟源的区别,以及高速和低速时钟源的应用。这些知识对于理解STM32的工作原理至关重要。

时钟树的概念

首先,我们来看一下时钟树。时钟树是一套硬件电路,专门用于控制时钟的生成和供给。它的作用是为外设提供时钟信号。

时钟树的结构

在STM32中,时钟树的顶部有AHB总线、APB2总线和APB1总线,下面则是各种外设。时钟树的主要功能是将时钟信号从源头传递到各个外设。

时钟信号的生成

STM32的时钟信号生成需要经过一系列处理。例如,虽然AHB的主频是72MHz,但外部晶振通常是8MHz。因此,8MHz的信号需要经过处理才能生成72MHz的时钟信号。

内部与外部时钟源

STM32有两棵独立的时钟树:一棵是为所有外设服务的,另一棵是专门为RCC模块服务的。我们今天主要关注的是为外设服务的那棵大树。

外部时钟源

外部时钟源包括高速和低速时钟源。高速时钟源通常是8MHz,而低速时钟源则是32.768kHz。外部时钟源的优势在于其稳定性和精确性。

内部时钟源

STM32内部也有时钟源,通常是RC振荡电路。RC振荡电路由电阻和电容组成,能够生成时钟信号,但对温度变化非常敏感,因此不够稳定。

时钟源的选择

在设计电路时,我们需要根据具体需求选择时钟源:

  • 使用外部晶振:当需要高精度和稳定性时,选择外部晶振是最佳选择,尤其是在对时钟信号要求较高的应用中。
  • 使用内部时钟源:在对时钟精度要求不高的简单应用中,可以使用内部时钟源来降低成本。

结语

今天我们学习了STM32中的时钟源,包括内部和外部时钟源的区别,以及高速和低速时钟源的应用。理解这些概念将帮助你更好地设计和调试STM32项目。

6. 时钟树是如何生成时钟信号的

引言

大家好,今天我们将深入探讨STM32的时钟树是如何生成时钟信号的。这对于理解STM32的时钟系统和外设配置至关重要。

时钟树的构成

时钟树分为两部分:上半部分负责时钟供给,下半部分负责时钟生成。我们今天主要关注下半部分,也就是时钟生成。

分频器(Prescaler)

时钟树中的分频器用于降低时钟频率。如果标记为“/2”,则表示将时钟频率降低到原来的二分之一;如果标记为“/4”,则降低到四分之一。

锁相环(PLL)

锁相环是时钟树中的一个重要组件,它可以根据配置倍频。锁相环可以将时钟频率提高到2倍、3倍、4倍,一直到16倍。

时钟信号的生成过程

内部时钟源

STM32内部的高速时钟源(HSI)本身就是8MHz。如果需要8MHz的主频,可以直接使用内部时钟源。

外部时钟源

如果追求更好的精度,可以使用外部时钟源。STM32的数据手册允许使用4到16MHz的外部晶振,通常情况下我们选择8MHz。

生成8MHz主频

  • 直接输出:外部8MHz晶振可以直接输出8MHz的主频。
  • 分频后倍频:也可以先分频再倍频,例如8MHz分频后变为4MHz,再倍频回到8MHz。

生成12MHz主频

  • 内部时钟源:需要先分频(8MHz / 2 = 4MHz),然后倍频(4MHz * 3 = 12MHz)。
  • 外部时钟源:可以直接输入8MHz,然后分频(8MHz / 2 = 4MHz),再倍频(4MHz * 3 = 12MHz)。

生成72MHz主频

  • 内部时钟源:需要先分频(8MHz / 2 = 4MHz),然后倍频(4MHz * 18 = 72MHz)。但锁相环最高支持16倍频,因此内部时钟源最高只能达到60MHz。
  • 外部时钟源:可以直接输入8MHz,然后倍频(8MHz * 9 = 72MHz)。

结语

通过今天的学习,我们了解了STM32时钟树是如何生成时钟信号的。我们探讨了内部和外部时钟源的使用,以及如何通过分频器和锁相环生成所需的时钟频率。

7. HAL库的SYS和RCC基本配置

引言

大家好,今天我们将进入实操环节,学习如何在STM32项目中配置系统(SYS)和复位及时钟控制(RCC)。

系统工作模式(SYS)配置

1. 打开STM32CubeMX

首先,我们打开STM32CubeMX软件,准备进行配置。

2. 配置系统工作模式

在左侧菜单中找到SYS选项。这里配置的是系统工作模式,而非系统时钟。

3. 选择调试模式

在SYS配置中,我们需要选择调试模式。这里涉及到STlink的使用,STlink仅支持ST公司的ARM内核芯片的调试。

  • STlink:选择“Serial Wire”(SW)模式,这是串行线调试模式。

4. 确保正确配置

确保选择了SW模式,否则芯片将无法进行二次烧录。如果选择了“No Debug”,需要将芯片的启动模式改为Boot模式,这通常需要硬件上的飞线操作。

时钟配置(RCC)

1. 打开RCC配置

在STM32CubeMX中,找到并打开RCC配置。

2. 选择时钟源

在RCC配置中,我们需要选择时钟源。通常有两种时钟源:

  • 高速时钟(HSE):高速外部时钟源。
  • 低速时钟(LSE):低速外部时钟源。

3. 选择晶体振荡器

选择晶体振荡器(Crystal Oscillator)作为时钟源,这是外部晶振。

4. 配置时钟

点击“Clock Configuration”页面,这里会显示一个详细的时钟配置图,可以进行详细的时钟设置。

结语

通过今天的学习,我们了解了如何在STM32CubeMX中进行SYS和RCC的基本配置。这些配置对于项目的后续开发至关重要。

8. CubeMX的时钟配置

引言

大家好,今天我们将学习如何在STM32CubeMX中配置时钟。时钟配置是嵌入式系统开发中的重要环节,正确的时钟配置可以确保系统的稳定性和性能。

时钟配置图解

首先,我们来看一下时钟配置的图。这个图非常易读,下面的部分是用来输出时钟信号的,基本上不需要关注。中间的竖线将图分为两部分:

  • 左侧:芯片的外部部分。
  • 右侧:芯片的内部部分。

时钟源选择

在时钟配置中,你会发现当前默认使用的是外部时钟信号。具体来说,有两个时钟源:

  • 32.768 kHz:用于低速时钟。
  • 8 MHz:用于高速时钟。

需要注意的是,如果你使用了外部的低速晶振,那么只能使用32.768 kHz的频率。

时钟树的结构

STM32的时钟树分为两部分:

  1. 高速时钟:用于驱动外设。
  2. 低速时钟:仅用于RTC模块。

高速时钟配置

在时钟配置中,当前的时钟源是内部的RC震荡电路(HSI),而外部时钟源(HSE)则是8 MHz。我们希望将AHB的频率提升到72 MHz。

切换时钟源

要切换到外部时钟信号,首先需要选择PLL(锁相环)作为倍频器。通过PLL,我们可以将外部时钟信号进行倍频处理。

  1. 选择PLL:将输入源设置为外部时钟。
  2. 配置倍频:将倍频系数设置为9倍,以达到72 MHz的主频。

APB总线配置

在配置APB总线时,要注意APB1的最高频率为36 MHz。如果AHB频率超过APB1的最大频率,需要使用分频器将其降低。

  1. 分频器设置:将APB1的分频系数设置为2,以确保其频率不超过36 MHz。

结语

通过今天的学习,我们了解了如何在STM32CubeMX中进行时钟配置,包括选择时钟源、配置倍频和设置APB总线的分频。正确的时钟配置对于确保系统的稳定性和性能至关重要。

9. CubeMX LED GPIO的配置

引言

大家好,今天我们将学习如何在STM32CubeMX中配置LED的GPIO。通过这个实操案例,我们将了解如何为LED灯配置GPIO引脚。

GPIO配置步骤

1. 打开STM32CubeMX

首先,打开STM32CubeMX软件,准备进行GPIO配置。

2. 选择GPIO引脚

在STM32CubeMX中,找到并选择我们需要配置的GPIO引脚。通常,这些引脚已经被归类在GPIO栏目下。

3. 配置PA0、PA1和PA8

我们需要为PA0、PA1和PA8引脚做一些相关配置。这些引脚将被用作LED灯的控制引脚。

PA0配置
  • 功能选择:选择GPIO推挽输出(GPIO Output)。
  • 默认电平:设置为高电平(High),确保开机时LED灯熄灭。
  • 模式:选择推挽输出(Push Pull)。
  • 上拉/下拉:无上拉下拉(No Pull)。
  • 输出速度:选择最高速度(50 MHz)。
  • 用户标签:设置为LED0,方便代码中操作。
PA1配置
  • 功能选择:选择GPIO推挽输出(GPIO Output)。
  • 默认电平:设置为高电平(High)。
  • 模式:选择推挽输出(Push Pull)。
  • 上拉/下拉:无上拉下拉(No Pull)。
  • 输出速度:选择最高速度(50 MHz)。
  • 用户标签:设置为LED1。
PA8配置
  • 功能选择:选择GPIO推挽输出(GPIO Output)。
  • 默认电平:设置为高电平(High)。
  • 模式:选择推挽输出(Push Pull)。
  • 上拉/下拉:无上拉下拉(No Pull)。
  • 输出速度:选择最高速度(50 MHz)。
  • 用户标签:设置为LED2。

4. 保存配置

完成配置后,保存并生成代码,以便在项目中使用。

结语

通过今天的学习,我们了解了如何在STM32CubeMX中配置LED的GPIO引脚。这些步骤将帮助我们在项目中轻松控制LED灯的状态。

10. 如何关闭不小心多配的引脚

引言

大家好,今天咱们来聊一个在配置STM32时经常遇到的问题:如果不小心多配置了一个引脚,该如何撤销这个操作。

撤销多余引脚配置的步骤

1. 识别问题

有时候在配置GPIO时,可能会不小心配置错了引脚,比如将PA9错误地配置成了输出。

2. 撤销配置

如果你需要撤销这个错误的配置,不要直接在左侧列表中尝试删除。正确的做法是:

步骤2.1 重新选择引脚
  • 直接点击你想要撤销配置的引脚(例如PA9)。
步骤2.2 重置为默认状态
  • 在配置界面中,找到“复位状态”(Reset State)选项。这个选项会将引脚恢复到开机复位后的状态,即默认状态。

3. 确认更改

  • 选择“复位状态”后,相当于什么都没发生过,引脚配置被撤销。

结语

通过上述步骤,你可以轻松地撤销那些不小心多配置的引脚。这是一个简单但实用的技巧,希望对你有所帮助

11. 生成HAL项目

引言

大家好,今天我们将学习如何在STM32CubeMX中生成HAL项目。在完成了时钟、RCC和GPIO的配置之后,我们就可以开始生成代码,准备编写程序了。

生成HAL项目的步骤

1. 打开Project Manager

在STM32CubeMX中,点击右侧的Project Manager,准备生成代码。

2. 配置项目名称和位置

在生成代码之前,需要对项目进行一些基本配置。

项目名称(Project Name)
  • 指定一个项目名称,例如“04LEDFlow”。
项目位置(Project Location)
  • 选择项目存放的路径,确保路径中不包含中文字符,以避免生成过程中出现问题。

3. 选择IDE和工具链

选择你将使用的IDE和工具链。例如,如果你使用的是Keil MDK-ARM,就需要选择对应的选项。

4. 配置代码生成选项

在Code Generator选项中,有一些重要的配置需要设置。

包含必要的库(Copy only the necessary libraries)
  • 建议勾选这个选项,以减少项目体积和编译时间,只包含项目实际需要的库。
生成成对的C和H文件(Generate paired C/H files for each peripheral)
  • 勾选这个选项,为每个外设生成对应的C和H文件,方便管理和操作外设。

5. 生成代码

配置完成后,点击右上角的“Code”按钮,开始生成代码。

6. 确保路径无中文

在生成代码时,确保项目路径中不包含中文字符,否则生成过程可能会失败。

结语

通过上述步骤,我们可以在STM32CubeMX中成功生成HAL项目。这些步骤将帮助我们快速开始STM32的HAL库开发。

12. 如何打开HAL库项目

引言

大家好,今天我们将学习如何在STM32CubeMX中成功生成HAL项目后,如何打开并开始操作这个项目。

打开HAL项目的步骤

1. 生成代码

在STM32CubeMX中配置完成后,点击“Code”生成代码。如果生成成功,会显示“the code is successfully generated”。

2. 关闭STM32CubeMX

生成代码后,可以选择关闭STM32CubeMX或者直接点击“Open Project”尝试打开项目。

3. 定位项目文件夹

关闭STM32CubeMX后,回到项目的所在路径,找到生成的文件夹,例如“04LEDFlowHAL”。

4. 理解项目结构

在项目文件夹中,你会看到以下文件和文件夹:

  • 项目名称文件夹:与项目名称相同的文件夹,例如“04LEDFlowHAL”。
  • .MXworkspace:STM32CubeMX的工作空间文件,记录项目配置信息。
  • ** INC**:包含各种头文件的文件夹。
  • ** SRC**:包含源文件的文件夹。

5. 打开Keil MDK-ARM项目

在MDK-ARM中打开项目,通常是一个.uvproj文件。双击该文件,可以直接打开Keil MDK-ARM并加载项目。

6. 检查项目配置

在Keil MDK-ARM中,检查项目配置是否正确,包括STlink配置和自动reset设置。

7. 识别项目路径

确保你的工作路径是项目的根目录,这样Keil MDK-ARM才能正确识别和加载项目文件。

8. 开始编码

SRC文件夹中找到main.c文件,这是HAL库为你生成的主函数文件,你可以在这里开始编写代码。

结语

通过上述步骤,你可以成功打开并开始操作STM32的HAL库项目。这些步骤将帮助你快速进入开发状态。

13. HAL库编写代码的注意事项

引言

大家好,今天我们将讨论在使用STM32 HAL库编写代码时需要注意的一些重要事项,以确保我们的代码既安全又高效。

编写代码的注意事项

1. 注释的重要性

在HAL库生成的代码中,包含了大量的注释。这些注释不应该被删除,因为它们包含了重要的信息和指导。

用户代码区域
  • 注释中会特别标记出“用户代码”区域,通常在/* USER CODE BEGIN *//* USER CODE END */之间。
  • 这是你编写自定义代码的安全区域,确保在这些注释之间添加或修改代码。

2. 代码覆盖风险

如果你在“用户代码”区域外编写代码,重新生成代码时,这些代码可能会被覆盖。

举例说明
  • 假设你在用户代码区域外添加了一些测试代码,然后重新生成代码,这些测试代码将被新生成的代码覆盖。

3. 代码重新生成

当你需要修改配置或更新HAL库时,你可能需要重新生成代码。

重新生成的影响
  • 任何在“用户代码”区域外的代码都将被新生成的代码覆盖。
  • 因此,始终在“用户代码”区域内编写代码,以保护你的自定义代码不被覆盖。

4. 用户代码区域的使用

HAL库为用户提供了多个代码区域,包括:

  • User Code Begin Include:用于添加自定义头文件。
  • User Code Begin:用于添加初始化代码。
  • User Code End:用于添加清理代码。
正确使用用户代码区域
  • 确保所有自定义代码都位于这些区域内,以避免在代码重新生成时丢失。

结语

通过遵循这些简单的指导原则,你可以确保在使用STM32 HAL库时,你的代码安全、有效,并且能够顺利地与HAL库集成。

14. 使用HAL库翻转LED1灯的状态

引言

大家好,今天我们将学习如何使用STM32的HAL库来翻转LED1灯的状态。这是一个基础操作,对于理解HAL库如何控制GPIO非常有帮助。

HAL库操作LED的步骤

1. 理解HAL库文件结构

在HAL库项目中,我们有两个重要的头文件:main.hgpio.h。HAL库会为我们生成初始化代码,包括时钟配置和GPIO配置。

2. 时钟配置

main.c文件中,HAL库会声明一个SystemClock_Config函数原型,用于系统的时钟配置。这个函数的实现也在main.c文件中,负责配置PLL(锁相环)和其他时钟相关设置。

3. GPIO初始化

HAL库还会为我们生成一个以MX开头的函数,例如MX_GPIO_Init,用于初始化我们之前在CubeMX中配置的GPIO。

4. 编写翻转LED状态的代码

main.c中,我们可以编写代码来翻转LED1的状态。以下是具体的步骤:

步骤4.1 包含头文件

c

#include "main.h"
#include "gpio.h"
步骤4.2 编写翻转LED的函数

main.c中,我们可以添加以下代码来翻转LED1的状态:

c

void Toggle_LED1(void) {HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
}

这个函数使用HAL_GPIO_TogglePin函数来翻转GPIOA的第1个引脚(即LED1)的状态。

步骤4.3 在主循环中调用翻转函数

main函数的无限循环中,我们可以调用Toggle_LED1函数,并添加适当的延时:

c

int main(void) {// HAL初始化HAL_Init();// 配置系统时钟SystemClock_Config();// 初始化GPIOMX_GPIO_Init();while (1) {Toggle_LED1(); // 翻转LED1状态HAL_Delay(1000); // 延时1秒}
}

5. 编译和烧录

编写完代码后,编译项目并烧录到STM32芯片中。如果一切顺利,你应该能看到LED1灯每秒翻转一次状态。

结语

通过今天的学习,我们了解了如何使用HAL库来控制LED的状态。这是一个非常基础的操作,但对于理解HAL库如何工作非常有帮助。

15. 阅读HAL_GPIO_WritePin源码

引言

大家好,今天我们将深入了解HAL库中的HAL_GPIO_WritePin函数的源码,理解它是如何工作的,以及为什么HAL库在实际开发中非常重要。

HAL库的重要性

1. HAL库在项目中的应用

HAL库提供了许多便捷的操作,使得我们不需要直接操作寄存器,从而简化了代码的编写。但同时,理解HAL库背后的实现原理对于深入掌握STM32编程至关重要。

2. 查看源码的方法

查看源码时,首先应该查看函数的注释,这有助于我们快速理解函数的作用和实现方式。

分析HAL_GPIO_WritePin函数

1. 函数的作用

HAL_GPIO_WritePin函数用于设置GPIO引脚的状态,可以是高电平(Set)或低电平(Reset)。

2. 参数校验

函数首先会进行参数校验,确保传入的参数是有效的。这是HAL库非常周到的一点,它确保了传入的参数是合法的,避免了非法参数导致的问题。

3. 断言(Assert)

HAL库使用断言来检查参数是否合法。如果参数不合法,程序将不会执行后续的代码。

4. 根据引脚状态进行操作

函数会根据传入的引脚状态(Set或Reset)来决定是将引脚设置为高电平还是低电平。

5. 寄存器操作

底层操作仍然是对寄存器的操作。HAL库将这些操作封装成了函数,使得我们不需要直接编写寄存器操作代码。

6. BSRR寄存器

HAL_GPIO_WritePin函数通过操作BSRR(Bit Set/Reset register)寄存器来改变GPIO引脚的状态。如果传入的是Set,它会将对应的位设置为1;如果是Reset,它会将对应的位设置为0。

结语

通过今天的学习,我们了解了HAL_GPIO_WritePin函数的工作原理,以及HAL库如何通过封装寄存器操作来简化我们的开发工作。这对于我们深入理解STM32的HAL库和提高编程技能非常有帮助

16. 在HAL库中添加LED的C和H文件

引言

大家好,今天我们将学习如何在STM32的HAL库项目中添加自定义的LED控制代码。这包括创建新的C和H文件,并在项目中正确配置这些文件。

添加LED控制代码的步骤

1. 理解HAL库项目结构

在HAL库项目中,我们通常不需要修改由STM32CubeMX自动生成的文件。相反,我们应该将自定义代码放在单独的文件中,以保持项目的整洁和可维护性。

2. 创建新的C和H文件

我们将创建两个新文件:一个C文件(实现文件)和一个H文件(头文件),用于控制LED。

步骤2.1 创建文件夹
  • 在项目目录中创建一个名为Hardware的新文件夹。
  • Hardware文件夹内,创建一个名为LED的子文件夹。
步骤2.2 添加文件
  • LED文件夹内,创建LED.cLED.h文件。

3. 配置Keil MDK-ARM项目

步骤3.1 添加源文件
  • 打开Keil MDK-ARM项目。
  • 右键点击项目,选择“Add Files to Group ‘Source’”。
  • 浏览并添加LED.c文件。
步骤3.2 添加头文件
  • 右键点击项目,选择“Options for Target”。
  • 选择“C/C++”标签页,然后选择“Preprocessor”。
  • 点击“Add”按钮,添加LED文件夹的路径,以便项目可以找到LED.h文件。

4. 编写LED控制代码

LED.c文件中,我们可以添加如下代码来控制LED:

c

#include "LED.h"void LED_Init(void) {GPIO_InitTypeDef GPIO_InitStruct = {0};// 配置GPIO
}void LED_On(void) {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
}void LED_Off(void) {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
}

LED.h文件中,我们声明这些函数:

c

#ifndef __LED_H
#define __LED_H#include "stm32f4xx_hal.h"void LED_Init(void);
void LED_On(void);
void LED_Off(void);#endif

5. 编译和烧录

编译项目并烧录到STM32芯片中。如果一切顺利,你应该能够通过LED_OnLED_Off函数控制LED的状态。

结语

通过今天的学习,我们了解了如何在HAL库项目中添加自定义的C和H文件来控制LED。这不仅有助于我们更好地组织代码,也使得项目更加模块化和易于维护。

17. 路径解释

引言

大家好,今天我们将深入理解在STM32 HAL库项目中配置路径的重要性,以及如何正确地添加和引用自定义文件。

理解项目路径配置

1. Project Items配置

在Keil MDK-ARM项目中,Project Items是指项目中包含的所有源文件。如果你添加了一个新的C文件,比如LED.c,你需要将其添加到Project Items中,以便在编译时能够包含这个文件。

2. 添加C文件

  • 打开Keil MDK-ARM项目。
  • 右键点击项目,选择“Add Files to Group ‘Source’”。
  • 浏览并添加你的自定义C文件,如LED.c

3. CC++ Include Paths配置

当我们在C文件中引用H文件时,编译器需要知道在哪里找到这些H文件。这就是为什么我们需要配置CC++ Include Paths

4. 包含自定义H文件

假设你在Hardware/LED文件夹中创建了LED.h文件,你需要确保编译器能够找到这个文件。如果LED.h不在项目的Include Path中,编译器将报错,提示找不到LED.h

5. 路径的特殊含义

  • ..:表示上一级目录。
  • /:表示目录分隔符,Windows系统中可以是正斜杠/或反斜杠\

6. 配置Include Path

在Keil MDK-ARM中,你需要将自定义H文件的路径添加到CC++ Include Paths中。这样,编译器就会在这些路径中查找引用的H文件。

7. 路径配置示例

假设你的项目结构如下:

Project
│
├── MDK-ARM
│   ├── Group
│   │   └── Source
│
└── Hardware└── LED└── LED.h

你需要在Keil MDK-ARM中配置Include Path../Hardware/LED,以便编译器能够找到LED.h文件。

结语

通过今天的学习,我们了解了如何在Keil MDK-ARM项目中配置路径,以及如何确保编译器能够找到我们的自定义文件。这对于管理大型项目和维护代码的整洁性至关重要。

18. HAL库中写LED的C和H文件

引言

大家好,今天我们将学习如何在STM32的HAL库项目中编写LED的C和H文件。这将帮助我们更好地理解和控制硬件操作。

编写LED的H文件

1. 创建LED.h

Hardware/LED文件夹中创建LED.h文件,并添加以下内容:

c

#ifndef __LED_H
#define __LED_H#include "stm32f4xx_hal.h"void LED_Init(void);
void LED_On(void);
void LED_Off(void);
void LED_Toggle(void);#endif

2. 包含LED.h

main.c或其他需要控制LED的C文件中,包含LED.h

c

#include "LED.h"

编写LED的C文件

1. 创建LED.c

Hardware/LED文件夹中创建LED.c文件,并添加以下内容:

c

#include "LED.h"// 假设LED连接在GPIOA的PIN1
#define LED_PIN GPIO_PIN_1
#define LED_GPIO_PORT GPIOAvoid LED_Init(void) {GPIO_InitTypeDef GPIO_InitStruct = {0};// GPIO端口时钟使能__HAL_RCC_GPIOA_CLK_ENABLE();// 配置GPIO引脚为推挽输出模式GPIO_InitStruct.Pin = LED_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
}void LED_On(void) {HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, GPIO_PIN_SET);
}void LED_Off(void) {HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, GPIO_PIN_RESET);
}void LED_Toggle(void) {HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_PIN);
}

2. 编译和烧录

编译项目并烧录到STM32芯片中。如果一切顺利,你应该能够通过LED_OnLED_OffLED_Toggle函数控制LED的状态。

结语

通过今天的学习,我们了解了如何在HAL库项目中编写LED的C和H文件,并控制LED的状态。这不仅有助于我们更好地组织代码,也使得项目更加模块化和易于维护。

19. 自动补全操作技巧

引言

大家好,今天我们将分享一些关于自动补全的操作技巧,这些技巧将帮助我们更高效地编写代码。

自动补全的常见问题

1. 省略号问题

在使用自动补全功能时,有时函数名可能会被省略,只显示为省略号,这使得我们无法看到函数的全称,从而不清楚具体的函数是什么。

2. 解决方法

步骤2.1 展开函数提示
  • 使用鼠标点击自动补全列表中的第一项右侧的箭头,展开函数提示。
步骤2.2 查看完整函数名
  • 展开后,函数的完整名称会显示在代码编辑区域的右侧,这样我们就可以清楚地看到函数的具体名称。
步骤2.3 记忆用户偏好
  • 这个设置会被VSCode记忆,下次打开时不需要再次点击。

3. 避免函数名被省略

通过上述操作,我们可以避免函数名被省略的问题,确保我们能够看到函数的全称,从而更好地理解代码。

结语

通过今天的学习,我们掌握了如何在使用自动补全功能时查看函数的完整名称,这将提高我们的编码效率和准确性

20. HAL库主要逻辑:同时亮、同时灭的实现效果

引言

大家好,今天我们将学习如何在STM32的HAL库中实现LED灯的同时亮起和熄灭。这是一个基础但重要的操作,有助于我们理解HAL库的控制逻辑。

实现同时亮、同时灭的步骤

1. 封装LED控制函数

首先,我们在HAL库中封装了三个基本的LED控制函数:LED_OnLED_OffLED_Toggle

2. 在main.c中编写主要逻辑

我们需要在main.c文件的main函数中编写逻辑,以控制LED灯。

步骤2.1 包含LED头文件

main.c中包含我们之前创建的LED.h头文件:

c

#include "LED.h"
步骤2.2 编写控制逻辑

main函数中,我们可以使用HAL_GPIO_WritePin函数来同时控制多个LED灯的状态。以下是实现同时亮和同时灭的代码示例:

c

int main(void) {// HAL初始化HAL_Init();// 配置系统时钟SystemClock_Config();// 初始化LEDLED_Init();while (1) {// 同时亮HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_SET);// 延时HAL_Delay(1000);// 同时灭HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_RESET);// 延时HAL_Delay(1000);}
}

3. 编译和烧录

编译项目并烧录到STM32芯片中。如果一切顺利,你应该能够看到LED灯按照代码逻辑同时亮起和熄灭。

注意事项

  • 确保不要删除或修改usercode区域的注释,因为STM32CubeMX依赖这些注释来识别用户代码区域。
  • 如果你删除了GPIO初始化函数,需要重新生成代码或手动调用初始化函数,以确保LED能够正常工作。

结语

通过今天的学习,我们掌握了如何在HAL库中实现LED灯的同时亮起和熄灭。这不仅有助于我们更好地理解HAL库的控制逻辑,也为我们后续的项目开发打下了基础。

21. 复习中断和优先级的概念

引言

大家好,今天我们将复习中断和优先级的概念,这对于理解STM32的中断处理机制非常重要。

中断的概念

1. 中断的定义

中断是指在程序执行过程中,由于某些紧急事件需要立即处理,CPU暂停当前任务,转而去处理这些紧急事件的机制。

2. 中断的例子

就像你在听音乐时,女朋友突然推荐一首歌给你,你需要暂停当前的音乐去听她推荐的歌曲,听完后再继续听原来的音乐。

3. 中断的处理

中断处理需要CPU暂停当前任务,处理紧急事件,然后再返回到原来的任务继续执行。

中断的优先级

1. 优先级的定义

在多个紧急事件同时发生时,需要根据事件的优先级来决定处理顺序。

2. 优先级的例子

就像你在游戏中推塔时,女朋友要求你听歌曲,如果游戏(高优先级事件)正在进行,你可能会选择先暂停歌曲,处理游戏中的紧急情况。

3. 中断嵌套

如果一个高优先级的中断可以打断一个低优先级的中断,这种情况称为中断嵌套。

4. 中断排队

如果所有中断优先级都高于当前执行的中断,这些中断将排队等待处理。

STM32的中断处理

1. STM32中断复杂性

STM32的中断处理比简单的定义和例子要复杂,涉及到具体的硬件和软件配置。

2. 为什么需要中断

中断机制允许微控制器及时响应外部事件,这对于实时系统尤为重要。

结语

通过今天的复习,我们重新理解了中断和优先级的概念,以及它们在STM32微控制器中的应用。这些知识对于后续的学习和项目开发非常有帮助。

22. 我们的单片机不属于互联星

引言

大家好,今天我们来聊聊STM32单片机的中断系统,特别是它与8051单片机的比较,以及STM32的中断数量和类型。

STM32与8051中断数量比较

1. 8051中断数量

8051单片机的中断数量相对有限,通常外部中断数量大约为8个。

2. STM32中断数量

STM32的Cortex-M3内核原生支持的中断数量为256个,这在资源上远远超过了8051单片机。

中断类型

1. 内核中断

STM32支持16个内核中断。

2. 外部中断

STM32支持240个外部中断。

3. 可编程中断

STM32具有256级的可编程中断设置。

区分内核中断和外部中断

内核中断和外部中断是两个不同的概念,需要区分开来。

互联型与非互联型单片机

1. 互联型单片机

互联型单片机指的是那些原生支持网络通信功能的芯片,不需要外挂任何模块即可直接联网。

2. 非互联型单片机

我们的STM32单片机不属于互联型,因为它需要通过外挂以太网模块来实现网络通信功能。

3. 原生支持与外挂模块

  • 原生支持:芯片内部集成了网络通信功能,如华为海思芯片集成5G基带。
  • 外挂模块:需要通过外部连接模块来实现网络通信,如我们的STM32单片机通过外挂以太网模块。

STM32中断和事件

1. NVIC

STM32的中断和事件由NVIC(Nested Vectored Interrupt Controller)管理。

2. 中断向量表

在STM32的参考手册中,第九章详细介绍了中断和事件中断,包括中断向量表。

结语

通过今天的学习,我们了解了STM32单片机的中断系统,包括中断数量、类型以及如何区分内核中断和外部中断。我们还了解了STM32单片机不属于互联型单片机,需要通过外挂模块实现网络通信。

23. STM32中断源头一览

引言

大家好,今天我们将深入了解STM32的中断系统,包括中断的来源、类型以及如何管理这些中断。

中断系统概述

1. 中断类型数量

STM32的Cortex-M3内核支持多达256个中断源,这些中断源分为内核中断和外部中断。

2. 内核中断与外部中断

  • 内核中断:源自CPU内部的中断,例如SysTick定时器。
  • 外部中断:源自芯片外部的中断,例如GPIO中断。

NVIC的作用

1. NVIC定义

NVIC(Nested Vectored Interrupt Controller)是STM32中用于管理所有中断信号的模块,负责分配中断优先级。

2. NVIC的功能

NVIC允许开发者为每个中断信号配置优先级,这是与8051等其他单片机的一个显著区别。

中断来源

1. 内核内部中断

例如SysTick定时器,这些中断源自CPU内部。

2. 片上外设中断

例如USART(串口)、TIM(定时器)等,这些中断源自STM32的片上外设。

3. 外部中断

例如GPIO引脚的中断,这些中断源自芯片外部。

中断优先级配置

1. 优先级范围

STM32的中断优先级从0到63,其中0是最高优先级。

2. 可配置性

大多数中断的优先级都可以手动配置,但有一些如复位中断的优先级是固定的。

3. 固定优先级中断

例如复位中断,其优先级是最高的,不能更改。

结语

通过今天的学习,我们了解了STM32中断系统的基本概念,包括中断的来源、NVIC的作用以及如何配置中断优先级。

24. 外部中断的传输路径

引言

大家好,今天我们将探讨STM32中外部中断的传输路径,了解外部中断是如何被触发和处理的。

外部中断的定义

1. 外部中断的来源

外部中断通常来源于外部传感器或按键,它们可以通过发送上升沿或下降沿信号来触发中断。

2. 外部中断的逻辑

外部中断是指通过GPIO引脚发送的信号,这些信号可以是高电平或低电平,用于触发中断服务函数。

中断传输路径

1. GPIO引脚的角色

外部中断信号需要通过STM32的GPIO引脚传输。这些引脚可以工作在通用模式或复用模式。

2. 通用模式与复用模式

  • 通用模式:控制权在CPU手中,适用于简单的输入输出操作。
  • 复用模式:控制权交给其他片上外设,适用于更复杂的功能,如外部中断。

3. 将GPIO引脚配置为外部中断

要将GPIO引脚配置为外部中断,需要将其交给外部中断模块(EXTI)。

4. EXTI模块的作用

EXTI模块专门负责处理外部中断信号,如上升沿或下降沿。

5. 配置GPIO引脚为复用模式

通过配置AF(Alternate Function)设置,将GPIO引脚配置为复用模式,并将其定义为外部中断功能。

6. 信号传输路径

  • GPIO引脚接收到外部信号(上升沿/下降沿)。
  • 信号被传递给EXTI模块。
  • EXTI模块处理信号并触发相应的中断服务。

结语

通过今天的学习,我们了解了STM32中外部中断的传输路径,包括GPIO引脚的角色、EXTI模块的作用以及如何配置GPIO引脚以处理外部中断。

25. 什么是AFIO

引言

大家好,今天我们将探讨STM32中的AFIO(Alternate Function I/O)模块,了解它在外部中断传输路径中的作用。

AFIO模块概述

1. AFIO的定义

AFIO是STM32中的一个模块,负责引脚功能的复用。它决定了GPIO引脚是用作通用输入输出还是复用为其他片上外设的功能。

2. STM32的设计风格

STM32的每个引脚都有多种功能,既可以作为GPIO,也可以复用为其他外设的功能,如USART、I2C等。

AFIO的作用

1. 引脚复用配置

AFIO通过配置决定GPIO引脚的具体功能,是用作普通的IO,还是作为某个外设的特定功能引脚。

2. 引脚控制权的分配

当GPIO引脚被配置为复用功能时,AFIO负责将控制权从CPU转移到相应的外设。

3. 外部中断与AFIO

对于外部中断,AFIO将GPIO引脚的控制权分配给EXTI模块,使得外部信号能够触发中断。

AFIO与外部中断的关系

1. 外部中断信号的传输

外部中断信号(如按键的上升沿或下降沿)需要通过AFIO模块来传输到EXTI模块,从而触发中断。

2. AFIO作为开关

AFIO类似于一个开关,根据配置将GPIO引脚连接到不同的外设,如串口或I2C。

3. 配置AFIO

通过软件配置AFIO,可以将GPIO引脚分配给不同的外设功能,或者将其设置为外部中断输入。

结语

通过今天的学习,我们了解了AFIO在STM32中的作用,特别是它如何管理GPIO引脚的复用以及与外部中断的关系。

26. 不同组的同一个编号的IO引脚只能同时有一个当作外部中断的输入引脚

引言

大家好,今天我们来深入探讨STM32中外部中断的一个特殊规则:不同组的同一个编号的IO引脚只能同时有一个被配置为外部中断的输入引脚。

外部中断的传输路径

1. 信号传输概述

在STM32中,外部中断信号需要通过一系列处理才能到达CPU。这个过程涉及到多个硬件模块,包括AFIO和EXTI。

2. AFIO的作用

AFIO(Alternate Function I/O)模块在外部中断信号的传输中起到了关键作用。它类似于一个开关,决定将GPIO引脚的控制权分配给哪个外设。

3. EXTI的角色

EXTI(External Interrupt)模块是STM32中处理外部中断信号的硬件模块。它接收来自AFIO的信号,并在检测到上升沿或下降沿时触发中断。

外部中断的特殊规则

1. 同一个编号的IO引脚限制

不同组的同一个编号的IO引脚(例如PA0和PF0)只能有一个被配置为外部中断的输入引脚。这意味着,如果PA0已经被配置为外部中断,那么PF0就不能再被配置为外部中断。

2. 信号选择器的作用

STM32中的信号选择器(复用器)确保在多个输入中只能选择一个信号传递给EXTI。这解释了为什么虽然有112个引脚可以作为外部中断输入,但实际上只有16个外部中断信号。

3. 实际应用中的影响

在实际应用中,这意味着你不能将两个不同组的同名引脚都用于外部中断。例如,如果你将PA0用作外部中断,那么PF0就不能用作外部中断。

4. 配置示例

如果你希望两个按键分别连接到PA0和PF0,并触发外部中断,你会发现只有PA0能够触发中断,而PF0不能,因为它的信号在到达EXTI之前就被信号选择器阻断了。

结语

通过今天的学习,我们了解了STM32中外部中断的一个关键规则,以及AFIO和EXTI在外部中断信号传输中的作用。这个规则对于设计STM32的外部中断系统至关重要。

27. EXTI模块:0,1,2,3,4有独立的中断服务函数,5-9,10-15是共享函数的

引言

大家好,今天我们来详细了解STM32中的EXTI(External Interrupt)模块,特别是关于它的中断服务函数如何分配给不同的中断线。

EXTI模块概述

1. EXTI中断线的数量

之前提到STM32有16个外部中断线,但实际上还有更多的中断线,总共有20个。

2. 非互联型产品

对于非互联型产品,STM32型号实际上有19个可用的外部中断线,因为缺少以太网唤醒中断。

EXTI中断服务函数的分配

1. 独立的中断服务函数

  • EXTI0到EXTI4有独立的中断服务函数。
  • 这意味着每个中断线都可以单独响应中断事件。

2. 共享的中断服务函数

  • EXTI5到EXTI9共享一个中断服务函数。
  • EXTI10到EXTI15也共享一个中断服务函数。
  • 这意味着这些中断线将共用同一个中断服务函数,需要在软件中区分具体的中断源。

3. 中断服务函数的命名

在STM32中,中断服务函数的名称是固定的,不需要在函数声明中指定中断号或使用特定的关键字。

4. 函数名的重要性

  • STM32要求中断服务函数的名称必须与特定的模式匹配,否则中断将不会被正确识别和处理。

5. 中断向量表

  • 在STM32的中断向量表中,每个独立的中断线都有一个对应的条目,而共享函数的中断线则共用一个条目。

结语

通过今天的学习,我们了解了STM32的EXTI模块中不同中断线如何分配中断服务函数,以及为什么有些中断线需要共享同一个服务函数。

28. EXTI中断到NVIC的过程是怎么处理的

引言

大家好,今天我们将深入了解STM32中外部中断(EXTI)信号是如何传递到嵌套向量中断控制器(NVIC)的。

EXTI到NVIC的传递过程

1. EXTI中断线的数量

我们之前提到STM32有16个外部中断线,但实际上有19个,因为还包括一些特殊中断线。

2. EXTI到NVIC的线路数量

EXTI给NVIC的线路并不是19条,而是7条。这是因为多个EXTI中断线共享同一个中断服务函数。

3. NVIC的作用

NVIC负责处理所有中断信号的优先级排队。每个中断信号都会被分配一个优先级,这个优先级决定了中断处理的顺序。

4. 优先级的表示

NVIC使用4个比特来表示每个中断的优先级,这意味着可以有16种不同的优先级级别。

5. 优先级的数量与中断数量

尽管有16种优先级,但中断的数量可能超过16个,因此有些中断会共享相同的优先级,需要排队处理。

6. 嵌套优先级与排队优先级

NVIC可以配置为将4个比特分配给嵌套优先级和排队优先级。一般情况下,我们将其全部配置为嵌套优先级。

7. 中断服务函数的固定命名

在STM32中,中断服务函数的名称是固定的,不需要在函数声明中指定中断号或使用特定的关键字。

8. 中断向量表

STM32的中断向量表中,每个独立的中断线都有一个对应的条目,而共享函数的中断线则共用一个条目。

结语

通过今天的学习,我们了解了STM32中外部中断信号是如何传递到NVIC的,以及NVIC如何处理这些中断信号的优先级。

29. EXTI框图工作原理

引言

大家好,今天我们将深入了解STM32的外部中断(EXTI)模块的工作原理,包括它的内部电路是如何工作的以及相关的配置。

EXTI模块工作原理

1. EXTI信号的传递

我们已经知道EXTI信号是如何从GPIO传递到EXTI,再传递到NVIC的。现在,我们将深入了解EXTI内部的工作原理。

2. 边沿检测电路

EXTI模块包含一个边沿检测电路,用于检测外部信号的上升沿或下降沿。

  • 上升沿触发选择寄存器:配置为1时,表示检测到上升沿时触发中断。
  • 下降沿触发选择寄存器:配置为1时,表示检测到下降沿时触发中断。

3. 信号传递路径

  • 外部GPIO引脚的信号首先经过AFIO配置。
  • 信号到达EXTI后,经过边沿检测电路。
  • 检测到边沿后,产生一个短暂的高电平脉冲。
  • 脉冲信号经过或门,最终触发中断服务函数。

4. 中断与事件信号

  • 中断信号:用于中断CPU执行,传递给NVIC。
  • 事件信号:不经过CPU,直接传递给其他片上外设。

5. 软件触发中断

  • 通过设置特定的寄存器值,软件也可以触发中断服务函数。

6. 中断屏蔽寄存器

  • 中断屏蔽寄存器用于控制是否允许中断信号传递给NVIC。

7. EXTI与NVIC的交互

  • 当EXTI检测到边沿并产生脉冲后,脉冲信号会传递给NVIC。
  • NVIC根据优先级和其他因素决定是否中断当前执行的代码。

结语

通过今天的学习,我们了解了STM32的EXTI模块的工作原理,包括边沿检测、信号传递路径、中断与事件信号的区别,以及如何通过软件触发中断。

30. 最终串讲

引言

大家好,今天我们不讲新内容,而是用大约十分钟的时间来串讲一遍,让整个知识体系更加连贯。

中断处理流程

1. 中断需求引子

我们通过一个需求来引入中断的概念:通过按键触发CPU的中断服务函数。

2. STM32中断信号源

STM32有很多中断信号源,分为内核内部(CPU内部)和外部(片上外设)。

  • 内核内部中断:包括系统滴答定时器(SysTick)等,有些中断优先级可以配置,有些则固定且最高。
  • 外部中断:包括GPIO、USART、I2C等外设触发的中断。

3. 外部中断(EXTI)

外部中断是指从STM32芯片外部触发的中断,如按键的上升沿或下降沿。

4. EXTI信号路径

  • GPIO引脚信号经过AFIO配置。
  • 信号到达EXTI后,经过边沿检测电路。
  • 检测到边沿后,产生脉冲信号。
  • 脉冲信号经过或门,触发中断服务函数。

5. 中断与事件信号

  • 中断信号:用于中断CPU执行,传递给NVIC。
  • 事件信号:不经过CPU,直接传递给其他片上外设。

6. 软件触发中断

软件可以通过设置寄存器值来触发中断服务函数。

7. 中断屏蔽寄存器

用于控制是否允许中断信号传递给NVIC。

8. EXTI内部框图

EXTI内部框图展示了信号如何在EXTI内部处理,包括边沿检测、事件触发器和中断信号通道。

9. NVIC与中断优先级

NVIC负责处理所有中断信号的优先级排队,每个中断使用四个比特表示优先级。

结语

通过今天的串讲,我们了解了STM32的中断处理流程,从GPIO信号经过EXTI到NVIC的整个过程。

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

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

相关文章

[371]基于springboot的高校实习管理系统

摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统高校实习管理系统信息管理难度大,容错率低&am…

基于无线传感器网络的无线温湿度采集系统(附详细使用教程+完整代码+原理图+完整课设报告)

🎊项目专栏:【Zigbee课程设计系列文章】(附详细使用教程完整代码原理图完整课设报告) 前言 👑由于无线传感器网络(也即是Zigbee)作为🌐物联网工程的一门必修专业课,具有…

启动前后端分离项目笔记

一、项目 首先可以在各大开源软件拿取一个项目,以下项目是在gitee上获取 二、准备工作 配置JDK环境,node.js环境,安装vue脚手架工具以及maven环境 三、前端项目启动 在前端目录下安装依赖 npm install 如果报错可能是因为权限不够&#…

代理池搭建优化-(书接上回,优化改进)

炮台有效炮弹实现 声明 学习视频来自 B 站UP主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 ✍🏻作者…

odoo18中模型的常用字段类型

字段的公共属性: Char 字符类型,对应数据库中varchar类型,除了通用类型外接收另外两个参数: size: 字符长度,超出的长度将被截断 trim: 默认True,是否字段值应该被去空白。 Text 文本类型,对应数据库…

ABAP开发实战——表单打印单位输出问题

在之前的文章中有提到过ABAP开发报表程序时会出现单位显示未转化值,就是说在中文环境下,用户希望看到的单位是“套”,但是报表程序输出的确是“SUI”,这时候需要取数时添加语句进行转化,但是,最近开发表单打…

基于SpringBoot的城镇保障性住房管理系统【附源码】

基于SpringBoot的城镇保障性住房管理系统 效果如下: 系统登录页面 用户管理页面 房源信息管理页面 住房分配管理页面 公示信息页面 系统主页面 用户登陆页面 房源信息页面 研究背景 随着城市化进程的加速,住房问题一直是人们关注的焦点。为了解决低收…

Java文件上传解压

目录结构 工具类 枚举 定义文件类型 public enum FileType {// 未知UNKNOWN,// 压缩文件ZIP, RAR, _7Z, TAR, GZ, TAR_GZ, BZ2, TAR_BZ2,// 位图文件BMP, PNG, JPG, JPEG,// 矢量图文件SVG,// 影音文件AVI, MP4, MP3, AAR, OGG, WAV, WAVE}为了避免文件被修改后缀&#xff0…

IDEA 下载源码很慢,Download Source使用阿里云镜像仓库

参考: IDEA maven本地仓库、中心仓库、远程仓库配置 在观看第三方jar包的api时,有时候需要下载源码看下注释。 这个时候用idea 上的提示的Download Source会发现一直下载不下来。 因此就怀疑用的是apache的maven仓库,不是我们用的 aliyun 镜…

英文版本-带EXCEL函数的数据分析

一、问题: 二、表格内容 三、分析结果 四、具体的操作步骤: 销售工作表公式设计与数据验证 类别(Category)列公式: 在Category列(假设为D列),根据ProductCode在Catalogue工作表中查找…

三层交换机静态路由实验

1、前置知识 2、实验目的 3、实验器材: 3560-23PS交换机2台、主机4台、交叉线1根和直通网线4根。 4、实验规划及拓扑 实验要求: (1)在交换机A和交换机B上分别划分基于端口的VLAN: 交换机 VLAN 端口成员 交换机…

PLC与PLC跨网段通讯的几种方法:厂区组网实践

PLC通常通过以太网或其他工业网络协议(如PROFINET、Modbus TCP等)进行通信。当PLC位于不同的网段时,它们不能直接通信,需要特殊的配置或设备来实现通信,不同网段的PLC通讯变得尤为重要。 随着工业网络的发展和工业4.0概…

观察者模式和订阅模式

观察者模式和订阅模式在概念上是相似的,它们都涉及到一个对象(通常称为“主题”或“发布者”)和多个依赖对象(称为“观察者”或“订阅者”)之间的关系。然而,尽管它们有相似之处,但在某些方面也…

HarmonyOs鸿蒙开发实战(20)=>一文学会基础使用组件导航Navigation

敲黑板,以下是重点技巧。文章末尾有实战项目效果截图及代码截图可参考 1.概要 Navigation是路由导航的根视图容器Navigation组件主要包含​导航页(NavBar)和子页(NavDestination),导航页不存在页面栈中&am…

DevOps-Jenkins-新手入门级

1. Jenkins概述 1. Jenkins是一个开源持续集成的工具,是由JAVA开发而成 2. Jenkins是一个调度平台,本身不处理任何事情,调用插件来完成所有的工作 1.1 什么是代码部署 代码发布/部署>开发书写的程序代码---->部署测试/生产环境 web服务…

在win10下搭建ftp服务器

1 说明 本文档在win10下实现。 2 安装ftp服务器 打开“控制面板/程序和功能”,如下: 点击“启用或关闭windows功能”,如下: 安装“ftp服务器”,将下图红色圈中部分打勾,如下: 必须勾选…

数据结构C语言描述4(图文结合)--栈的实现,中序转后序表达式的实现

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法;有C基础即可跟着学习,代码均可运行;准备考研的也可跟着写,个人感觉,如果时间充裕,手写一遍比看书、刷题管用很多,这也是本人采用纯C语言…

vue中路由缓存

vue中路由缓存 问题描述及截图解决思路关键代码及打印信息截图 问题描述及截图 在使用某一平台时发现当列表页码切换后点击某一卡片进入详情页后,再返回列表页时页面刷新了。这样用户每次看完详情回到列表页都得再重新输入自己的查询条件,或者切换分页到…

如何在 UniApp 中实现 iOS 版本更新检测

随着移动应用的不断发展,保持应用程序的更新是必不可少的,这样用户才能获得更好的体验。本文将帮助你在 UniApp 中实现 iOS 版的版本更新检测和提示,适合刚入行的小白。我们将分步骤进行说明,每一步所需的代码及其解释都会一一列出…

移动充储机器人“小奥”的多场景应用(上)

一、高速公路服务区应用 在高速公路服务区,新能源汽车的充电需求得到“小奥”机器人的及时响应。该机器人配备有储能电池和自动驾驶技术,能够迅速定位至指定充电点,为待充电的新能源汽车提供服务。得益于“小奥”的机动性,其服务…