历史上的今天
今天是:2025年01月23日(星期四)
2021年01月23日 | 宏定义“中断函数接口”的注意事项
2021-01-23 来源:eefocus
1问题来源
我前面移植一部分代码,忽略了一些细节问题,直接测试,一有数据(正常应该是进入中断),程序就挂了,进入了“B .”处,如下图:

这代表什么意思呢? 网上一搜B .的意思就知道,程序运行到这个地方,在这里死循环了。
2问题跟踪,并解决
遇到上面问题,于是我就开始了在线调试查找问题。果然,在线调试一眼就看出了问题,中断函数体没有被触发,先看下图:

看上图,经常调试的人就知道,前面没有灰色的标记代表程序不会运行到这个位置。
上面那个DEBUG_COM_IRQHandler函数,我使用的是宏定义:

那么,问题来了,我使用了宏定义中断函数接口,为什么没有进入中断函数?
问题就出在宏定义和被定义函数体的包含关系,简单说就是:stm32f4xx_it.c文件里面应该添加#include "bsp_usart.h"这行代码。
不添加包含宏定义的文件,编译时就会把DEBUG_COM_IRQHandler当做成一个普通函数,也不会出错。此时,中断函数其实是没有定义的,那么,程序运行中断函数时,没有定义函数体,自然就会跳转到B .处去。
解决的办法就如上所说:stm32f4xx_it.c文件添加添加#include "bsp_usart.h"即可。
3总结
针对以上问题,拓展并总结几点内容:
1.宏定义注意事项
宏定义与源代码最好要高度一致,就拿USART时钟的宏定义来说,如下这种方式就容易出错。
宏定义:
#define DEBUG_COM_CLK RCC_APB2Periph_USART1
调用方式:
RCC_APB2PeriphClockCmd(DEBUG_COM_CLK, ENABLE);
假如我修改时钟:
RCC_APB2Periph_USART1改为RCC_APB1Periph_USART2
发现问题没有:
APB2和APB1混乱调用了。
2.B .含义
这里提出来,是让有些初学者顺便了解一下(其实网上一搜就明白)。这是一个汇编指令,“B”代表不返回的跳转,比如跳到某个标号处。“.”是指定当前的地址, B .这条指令,其实就是死循环。
3.在线调试代码覆盖
经常有朋友问题:我在线调试,为什么有些地方不能打断点? 处理需要配置输出调试信息之外,就是这里说的代码覆盖问题。
看见我上面有两个中断函数那张图没有,里面我有文字说明:前面有灰色标记的代码,代表程序可执行(已覆盖)。相反,则没有被覆盖。
4.中断函数接口宏定义
一般很多初学者不知道函数接口可以使用宏定义。其实,有很多地方,包括一些标准的代码都有用到使用宏定义函数接口。拿我们比较熟悉的FreeRTOS来说,为了移植方便,使用宏定义三个中断函数,如下图:

这里需要注意的就如上面分析的,包含关系需加上。
史海拾趣
|
基于Ansoft电磁技术的新一代PCB仿真设计 针对PCB设计人员关注的问题予以讨论,剖析PCB电磁问题的实质及处理方法,介绍Ansoft仿真解决方案的技术特点,与同类型产品的定位关系及比较,并为您展示Ansoft电磁技术及工具在国内 ...… 查看全部问答> |
|
我用了一个看门狗芯片LTC1232,想每100ms喂狗,程序如下,OK没问题。 但现在我的两个定时器都要用到别的地方,做计数器用,难道我要在主程序里面每过一段时间喂狗码? 请高手指教 void time0() interrupt 1//定时器中断time0 {   ...… 查看全部问答> |
|
[===============]WINCE arm开发板 上电后 全屏 自动运行 指定程序 第一次 接触 wince 开发板 首先遇到的问题是 要让用vs2003写的程序 在 设备 一上电 就 全屏 自动运行 这个问题 就是不想让用户 看到 wince 系统界面上的程序 请各位大侠 指教 … 查看全部问答> |
|
[wince5.0]关于interruptinitialize的使用问题,请教! 我目前是在一个wince5.0平台上写个小驱动,需要在init里启用一个中断,于是就想到了interruptinitialize()这个函数。现在的问题是如果在原BSP里的某个驱动里使用这个函数调用就没有问题,并且能完成任务;但是我自己写的驱动,编译完成后就总是出现 ...… 查看全部问答> |
|
各位大哥:本人现做的一个项目需要用到一个8M的RAM缓存,初步打算用1*16的SDRAM,主控是AVR单片机,我想请问一下哪位高手有用过普通单片机来控制SDRAM的呢?具体怎么实现?还有,究竟怎样通过执行LOAD MODE REGISTER命令,完成对SDRAM工作模式设定 ...… 查看全部问答> |




