首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

不能在stm32 F407VG的ISR中使用HAL_Delay()吗

基础概念: STM32F407VG是一款基于ARM Cortex-M4内核的微控制器。ISR(中断服务例程)是在特定中断发生时由处理器执行的特殊函数。HAL_Delay()是STM32 HAL库中的一个函数,用于产生延时。

为什么不能在ISR中使用HAL_Delay(): HAL_Delay()函数依赖于SysTick定时器来实现延时功能。在ISR中调用HAL_Delay()会导致SysTick定时器被阻塞,进而影响系统的实时性和其他中断的处理。

原因分析

  1. SysTick定时器的特性:SysTick定时器是系统滴答定时器,用于提供时间基准和延时功能。当调用HAL_Delay()时,SysTick定时器会持续计数直到达到指定的延时时间。
  2. 中断优先级和嵌套:在ISR中使用HAL_Delay()会阻塞SysTick定时器的中断,这可能导致更高优先级的中断无法及时响应,从而影响系统的实时性能。
  3. 资源占用:ISR应该尽可能短小且高效,以快速响应中断事件并释放CPU资源。使用HAL_Delay()会导致ISR长时间占用CPU,违背了ISR的设计原则。

解决方案: 在ISR中应避免使用HAL_Delay(),可以采用以下替代方案:

方案一:使用硬件定时器

配置一个硬件定时器,在定时器中断中处理延时相关的任务。

代码语言:txt
复制
// 配置定时器中断
TIM_HandleTypeDef htim;
void MX_TIMx_Init(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    htim.Instance = TIMx;
    htim.Init.Prescaler = SystemCoreClock / 10000 - 1; // 10kHz
    htim.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim.Init.Period = 1000 - 1; // 1ms
    htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&htim) != HAL_OK)
    {
        // 初始化错误处理
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim, &sClockSourceConfig) != HAL_OK)
    {
        // 配置时钟源错误处理
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig) != HAL_OK)
    {
        // 主从同步配置错误处理
    }
    HAL_TIM_Base_Start_IT(&htim);
}

// 定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIMx)
    {
        // 处理延时相关的任务
    }
}

方案二:使用标志位和主循环

在中断中设置一个标志位,在主循环中检查该标志位并执行延时操作。

代码语言:txt
复制
volatile uint8_t delayFlag = 0;

// 中断服务例程
void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_0)
    {
        delayFlag = 1;
    }
}

// 主循环
int main(void)
{
    while (1)
    {
        if (delayFlag == 1)
        {
            HAL_Delay(1000); // 延时1秒
            delayFlag = 0;
        }
        // 其他任务处理
    }
}

方案三:使用RTOS任务调度

如果系统中使用了实时操作系统(RTOS),可以将延时相关的任务放在一个独立的任务中,并使用RTOS提供的延时函数。

代码语言:txt
复制
// 任务函数
void Task_Delay(void *argument)
{
    while (1)
    {
        // 延时任务处理
        osDelay(1000); // 延时1秒
    }
}

// 创建任务
osThreadDef(Task_Delay, osPriorityNormal, 1, 0);
osThreadCreate(osThread(Task_Delay), NULL);

应用场景

  • 硬件定时器:适用于需要精确延时和实时性较高的场景。
  • 标志位和主循环:适用于简单的延时需求,系统复杂度较低的情况。
  • RTOS任务调度:适用于复杂的系统架构,需要多任务并发执行的场景。

通过以上方案,可以在ISR中避免使用HAL_Delay(),确保系统的实时性和稳定性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

stm32开发教程_单片机STM32

上一段话包含两层意思:1、在不熟悉STM32的情况下,如何入手学习相关的技术知识。2、在不熟悉STM32的情况下,作为公司在职开发人员,如何快速进入STM32相关的项目开发工作中,保证开发效率。...STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。...另外,STM32还可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。   系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。...在以上的时钟输出中,有很多是带使能控制的,例如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等等。当需要使用某模块时,记得一定要先使能对应的时钟。   ...本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

81820

基于STM32CUBE的USB鼠标键盘二合一

感兴趣的就看一眼,没兴趣的就算了。 前面两篇文章分别说了如何实现基于STM32的USB鼠标和基于STM32的USB键盘。这篇文章,我们试着同时在一个USB设备上,实现USB的鼠标与键盘二合一。...花一份的钱,实现两样东西,它不香吗? 这里要说一下,实现鼠标键盘二合一的功能,方法有多种,这里只说其中一种。 少废话,开始干!...第二,修改usbd_hid.c中的配置集合(USBD_HID_CfgFSDesc)。如下图所示,框住的地方是个宏定义。配置集合的长度,由之前的34,变为41. ? 端点个数,由1变成2....STM32CubeMX工具自动生成的工程里,报告描述符是鼠标的。现在我们要实现的是键盘与鼠标二合一,要修改的核心位置就是报告描述符这里。 简单来说,就是把前面两个例程中的报告描述符合二为一。...在USB协议中,报告ID默认是数组的第一个元素。明白了这一点,我们可以去修改main.c文件了。 第五,添加头文件,并定义相关的数组。

2.6K41
  • 如何解决STM32待机模式无法下载程序问题

    为了解决这个问题,你可以通过以下几种方式来避免进入待机模式或使MCU能够响应调试器: 1.1 使用复位键 在STM32的许多型号中,当MCU处于待机模式时,可以通过按住复位键来强制将其复位,从而跳出待机模式...2 设置MCU的启动选项 有些STM32型号支持在启动时选择不同的启动模式。 可以在启动模式中设置“低功耗启动”以避免快速进入待机模式。...2.1 启动后不立刻进入待机模式 在MCU复位后,通常有一定的时间窗口允许你进行调试和下载。 你可以确保代码中没有过快进入待机模式,或者在系统启动后延迟一段时间再进入低功耗模式。...3.2 使用ST-Link或J-Link替代 如果DAPmini无法正常连接,可以尝试使用ST-Link或J-Link调试器,这些调试器对于STM32的支持更加广泛,并且支持更多的连接方式。...5 软件层面避免进入待机模式 在某些情况下,可能在程序代码中不小心让MCU进入了待机模式,导致后续调试无法进行。 你可以在代码中添加防止进入待机模式的逻辑。

    14210

    STM32MP157D-DK1 STM32CubeID使用与M核开发

    STM32MP157具有A7内核核M4内核,前面介绍的一些文章,都是在A7内核上进行的,本篇来介绍M4内核的开发,以及开发时要用到的STM32 CubeIDE软件的使用。...exe安装,这里不展开介绍。...,关联成功,就会变成绿色的方块: 可以在下载位置查看下载的文件: 1.2 配置引脚 使用LED中的LD7进行LED控制,根据文档,对应的是PH7引脚,高电平点亮: 搜索PH7引脚,设置为Output模式...,LD7_Pin,GPIO_PIN_SET); HAL_Delay(500); HAL_GPIO_WritePin(LD7_GPIO_Port,LD7_Pin,GPIO_PIN_RESET); HAL_Delay...lib/firmware目录中,添加可执行权限,然后使用如下指令即可运行M4内核的程序: #加载固件 echo 01_LED_CM4.elf >/sys/class/remoteproc/remoteproc0

    26510

    STM32CubeMX实战教程(三)——外部中断(中断及HAL_Delay函数避坑)

    Priority Group是优先级分组 STM32以4个比特位表示中断的抢占优先级和响应优先级。...,用过STM32中断的应该都知道,单片机再执行中断服务函数之前,Contex-M4内核先将现在使用到的寄存器和主程序中断点的地址压入堆栈(保护现场)。...,我们在使用STM32CubeMX开发的过程中,使用的任何中断都不需要去关心标志位的问题。...百度一下HAL_Delay函数卡死,相关帖子层出不穷,真正说出原因并提供解决方法的几乎没有。但其实原因并不难,进来HAL_Delay函数看看就知道。...带着这个问题我们回到STM32CubeMX中重新找到NVIC。 这时候我们注意到在默认使能的中断里面有一个System tick的中断,这就是给HAL_Delay函数提供时基的定时器中断了。

    4.7K21

    1.使用GPIO点亮LED

    开发环境 NUCLEO-G071RB开发板一块 stm32cubemx,keil开发环境 用stm32cubemx生成MDK工程 新建工程并选择芯片 配置时钟 这次工程使用哦内部时钟源即可,...所以使用默认时钟配置即可 关于时钟配置可以看这篇:stm32时钟配置 配置引脚 硬件电路如下 这里使用PC8作为led的引脚,设置为输出脚 生成工程 配置好工程路径,开发环境后,就可以生成代码了...在MDK中编写代码 在main.c中找到主程序的while循环 添加代码 HAL_Delay(200); HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8); 下载程序 工程配置中...按钮就可以了 代码分析 GPIO输出函数 HAL_GPIO_TogglePin(GPIOx, GPIO_Pin); GPIOx: GPIO端口,GPIOA~GPIOH GPIO_Pin: 该端口对应的Pin...脚数 实现GPIO口的状态翻转 HAL_Delay(); 延时函数,堵塞式延时,单位毫秒ms,输入值长度uint32_t。

    1.2K20

    用GCC开发STM32入门二

    之前从网上下载了一份用GCC开发stm32的程序,也是用的stm32的库函数编程,启动文件是startup_stm32f10x_hd.s,链接脚本文件是从gcc_ride7中拷贝出的stm32f10x_flash_extsram.ld...这条语句使用了__attribute__ ((section(".stackarea"))) 把数组定位在 了.stackarea这个段中。...,把所有目标文件相应的段连接到一起,并把目标文件中的“变量地址”“函数地址”重定位至正确的地址空间; 比如,对于stm32来说向量表,.text和.rodata就应该放到从0x0800 0000开始的..._etext = .; } > FLASH 按.isr_vector, .text, .rodata的顺序排列正文段的内容;回忆前述VectorTable[]数组就被定为与.isr_vector段中...但向量表不是应该从0x0000 0000开始吗?原来stm32可以通过boot0、boot1引脚的配置将 flash映射到0x0000 0000处。具体可参考stm32的数据手册。

    1.9K20

    一种Cortex-M内核中的精确延时方法(ns级别)

    本文介绍一种Cortex-M内核中的精确延时方法 ? 前言 为什么要学习这种延时的方法?...很多裸机教程使用延时函数又是基于SysTick的,这样一来又难免产生冲突。 很多人会说,不是还有定时器吗,定时器的计时是超级精确的。...这点我不否认,但是假设,如果一个系统,总是进入定时器中断(10us一次/1us一次/0.5us一次),那整个系统就会经常被打断,线程的进行就没办法很好运行啊。...,不过好在,HAL_Delay()是一个弱定义的,我们可以重写这个函数的实现,那么,采用内核延时当然是最好的办法啦(个人是这么觉得的)当然你有能力完全用for循环写个简单的延时还是可以的。...(218000000) 后记 其实在ucos-iii 源码中,有一个功能是测量关中断时间的功能,就是使用STM32的时间戳,即记录程序运行的某个时刻,如果记录下程序前后的两个时刻点

    1.9K10

    STM32CubeMX-27(补充) | 系统滴答定时器Systick的使用

    本篇文章主要介绍STM32中Systick定时器的使用以及HAL_Delay函数的原理。 1....配置时钟源 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC; 如果使用默认内部时钟(HSI),这一步可以略过; 这里我都使用外部时钟: ?...HAL_IncTick函数会把当前系统中定义的计数值变量递加,在stm32l4xx_hal.c文件中,实现如下: ?...编写用户代码 HAL库中还定义了一个函数 HAL_GetTick(),使用此API可以获取到当前系统中的计数值,定义如下: ? 接下来使用此API来编写LED闪烁程序。...补充 —— HAL_Delay的实现原理 最开始使用HAL库的时候,觉得 HAL_Delay 简直太方便了,其实 HAL_Delay 也是依靠系统的时基信号来实现的,在stm32l4xx_hal.c文件中

    5.6K20

    BME280传感器与STM32 Blue Pill连接并使用STM32CubeIDE

    在本教程中,我们将学习如何将 BME280 传感器与 STM32 Blue Pill 连接,并使用 HAL 库在 STM32CubeIDE 中对其进行编程。...首先,我们将简要介绍 BME280 传感器,然后将其与我们的 STM32 接口,并使用 STMCube IDE 对其进行编程以测量温度、压力和湿度。...我们使用与上表中指定的连接相同的连接。 图片 STM32 Blue Pill BME280 代码带OLED 我们将使用 STM32Cube IDE 对我们的 STM32 板进行编程。...首先,我们必须将我们的 Blue Pill STM32 与 ST-Link 编程器连接起来。我们将使用 ST-Link V2。 图片 这将在我们的计算机和我们的 STM32 板之间提供一个接口。...接下来按 IDE 中的 RUN 按钮。“编辑配置”窗口将打开。单击“确定”。 片刻后,代码将成功发送到STM32板。否则,请按 STM32 开发板上的 RESET 按钮。

    1.5K60

    stm32编程入门书籍_STM32开发板

    Cortex-A系列主要面向一些复杂的应用,用来运行一些操作系统,运用到各类消费电子中;Cortex-R系列主要面向实时系统,运用到军事航天;Cortex-M系列主要面向微控制领域,为如今工业控制系统、...STM32的4个库 先给结论:从ST公司的发展方向和主推的库来讲,目前使用HAL是最正确的选择。...每个STM32系列的100多个片段演示了如何以最小的内存占用有效地使用STM32外围设备。STM32Snippets目前官方只提供:STM32F0和L0的示例代码包。...HAL_Delay(1000); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ 4.3 烧写代码流程 4.4 运行结果...本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

    1.5K20

    stm32cubemx使用教程pdf_库乐队完全新手教程

    前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6/ STM32F103ZET6...STM32的每个通用定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。...STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。...0:关闭使能 1:打开使能 5、输出电平信号 TIM定时器的四路通道TIMx_CHx输出PWM 摘自: 《STM32中文参考手册》254页 通用定时器框图 STM32定时器输出通道引脚 具体不同定时器对应引脚在对应芯片数据手册的引脚说明...(1); } HAL_Delay(200); /* USER CODE END 3 */ } 或者直接修改CCRx寄存器的值 htim3.Instance->CCR1 = 300;

    72310

    基于STM32L431设计的云端绿化管理系统(ESP8266+腾讯物联网云平台)

    小熊派开发板本身自带的例子程序也比较丰富,自带例子里采用的云平台是华为的物联网云平台,工程比较庞大使用了LiteOS操作系统。...本文里的工程是重新编写的代码,使用裸机完成项目功能,没有跑操作系统,MQTT协议和ESP8266驱动代码都是重新编写,框架、逻辑比较清晰,代码量也较少,适合初学者入门学习。...用到的功能属性: 小程序面板配置: 手机微信小程序运行效果: 串口打印的提示: 四、STM32源代码 STM32的代码主要分为以下几个部分: 1....这个MQTT协议不是使用ESP8266本身的SDK,是根据MQTT协议自己实现的,所以如果使用其他的网卡,移植也很方便,不挑网卡设备。 3....程序的模板是使用CubeMX生成的。

    95620

    用GCC开发STM32入门一(使用官方库)

    先说说为什么需要用GCC开发stm32吧,作为一名编程方面的爱好者,又是搞嵌入式的,总是用现成的IDE,感觉很不舒服,虽然IDE能很大提高咱们的工作效率,可是作为业余学习研究,还是越熟悉底层越好...比如如何搭建环境,如何使用编译器和编写makefile,这些搞过linux开发的都知道,而且 linux环境下没那么多IDE可用,而且也没必要用IDE.还有一个原因是,喜欢黑色的dos窗口下编程的感觉,...cygwin+skyeye+gcc 2.安装cygwin软件,安装步骤按照书上的进行,需要说明的是 :在进入cygwin setup-select packages界面时,必须选中devel包中的gcc4...首先将leeos_tools_for_cygwin.tar.gz复制到D:\cygwin\usr中(我把cygwin装在了D盘,具体看自己情况),然后解压缩为leeos_tools_for_cygwin...以下是我整理了一份自己使用的模板:makefile (LDSCRIPT) OBJS= main.o .PHONY: clean all:images images: (BINARY).hex (BINARY

    2.8K10

    【STM32F429】第6章 ThreadX操作系统移植(IAR)

    mod=viewthread&tid=99514 第6章 ThreadX操作系统移植(IAR) 本章节将为大家介绍ThreadX内核的IAR方式移植和设计框架,理论上不建议初学者直接学习,因为本章节涉及到的知识点很多...但是本章的工程模板框架一定要学习。 虽然本章节是以我们开发板为例进行移植的,但是教会大家如何移植到自己的板子上以及移植过程中的注意事项是本章节的重点。...需要周期性处理的程序bsp_ProPer1ms,对应裸机工程调用的SysTick_ISR。这个的实现非常重要,这样之前裸机里面使用的API,就可以直接在ThreadX里面直接调用。...stm32f4xx_hal_timebase_tim.c ThreadX系统时钟节拍默认是用的滴答定时器,STM32的HAL库时间基准也是用的滴答定时器。...替换HAL中的函数。因为HAL中的缺省函数依赖于Systick中断,如果在USB、SD * 卡中断中有延迟函数,则会锁死。

    72620

    14个最常见的Kafka面试题及答案

    Kafka服务器可以接收到的消息的最大大小是1000000字节。 6、解释Kafka的Zookeeper是什么?我们可以在没有Zookeeper的情况下使用Kafka吗?   ...Zookeeper是一个开放源码的、高性能的协调服务,它用于Kafka的分布式应用。   不,不可能越过Zookeeper,直接联系Kafka broker。...broker什么时候离开ISR?   ISR是一组与leaders完全同步的消息副本,也就是说ISR中包含了所有提交的消息。ISR应该总是包含所有的副本,直到出现真正的故障。...Kafka的信息复制确保了任何已发布的消息不会丢失,并且可以在机器错误、程序错误或更常见些的软件升级中使用。 12、如果副本在ISR中停留了很长时间表明什么?   ...如果首选的副本不在ISR中,控制器将无法将leadership转移到首选的副本。 14、有可能在生产后发生消息偏移吗?

    8.8K10

    STM32高级开发——链接器与启动文件

    至于其中各个.c文件产生的功能在单片机储存中的排列顺序和地址位置,在最后我们链接器工作产生的.map文件中是有显示的,如下面从样例工程中.map文件中复制的片段: .isr_vector 0x08000000...当然不排除我见识少,没见过特殊的。...在我们实际的工程建立及编写中,我们使用的都是从别处找来的ld文件,在样例工程中的.ld文件只要在内存大小堆栈等位置上根据stm32具体的型号稍作修改就可以使用了。...启动文件 很多刚接触stm32不久的童鞋对stm32的启动文件的印象大多就是教程里的一句话:启动文件就是stm32在执行main函数前将系统初始化并把PC(即程序计数器,也就是当前执行代码位置的指针)...确实在KEIL或IAR之类的集成开发环境中我们不必关心启动文件的存在,但是在我们的gcc的使用中,我们就需要去理解这个文件了。

    95730
    领券