一、assert_param是什麼
assert_param是STM32固件庫中的函數,用於檢查傳入的參數是否合法。該函數的原型為assert_param(),在代碼中使用時通常會被宏定義為以下形式:
#define assert_param(expr) ((void)0)
由此可見,如果表達式expr為真,則assert_param()函數不做任何操作,否則程序將進入死循環,表示傳入的參數不合法。
二、assert_param的作用
在程序開發過程中,我們經常需要在函數中檢查傳入的參數是否合法。例如,在初始化GPIO口之前,需要檢查GPIO口是否已經被使能,在設置ADC採樣率之前,需要檢查採樣率是否符合ADC的要求。這些參數的檢查需要花費大量的時間和精力,而assert_param函數正是為了解決這個問題而存在的。
assert_param函數能夠大大簡化參數檢查的工作,同時能夠提高代碼的可讀性和可維護性。使用assert_param函數,可以避免程序在使用不合法的參數時崩潰,提高了程序的穩定性和安全性。
三、assert_param的使用
assert_param函數通常用於STM32的固件庫中,我們可以在我們的代碼中使用這個函數來檢查傳入的參數是否合法。assert_param函數通常有如下幾個步驟:
第一步,定義assert_param()函數:
#define assert_param(expr) ((void)0)
第二步,根據表達式,判斷參數是否合法:
if(expr)
{
// do nothing
}
else
{
assert_param_failed(file, line);
}
第三步,當參數不合法時,調用assert_param_failed()函數:
void assert_param_failed(uint8_t *file, uint32_t line)
{
// 程序運行到這裡表示執行了不合法的操作,需要進行相應的處理
while (1)
{
// 程序進入死循環
}
}
在使用assert_param函數時,需要注意以下幾點:
1、assert_param函數僅用於檢查傳入的參數是否合法,不作為程序中斷或調試的依據;
2、在使用assert_param函數時,需要確保被檢查的參數已經被正確初始化,否則可能會出現錯誤的判斷結果;
3、在使用assert_param函數時,需要確保被檢查的參數不會修改被編譯器優化掉,否則可能會導致assert_param函數失效。
四、assert_param的示例代碼
下面是一個使用assert_param函數的示常式序,該程序功能是通過LM35感測器採集環境溫度,並將溫度值通過串口輸出:
#include "stm32f10x.h"
#include "stdio.h"
#define assert_param(expr) ((void)0)
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
void delay_ms(unsigned long n)
{
unsigned long i;
for(i=0;i<n;i++);
}
void USARTx_SendChar(USART_TypeDef *USARTx, char Data)
{
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, Data);
}
void USARTx_SendString(USART_TypeDef *USARTx, char *str)
{
while(*str != '\0')
{
USARTx_SendChar(USARTx, *str);
str++;
}
}
int main(void)
{
float temp = 0.0;
char buffer[50] = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
delay_ms(10);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (1)
{
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
temp = (float)ADC_GetConversionValue(ADC1)*3.3/4096*1000/10;
sprintf(buffer, "Temperature = %.2f\r\n", temp);
USARTx_SendString(USART1, buffer);
delay_ms(1000);
}
}
在上述代碼中,我們使用assert_param函數來檢查串口和ADC的初始化參數是否合法:
USART_Init(USART1, &USART_InitStructure); ADC_Init(ADC1, &ADC_InitStructure);
這裡需要注意的是,在使用assert_param函數時,需要先定義一個常量,以便在assert_param_failed()函數中使用:
#define FILE_NAME __FILE__
assert_param_failed()函數的代碼如下:
void assert_param_failed(uint8_t *file, uint32_t line)
{
char buffer[50] = {0};
sprintf(buffer, "assert_param_failed - file %s, line %d\r\n", file, line);
USARTx_SendString(USART1, buffer);
while (1)
{
// 程序進入死循環
}
}
在上述代碼中,我們使用串口將錯誤信息輸出,以方便我們進行調試和錯誤定位。
原創文章,作者:HMNM,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/145712.html
微信掃一掃
支付寶掃一掃