STM32中assert_param的使用

合集下载

assert常用方法

assert常用方法

assert常用方法在编写程序时,我们都会在代码中添加assert(断言)语句来进行调试,以确保代码的正确性。

assert语句是一种简单的调试工具,针对特定的场景可以提高代码的安全性和可靠性。

在本文中,我将分享一些常用的assert方法。

1. assert的基本语法assert语句包含一个测试表达式和一条错误信息。

如果测试表达式的结果为False,assert会抛出一个异常,打印错误信息。

assert 语句的基本语法如下:```assert expression [, arguments]```其中,expression是测试条件语句,而arguments是一个可选的错误信息。

2. 使用assert语句进行类型检查有时候我们需要对程序中的数据类型进行检查,例如判断一个参数是否是整数类型。

在这种情况下,我们可以使用assert语句来实现类型检查。

例如,下面代码检查一个参数是否为整数类型:```def func(num):assert isinstance(num, int), "参数必须为整数类型"print(num)```如果传入的参数不是整数类型,assert就会抛出异常,并输出错误信息。

3. 使用assert语句进行条件检查在编程中,我们需要对某些条件进行检查,例如判断一个列表是否为空或者判断一个变量是否为True。

在这种情况下,我们可以使用assert语句来进行条件检查。

例如,下面代码检查一个列表是否为空:```mylist = []assert len(mylist) > 0, "列表不能为空"```如果列表为空,assert就会抛出异常,并输出错误信息。

4. 使用assert语句进行程序调试当我们遇到程序中的错误时,在程序的关键位置添加assert语句可以帮助我们快速定位程序错误,进而进行调试。

例如,下面代码计算一个数的平方,但在输入负数时会出错:```def square(num):assert num >= 0, "输入的数必须大于等于0"return num ** 2```如果输入负数,assert就会抛出异常,并输出错误信息,提醒我们输入的数必须大于等于0。

使用STM32CubeMX生成RTC工程[秒中断]

使用STM32CubeMX生成RTC工程[秒中断]

使⽤STM32CubeMX⽣成RTC⼯程[秒中断] /********************************************************************************* File Name : main.c* Description : Main program body******************************************************************************** This notice applies to any and all portions of this file* that are not between comment pairs USER CODE BEGIN and* USER CODE END. Other portions of this file, whether* inserted by the user or by software development tools* are owned by their respective copyright owners.** COPYRIGHT(c) 2017 STMicroelectronics** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:* 1. Redistributions of source code must retain the above copyright notice,* this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright notice,* this list of conditions and the following disclaimer in the documentation* and/or other materials provided with the distribution.* 3. Neither the name of STMicroelectronics nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.********************************************************************************//* Includes ------------------------------------------------------------------*/#include "main.h"#include "stm32f1xx_hal.h"/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private variables ---------------------------------------------------------*/RTC_HandleTypeDef hrtc;/* USER CODE BEGIN PV *//* Private variables ---------------------------------------------------------*//* Buffer used for displaying Time */uint8_t aShowTime[50] = {0};uint8_t rtc_alarm_flag = 0;uint8_t rtc_event_flag = 0;/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);static void MX_GPIO_Init(void);static void MX_RTC_Init(void);/* USER CODE BEGIN PFP *//* Private function prototypes -----------------------------------------------*//* USER CODE END PFP *//* USER CODE BEGIN 0 */uint8_t BIN2BCD(uint8_t byte){uint8_t low, high;low = byte & 0x0F;high = ((byte >> 4) & 0x0F) * 10;return high + low;}uint8_t BCD2BIN(uint8_t byte){return ((byte/10)<<4) + (byte%10);}/*** @brief Configure the current time and date.* @param None* @retval None*/static void RTC_AlarmConfig(void){RTC_AlarmTypeDef salarmstructure;/*##-1- Configure the RTC Alarm peripheral #################################*//* Set Alarm to 01:17:30RTC Alarm Generation: Alarm on Hours, Minutes and Seconds */salarmstructure.Alarm = RTC_ALARM_A;salarmstructure.AlarmTime.Hours = 0x1;salarmstructure.AlarmTime.Minutes = 0x24;salarmstructure.AlarmTime.Seconds = 0x00;if(HAL_RTC_SetAlarm_IT(&hrtc,&salarmstructure,RTC_FORMAT_BCD) != HAL_OK){/* Initialization Error */Error_Handler();}}/*** @brief Display the current time.* @param showtime : pointer to buffer* @retval None*/static void RTC_TimeShow(uint8_t* showtime){RTC_DateTypeDef sdatestructureget;RTC_TimeTypeDef stimestructureget;/* Get the RTC current Time */HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);/* Get the RTC current Date */HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);/* Display time Format : hh:mm:ss */sprintf((char*)showtime,"%02d:%02d:%02d",stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds); }/* USER CODE END 0 */int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_RTC_Init();/* USER CODE BEGIN 2 *//*##-1- Configure Alarm ####################################################*//* Configure RTC Alarm */RTC_AlarmConfig();HAL_RTCEx_SetSecond_IT(&hrtc);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *//*##-2- Display the updated Time #########################################*/RTC_TimeShow(aShowTime);}/* USER CODE END 3 */}/** System Clock Configuration*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct;RCC_ClkInitTypeDef RCC_ClkInitStruct;RCC_PeriphCLKInitTypeDef PeriphClkInit;/**Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.LSIState = RCC_LSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){_Error_Handler(__FILE__, __LINE__);}/**Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){_Error_Handler(__FILE__, __LINE__);}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){_Error_Handler(__FILE__, __LINE__);}/**Configure the Systick interrupt time*/HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);/**Configure the Systick*/HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* SysTick_IRQn interrupt configuration */HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);}/* RTC init function */static void MX_RTC_Init(void){RTC_TimeTypeDef sTime;RTC_DateTypeDef DateToUpdate;/**Initialize RTC Only*/hrtc.Instance = RTC;hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;if (HAL_RTC_Init(&hrtc) != HAL_OK){_Error_Handler(__FILE__, __LINE__);}/**Initialize RTC and set the Time and Date*/if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0x32F2){sTime.Hours = 0x1;sTime.Minutes = 0x17;sTime.Seconds = 0x0;if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK){_Error_Handler(__FILE__, __LINE__);}DateToUpdate.WeekDay = RTC_WEEKDAY_FRIDAY;DateToUpdate.Month = RTC_MONTH_JULY;DateToUpdate.Date = 0x14;DateToUpdate.Year = 0x17;if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK) {_Error_Handler(__FILE__, __LINE__);}HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,0x32F2);}}/** Configure pins as* Analog* Input* Output* EVENT_OUT* EXTI*/static void MX_GPIO_Init(void){/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();}/* USER CODE BEGIN 4 */void HAL_RTCEx_RTCEventCallback (RTC_HandleTypeDef *hrtc){rtc_event_flag++;}/*** @brief Alarm callback* @param hrtc : RTC handle* @retval None*/void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc){rtc_alarm_flag++;}/* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @param None* @retval None*/void _Error_Handler(char * file, int line){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */ while(1){}/* USER CODE END Error_Handler_Debug */}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t* file, uint32_t line){/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */}#endif/*** @}*//*** @}*//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/仿真测试结果。

使用STM32库建立keil-4工程详细步骤教学总结

使用STM32库建立keil-4工程详细步骤教学总结

使⽤STM32库建⽴keil-4⼯程详细步骤教学总结STM32 使⽤外设库建⽴keil⼯程新建⽂件夹取名为⾃⼰想要的名称(如GPIO)1、打开⽂件,建⽴如下的⽂件结构:2、打开Project,建⽴如下⽂件:3、打开下载来的外设驱动库如下:4、把Libraries的下的两个⽂件(CMSIS和STM32F10x_StdPeriph_Driver)拷贝到GPIO⽂件下:5、打开下载的驱动库下的Project⽂件,打开STM32F10x_StdPeriph_Examples,找到我们需要的例程,如GPIO6、打开GPIO⽂件夹7、打开IOToggle,复制除了readerme.txt之外的⽂件到⼯程下的User⽂件。

复制好之后:8、到此,准备⼯作完毕。

9、打开KEIL,新建⼯程10、保存在Project⽂件夹下⾯,取名为⾃⼰的名字,我取名为GPIO。

11、选定⾃⼰使⽤的芯⽚,点击ok。

12、此时会跳出这个对框框,选择否:13、⼯程建好后是这样的。

14、在⼯程上右键选择Mange Componts 如下:15、建⽴如下组16、在User下⾯添加刚才⽅法哦User下的C⽂件:点击Add17、增加StdPeriph_Driver的⽂件,在⾃⼰⼯程StdPeriph_Driver下⾯的下⾯的src⽂件如下:(说明:只需要增加⾃⼰需要的,我这⾥全部添加了)18、在CMSIS下增加⽂件:CMSIS⽂件下的CM3的CoreSupport的⽂件19、在StartUp下⾯增加位于下的⽂件21、增加完⽂件后⼯程如下现在左键点击选中GPIO⼯程名,在点击右键选择Options for Target ‘GPIO’来配置⼯程Select Folder Objects…,选择我们在Project⽬录下的Obj⽂件23、勾选长⽣hex⽂件。

24、在Listing页⾯下点击Select Folder Objects for listings…,选择我们在project⽬录下的List⽂件在C/C++页⾯下配置,这是预编译的定义;Define 中写⼊USE_STDPERIPH_DRIVER, STM32F10X_HD其中第⼀个“USE_STDPERIPH_DRIVER”定义了使⽤外设库,定义此项会包含*_conf.h ⽂件,从⽽使⽤外设库;⽽第⼆个“STM32F10X_HD”从字⾯理解应该是定义了⼤等容量的STM32MCU,STM32F10X_MD则为中等容量等。

c中 断言assert 使用示例 举例说明

c中 断言assert 使用示例 举例说明

c中断言assert 使用示例举例说明全文共四篇示例,供读者参考第一篇示例:在C语言中,断言(assert)是一种用于在程序执行时检测逻辑错误的方法。

当条件表达式为假时,断言将终止程序的执行,以便能够及时发现错误并进行调试。

在本文中,我们将通过几个具体的示例来说明如何在C语言中使用断言。

示例1:检查数组下标是否越界假设我们有一个包含10个整数的数组,我们想访问数组的第11个元素,这将导致数组下标越界。

为了避免这种情况,我们可以使用断言来检查数组下标是否越界。

```c#include <assert.h>assert(index >= 0 && index < 10);printf("Element at index %d is %d\n", index, arr[index]);return 0;}```在上面的示例中,我们首先使用断言检查索引是否大于等于0且小于数组的大小(10)。

如果条件为假,程序将终止执行,并打印出一条错误消息。

通过这种方式,我们可以确保程序不会访问数组中不存在的元素。

示例2:检查指针是否为空另一个常见的用例是检查指针是否为空。

在C语言中,对空指针进行解引用将导致未定义的行为,因此我们可以使用断言来确保指针不为空。

void print_string(const char* str){assert(str != NULL);printf("String: %s\n", str);}总结通过上面的示例,我们可以看到断言在C语言中的重要性和灵活性。

它可以帮助我们在程序执行过程中及时发现潜在的逻辑错误,并防止这些错误导致严重的后果。

在编写C程序时,我们应该充分利用断言来提高代码的健壮性和可靠性。

希望这篇文章能够帮助您更好地理解和使用断言。

第二篇示例:在C语言编程中,断言(assert)是一种常用的调试技术,它允许程序员在代码中插入一些条件判断语句,用于检测程序的运行时错误。

STM32第一章

STM32第一章

32位基于ARM微控制器STM32F101xx与STM32F103xx 固件函数库介绍本手册介绍了32 位基于ARM微控制器STM32F101xx与STM32F103xx的固件函数库。

该函数库是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。

该函数库还包括每一个外设的驱动描述和应用实例。

通过使用本固件函数库,无需深入掌握细节,用户也可以轻松应用每一个外设。

因此,使用本固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。

每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。

每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API 对该驱动程序的结构,函数和参数名称都进行了标准化。

所有的驱动源代码都符合“Strict ANSI-C”标准(项目于范例文件符合扩充ANSI-C标准)。

我们已经把驱动源代码文档化,他们同时兼容MISRA-C 2004 标准(根据需要,我们可以提供兼容矩阵)。

由于整个固态函数库按照“Strict ANSI-C”标准编写,它不受不同开发环境的影响。

仅对话启动文件取决于开发环境该固态函数库通过校验所有库函数的输入值来实现实时错误检测。

该动态校验提高了软件的鲁棒性。

实时检测适合于用户应用程序的开发和调试。

但这会增加了成本,可以在最终应用程序代码中移去,以优化代码大小和执行速度。

想要了解更多细节,请参阅Section 2.5。

因为该固件库是通用的,并且包括了所有外设的功能,所以应用程序代码的大小和执行速度可能不是最优的。

对大多数应用程序来说,用户可以直接使用之,对于那些在代码大小和执行速度方面有严格要求的应用程序,该固件库驱动程序可以作为如何设置外设的一份参考资料,根据实际需求对其进行调整此份固件库用户手册的整体架构如下:… 定义,文档约定和固态函数库规则。

… 固态函数库概述(包的内容,库的架构),安装指南,库使用实例。

STM32库函数TIM_CCxCmd()和TIM_CCxNCmd()错误

STM32库函数TIM_CCxCmd()和TIM_CCxNCmd()错误

地址:安徽省、合肥市、肥东县、店埠镇,合肥市福来德电子科技有限公司2015年9月7日,在使用PWM 时,调试发现STM32 V3.5的库有几个函数有问题。

下载了STM32 V3.61的库,也是同样的问题,于是自己修改这个BUG 。

STM32库函数TIM_CCxCmd()和TIM_CCxNCmd()错误修改:/** * @brief Enables or disables the TIM Capture Compare Channel x.* @param T IMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral. * @param TIM_Channel: specifies the TIM Channel* This parameter can be one of the following values: * @arg TIM_Channel_1: TIM Channel 1* @arg TIM_Channel_2: TIM Channel 2* @arg TIM_Channel_3: TIM Channel 3* @arg TIM_Channel_4: TIM Channel 4* @param TIM_CCx: specifies the TIM Channel CCxE bit new state.* This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable.* @retval None*/ void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) {uint16_t tmp = 0;/* Check the parameters */ assert_param(IS_TIM_LIST8_PERIPH(TIMx));assert_param(IS_TIM_CHANNEL(TIM_Channel));assert_param(IS_TIM_CCX(TIM_CCx));tmp = CCER_CCE_Set << TIM_Channel;/* Reset the CCxE Bit */TIMx->CCER &= (uint16_t)~ tmp;/* Set or reset the CCxE Bit *///TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); //原来的库函数错误 //修改为:if (TIM_CCx==ENABLE) TIMx->CCER |= tmp;}/*** @brief Enables or disables the TIM Capture Compare Channel xN.* @param TIMx: where x can be 1, 8, 15, 16 or 17 to select the TIM peripheral. * @param TIM_Channel: specifies the TIM Channel* This parameter can be one of the following values:地址:安徽省、合肥市、肥东县、店埠镇,合肥市福来德电子科技有限公司 * @arg TIM_Channel_1: TIM Channel 1* @arg TIM_Channel_2: TIM Channel 2* @arg TIM_Channel_3: TIM Channel 3 * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable.* @retval None*/void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN) {uint16_t tmp = 0;/* Check the parameters */assert_param(IS_TIM_LIST2_PERIPH(TIMx));assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel));assert_param(IS_TIM_CCXN(TIM_CCxN));tmp = CCER_CCNE_Set << TIM_Channel;/* Reset the CCxNE Bit */TIMx->CCER &= (uint16_t) ~tmp;/* Set or reset the CCxNE Bit *///TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel); //原来的库函数错误 //修改为:if (TIM_CCxN==ENABLE) TIMx->CCER |= tmp;}。

Systick 定时器

Systick 定时器一、Systick定时器Systick是一个定时器而已,只是它放在了NVIC 中,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。

没有学过操作系统的同学,可能会很郁闷,啥叫滴答中断?这里来简单地解释一下:操作系统进行运转的时候,也会有“心跳”。

它会根据“心跳”的节拍来工作,把整个时间段分成很多小小的时间片,每个任务每次只能运行一个“时间片”的时间长度就得退出给别的任务运行,这样可以确保任何一个任务都不会霸占整个系统不放。

这个心跳,可以通过定时器来周期性触发,而这个定时器就是systick。

很明显,这个“心跳” 是不允许任何人来随意地访问和修改的。

只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。

二、systick编程现在我们想通过Systick 定时器做一个精确的延迟函数,比如让LED 精确延迟1 秒钟闪亮一次。

思路:利用systick 定时器为递减计数器,设定初值并使能它后,它会每个系统时钟周期计数器减1,计数到0 时,SysTick 计数器自动重装初值并继续计数,同时触发中断。

那么每次计数器减到0,时间经过了:系统时钟周期* 计数器初值。

我们使用72M 作为系统时钟,那么每次计数器减1 所用的时间是1/72M,计数器的初值如果是72000,那么每次计数器减到0,时间经过(1/72M) * 72000 = 0.001m,即1ms。

三、Systick相关寄存器(1)系统时钟节拍控制与状态寄存器(Systick_CTRL)(2)系统时钟节拍(SysTick)重装值寄存器(SysTick_LOAD)在计数器到达0 时,使用SysTick 重装值寄存器来指定载入“当前值寄存器”的初始值。

初始值可以是 1 到0x00FFFFFF 之间的任何值。

因此,作为一个连拍式(multi-shot)定时器,它每N+1 个时钟脉冲就触发一次,周而复始,此处N为1 到0x00FFFFFF 之间的任意值。

C语言assert用法

C语⾔assert⽤法 1/* Exported types ------------------------------------------------------------*/2/* Exported constants --------------------------------------------------------*/3/* Uncomment the line below to expanse the "assert_param" macro in the4 Standard Peripheral Library drivers code */5/* #define USE_FULL_ASSERT 1 */67/* Exported macro ------------------------------------------------------------*/8 #ifdef USE_FULL_ASSERT910/**11 * @brief The assert_param macro is used for function's parameters check.12 * @param expr: If expr is false, it calls assert_failed function which reports13 * the name of the source file and the source line number of the call14 * that failed. If expr is true, it returns no value.15 * @retval None16*/17#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))18/* Exported functions ------------------------------------------------------- */19void assert_failed(uint8_t* file, uint32_t line);20#else21#define assert_param(expr) ((void)0)22#endif /* USE_FULL_ASSERT */ 看到⼀个宏, 它⼤概是这样的: #define assert_param(expr) ((expr) ? (void)0 : assert_failed((u8 *)__FILE__, __LINE__)) 代码的含意简单, 关键是那个 (void)0 的⽤法, 我还是第⼀次见到(别笑). 我⽤ void 的时候, 有两种情况: 1.放到函数前⾯, 强调函数没有返回值, 也就是说函数不能作右值 如: void fun(int x); 2.放到函数形参⾥⾯, 强调函数⽆任何参数 如: int fun(void); 还有⼀种⽤法是: #define NULL ((void*)0) 当然, 这就是NULL空指针的定义⽅式(在 stdlib.h ⾥⾯). 可, 上⾯宏的 (void)0 , ⼀开始确实让我觉得有点奇怪, 不知道⼲嘛的, 平静下来, 想了想. 原来, 宏⾥⾯这样⽤的⽬的是防⽌该宏被⽤作右值, (void)0 本⾝也不能作右值, 因为 void ⾮实际的类型!。

stm32入门说明


下载好的文件一般是个压缩包, 我们把它解压一下默认的文件名就可以了, 我现在使用的是 v3.1.2 的库,解压后的文件名 STM32F10x_StdPeriph_Lib_V3.1.2,打开解压后的文件可以看到 如下的内容
Libraries 是系统的库,不需要我们修改。project 是工程的一些东西,里面是些例程和模板。 Utilities 是 st 的开发板的一些东西。我们主要关注 project 里面的内容。Project 如下
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef; 其中的 GPIOSpeed_TypeDef, GPIOMode_TypeDef 可以查看库中的 GPIO.h 文件中的详细定义 这里就不介绍。 看下 st 给出的库提供了哪些操作端口的函数吧: 这些函数的详细信息可以参考 st 的库说明,最好去看一下函数的原型代码,这样会有更好 的理解。当然了,我在具体使用的时候也会做一般的说明。 void GPIO_DeInit(GPIO_TypeDef* GPIOx); void GPIO_AFIODeInit(void); void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); void GPIO_EventOutputCmd(FunctionalState NewState); void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState); void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface); 介绍到这里, 对通用的 I/O 端口有个大概的了解了吧, 下面我们通过例子来详细的说明一下。 说到这里,是该介绍一下如何使用 MDK4.0 开始一个新的工程,这里我们使用最新的库进行 配置操作。 去下载新的库,如何下载大家 google 吧,一般 st 的网站上都有的,这里就略过了。

c语言的assert函数

c语言的assert函数摘要:1.C语言中的assert函数简介2.assert函数的用法和功能3.assert函数的优点与缺点4.使用assert函数的注意事项5.替代assert函数的方法正文:C语言作为一种具有较强控制能力的编程语言,提供了许多有用的函数。

其中,assert函数是一个用于检测程序错误的实用工具。

本文将详细介绍C语言的assert函数,包括其用法、功能、优缺点及使用注意事项。

1.C语言中的assert函数简介assert函数是C语言标准库中的一个函数,它的原型位于stdlib.h头文件中。

assert函数的作用是检验一个条件是否成立,如果条件不成立,则报告一个错误并终止程序运行。

2.assert函数的用法和功能assert函数的调用格式为:```#include <stdlib.h>void assert(int expression);```其中,expression表示需要检验的条件。

当程序运行过程中遇到assert 函数,它会检查expression的值是否为0。

如果expression的值为0,说明条件不成立,程序会按照预设的方式处理错误,通常是输出错误信息并终止运行。

如果expression的值不为0,说明条件成立,程序将继续正常执行。

3.assert函数的优点与缺点优点:- assert函数可以方便地检查程序中的条件,有助于发现潜在的错误。

- 当条件不成立时,assert函数可以报告错误信息,便于程序员定位问题。

缺点:- 使用assert函数会导致程序终止,可能在某些情况下影响程序的正常运行。

- 当多个地方使用assert函数时,需要分别为每个条件编写错误处理代码,增加了编程工作量。

4.使用assert函数的注意事项- 使用assert函数时,请确保报告错误信息的准确性和清晰度,以便于程序员理解问题所在。

- 避免在关键功能模块中使用assert函数,以免影响程序的正常运行。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32中assert_param的使用
在STM32的固件库和提供的例程中,到处都可以见到assert_param()
的使用。如果打开任何一个例程中的stm32f10x_conf.h文件,就可以
看到实际上assert_param是一个宏定义;
在固件库中,它的作用就是检测传递给函数的参数是否是有效的参数。
所谓有效的参数是指满足规定范围的参数,比如某个参数的取值范围只
能是小于3的正整数,如果给出的参数大于3,
则这个assert_param()可以在运行的程序调用到这个函数时报告错误,
使程序员可以及时发现错误,而不必等到程序运行结果的错误而大费周
折。

这是一种常见的软件技术,可以在调试阶段帮助程序员快速地排除那些
明显的错误。

它确实在程序的运行上牺牲了效率(但只是在调试阶段),但在项目的开
发上却帮助你提高了效率。

当你的项目开发成功,使用release模式编译之后,或在
stm32f10x_conf.h文件中注释掉对USE_FULL_ASSERT的宏定义,
所有的assert_param()检验都消失了,不会影响最终程序的运行效率。
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((u8
*)__FILE__, __LINE__))

。。。
assert_param(IS_ADC_ALL_PERIPH(ADCx));
。。。

在执行assert_param()的检验时,如果发现参数出错,它会调用函数
assert_failed()向程序员报告错误,在任何一个例程中的main.c中都有
这个函数的模板,如下:
void assert_failed(uint8_t* file, uint32_t line)
{

while (1)
{}
}

你可以按照自己使用的环境需求,添加适当的语句输出错误的信息提
示,或修改这个函数做出适当的错误处理。

1、STM32F10xD.LIB是DEBUG模式的库库文件。
2、STM32F10xR.LIB是Release模式的库库文件。
3、要选择DEBUG和RELEASE模式,需要修改stm32f10x_conf.h的
内容。
#define DEBUG 表示DEBUG模式,把该语句注释掉,则为
RELEASE模式。
4、要选择DEBUG和RELEASE模式,也可以在Options,C/C++,Define
里填入DEBUG的预定义。
这样,就不需要修改stm32f10x_conf.h的内容。
5、如果把库加入项目,则不需要将ST的库源文件加入项目,比较方便。
但是,库的选择要和DEBUG预定义对应。

相关文档
最新文档