首页>>科技 >>内容

STM32库函数中assert,param语句的用法解析

发布时间:2023-10-05 16:50:13编辑:温柔的背包来源:

很多朋友对STM32库函数中assert,param语句的用法解析不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。

STM32库函数中assert,param语句的用法解析

在使用STM32库函数时,你会发现带参数的库函数前面有assert_param语句。

例如,我们看一个库函数,如下所示:

该函数是3.5版本库函数stm32f10x_tim.c中的定时器复位函数。

assert_param语句的作用是什么?

assert_param语句是程序开发过程中用于调试的检测语句。默认情况下它是不启用的,您可以忽略它的存在。不过,当你在调试程序的时候,你可以打开这个检测机制,调试完之后再关闭它。

如何使assert_param起作用?

检查assert_param的定义,位于stm32f10x_conf.h文件中。你会发现它实际上是一个宏。查看其条件编译语句,会发现定义USE_FULL_ASSERT后,可以开启assert_param参数检测机制。宏定义USE_FULL_ASSERT已隐藏在文件中。我们只需删除它的注释符号即可。

看上图中第59行代码。它是一条条件编译语句,意思是:如果定义了USE_FULL_ASSERT,则将assert_param定义为三元运算结构体(第68行),否则(第71行),将assert_param定义为((void)0)(第72行)。换句话说,assert_param 仅在定义USE_FULL_ASSERT 时才起作用。该函数是通过一个三元运算结构来判断的(如下图)。三进制运算基础知识请参见http://www.rationmcu.com/clang/382.html

#defineassert_param(expr)((expr)?(void)0:assert_failed((uint8_t*)__FILE__,__LINE__))

assert_param语句的作用是检测函数的参数是否满足函数的要求。例如,上述函数中的参数为TIMx。我们找到IS_TIM_ALL_PERIPH的定义,可以看到TIMx中x的范围是1~17,也就是说,如果把函数写成TIM_DeInit(TIM1);如果将函数写为TIM_DeInit (TIM18);assert_param 的结果为(void) 0;将调用assert_failed函数。

#defineIS_TIM_ALL_PERIPH(PERIPH)((PERIPH)==TIM1)||\((PERIPH)==TIM2)||\((PERIPH)==TIM3)||\((PERIPH)==TIM4)||\ ( (PERIPH)==TIM5)||\((PERIPH)==TIM6)||\((PERIPH)==TIM7)||\((PERIPH)==TIM8)||\((PERIPH)==TIM9 )||\((PERIPH)==TIM10)||\((PERIPH)==TIM11)||\((PERIPH)==TIM12)||\((PERIPH)==TIM13)||\( (外围)==TIM14)||\((外围)==TIM15)||\((外围)==TIM16)||\((外围)==TIM17))

如何编写assert_failed函数?

如上,当定义了USE_FULL_ASSET并立即编译时,编译器会报错,表明assert_failed函数没有定义。我们将assert_failed函数放在main.c文件中,定义如下:

voidassert_failed(uint8_t*file,uint32_tline){printf("错误参数值:file%sonline%d\r\n",file,line);while(1);}

上面函数的含义是,如果参数错误,会输出错误的文件名和行号。结果输出到串口,可以使用串口调试助手查看输出结果。请注意,编译器“构建输出”列不会报告错误。

下面是一个例程,故意写入错误的参数,并通过STM32串口1将错误参数的文件名和行号发送到串口,打开串口调试助手就可以看到结果。

以上知识分享希望能够帮助到大家!