解决STM32在延时时无法进入中断的问题

这篇具有很好参考价值的文章主要介绍了解决STM32在延时时无法进入中断的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题:

在使用zigbee模块时,使用串口作为无线收发的载体,与stm32通信,使用DHT11作为简单的受控源,出现了bug:

当在while(1)里使用delay函数,或者使用DHT11_Read_Data函数时,程序无法进入串口接收中断,无法使用远程控制

其中的while函数为:

while (1){
        DHT11_Read_Data(&temp,&humi);//DHT11读取温度
        bufFun();
        if(dht11Res){
​
            USART2_SendByte('1');
            OLED_ShowNum(1,8,temp,2);
            temp++;
            
        }else{
            USART2_SendByte('2');
        }
        delay_ms(1000);
    }

解决思路:

一、常规检查

检查接线之后,我首先想到的是可能数据量过大无法进入中断,或者是某一步出错,使用STlink debug后,发现程序一直在主函数里,没有进入串口接收中断

二、延时函数

随后我仔细排查函数体,发现DHT11_Read_Data 或者其他函数体内,都存在延时函数,在之前的学习开发中,也遇到过因为滴答定时器优先级问题而出现的奇怪bug,尝试使用简单的软件延时代替:

//粗延时函数,微秒
void delay_us(u16 time)
{    
   u16 i=0;  
   while(time--)
   {
      i=10;  //自己定义
      while(i--) ;    
   }
}
//毫秒级的延时
void delay_ms(u16 time)
{    
   u16 i=0;  
   while(time--)
   {
      i=12000;  //自己定义
      while(i--) ;    
   }
}

无果后尝试另一种无需中断的硬件延时:

#include "delay.h"
​
void delay_us(u32 nus)
{
 u32 temp;
 SysTick->LOAD = 9*nus;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
     SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}
void delay_ms(u16 nms)
{
 u32 temp;
 SysTick->LOAD = 9000*nms;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 
    SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
​
}

三、串口处理函数

经过以上调试后,我开始注意到串口处理函数:bufFun

原本的想法是把它放在主函数里,读取数据帧,然后用来判断命令

void bufFun(void){//数据帧接收
    
        if(res){
            
            switch(USARTReceIn){
            case 0:
                if(udata=='@'){//头
                    databuf[USARTReceIn++] = udata;
                }
                else{
                    USARTReceIn = 0;
                }
                break;
        
            default:
                databuf[USARTReceIn++] = udata;
                break;
            }
            res=0;
        }
        
    if(USARTReceIn >= maxSizebuf)//数据帧接收完成
    {
        USARTReceFullFlag = 1;   
    }
    dataProcess();
        
    
}
void dataProcess(void){//数据帧处理
    
    if(USARTReceFullFlag)
    {
        //处理
        //USART_Send_Str(databuf,maxSizebuf); 
        func();
        //清空
            USARTReceFullFlag = 0;
            USARTReceIn = 0;
            memset(databuf,0x00,sizeof(udata));
    }
    
}

但是此处逻辑出现问题:

读取数据帧的前提是,串口接收中断成功接收一组数据帧,同时,while(1)里运行到bufFun,才可以识别一帧数据

但是当有延时,或者while中出现大量代码时,可能会出现,数据已经接收好,但是程序还没有运行到读取位,出现bug

尝试修改为在USART2_IRQHandler中运行bufFun:

问题解决文章来源地址https://www.toymoban.com/news/detail-658542.html

到了这里,关于解决STM32在延时时无法进入中断的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 hal库编程定时器清除中断标志位,开启定时器中断会立即进入中断的问题

    1、如果不清除中断标志位,开启定时器中断的话,不能完成相应的计时,会立即进入中断。 2、如果在开启定时器中断前清除了中断标志位,就会等待计时完成再出发中断。 3、主要是针对单次计时使用,尤其是对第一次计时有要求的程序。

    2024年02月01日
    浏览(58)
  • 关于STM32用DMA传输UART空闲中断中接收的数据时无法接收数据问题以及解决办法

             串口1相关的设置及printf函数的使用,这里没放,建议先实现串口打印功能 可以参考:使用STM32 CUBE IDE配置STM32F7 用DMA传输多通道ADC数据_stm32cubeide 配置adc_一只小白啊的博客-CSDN博客         普通模式和循环模式的区别在于,普通模式下,DMA只会接收一次数据,

    2024年02月05日
    浏览(61)
  • 【STM32笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)

    【STM32】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全、首字节错误的问题) 【STM32笔记】低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置(ADC唤醒无

    2024年02月14日
    浏览(39)
  • stm32 freertos多任务状态迁移,中断临界段,任务延时

    arm中SP,LR,PC寄存器以及其它所有寄存器以及处理器运行模式介绍 特权级与用户级的区别主要是某些寄存器能不能访问与修改: cortex M3/M4内核 特权级与用户级详解 Cortex-M3双堆栈MSP和PSP Cortex-M3双堆栈MSP和PSP M3内核何时使用MSP何时使用PSP? 特权级可以使用MSP 和PSP指针 用户级

    2024年02月12日
    浏览(56)
  • STM32不使用中断实现定时器微秒级精确延时

    我们在写代码的时候避免不了要使用延时函数,很多延时函数都是使用中断或者tick来实现的,tick的方式最大到毫秒ms级别,通过中断方式的通用定时器来实现,如果实现1us的延时那么每1us就来一次中断,很影响cpu的效率。 本文提供一种 不使用中断 ,并且很简单的方式实现的

    2024年04月11日
    浏览(49)
  • 关于 STM32 在使用 C++ 进行编程时无法进行中断(触发中断就死循环)的问题

    他妈的!!!就因为这破事导致我浪费了两天的时间!!! 都是基础不扎实的锅,导致我没能第一时间想到问题的关键 好了,平复一下心情,快速的写一篇博客来记录这个叼问题 先把结论放在这里:用 extern \\\"C\\\" {} 把中断函数包起来 本来我是想写一个 RS485 通信模块的,但是

    2024年02月12日
    浏览(46)
  • STM32 HAL库 中断处理中使用延时函数(HAL_Delay)

    今天在学习STM32 HAL库外部中断,使用的是按键触发外部中断,想在外部中断里面写一个按键消抖,也就是在HAL库外部中断处理函数中使用了HAL_Delay() 函数,后来经过实验,在外部中断处理函数(void EXTI1_IRQHandler(void))和中断回调函数(void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin))里面都

    2024年03月16日
    浏览(45)
  • 【HAL库】STM32CubeMX开发----非阻塞延时实验----SysTick(滴答定时器)中断

    STM32CubeMX 下载和安装 详细教程 【HAL库】STM32CubeMX开发----STM32F103/F207/F407----目录 HAL库 有自带的 ms级 延时函数: HAL_Delay(); 缺点: 这是 阻塞延时 方式,就是延时期间,什么都不能干,这样很浪费资源。 这篇文章主要介绍,利用 SysTick(滴答定时器)中断 实现 非阻塞延时 的实验

    2024年02月16日
    浏览(54)
  • stm32进入硬件错误中断hardfault的原因剖析以及如何定位(必看)

    指令集方面:arm一般高端处理器,比如cortex-a系列,都是32位的arm指令。而cortex-m0,1,3,4等低端处理器,也叫做单片机,为了增加代码密度(同样存储器内可以存更多指令),用的是thumb指令集(而且仅支持这个指令集),这个指令集大多数指令是16位的,少数是32位的。这就是为

    2023年04月09日
    浏览(37)
  • 通过串口中断的方式进行ASR-01S模块与STM32通信(问题与解决)

    最近在做一个智能家居的项目,需要实现语音控制的功能,于是我选用了ASR-01S模块与STM32通信,这个模块最大的好处在于有配套的编程软件和语音库,不用自己训练且编程简单(少儿编程的程度)。ASR-01S的代码架构在这不多说,总之在收到语音后它会通过串口发送一串命令给

    2024年04月22日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包