專(zhuān)業(yè)網(wǎng)站建設(shè)服務(wù)公司哪家好廣州今日頭條新聞最新
文檔說(shuō)明:通過(guò)滴答定時(shí)器的1ms中斷實(shí)現(xiàn)時(shí)間計(jì)數(shù),標(biāo)記需要的時(shí)間標(biāo)志,在主函數(shù)中查詢(xún)標(biāo)志,避免延時(shí)函數(shù)消耗CPU
1、HAL庫(kù)systick定時(shí)器說(shuō)明
在CubeMx生成的代碼main()函數(shù)首先執(zhí)行的函數(shù)為HAL_Init();里面會(huì)進(jìn)行滴答定時(shí)器初始化;
/*** @brief This function is used to initialize the HAL Library; it must be the first * instruction to be executed in the main program (before to call any other* HAL function), it performs the following:* Configure the Flash prefetch, instruction and Data caches.* Configures the SysTick to generate an interrupt each 1 millisecond,* which is clocked by the HSI (at this stage, the clock is not yet* configured and thus the system is running from the internal HSI at 16 MHz).* Set NVIC Group Priority to 4.* Calls the HAL_MspInit() callback function defined in user file * "stm32f4xx_hal_msp.c" to do the global low level hardware initialization * * @note SysTick is used as time base for the HAL_Delay() function, the application* need to ensure that the SysTick time base is always set to 1 millisecond* to have correct HAL operation.* @retval HAL status*/
HAL_StatusTypeDef HAL_Init(void)
{/* Configure Flash prefetch, Instruction cache, Data cache */
#if (INSTRUCTION_CACHE_ENABLE != 0U)__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
#endif /* INSTRUCTION_CACHE_ENABLE */#if (DATA_CACHE_ENABLE != 0U)__HAL_FLASH_DATA_CACHE_ENABLE();
#endif /* DATA_CACHE_ENABLE */#if (PREFETCH_ENABLE != 0U)__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif /* PREFETCH_ENABLE *//* Set Interrupt Group Priority */HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */HAL_InitTick(TICK_INT_PRIORITY);/* Init the low level hardware */HAL_MspInit();/* Return function status */return HAL_OK;
}
此處就是在做初始化滴答定時(shí)器:
/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */HAL_InitTick(TICK_INT_PRIORITY);
意思就是他的中斷函數(shù)會(huì)1ms調(diào)用1次,HAL_InitTick函數(shù)里面就是實(shí)現(xiàn)配置的
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{/* Configure the SysTick to have interrupt in 1ms time basis*/if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U){return HAL_ERROR;}......return HAL_OK;
}typedef enum
{HAL_TICK_FREQ_10HZ = 100U,HAL_TICK_FREQ_100HZ = 10U,HAL_TICK_FREQ_1KHZ = 1U,HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ
} HAL_TickFreqTypeDef;
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
由此可得HAL_SYSTICK_Config(系統(tǒng)時(shí)鐘/1000U/1),所以是1KHz的中斷
2、時(shí)間戳文件
Timestamp_Driver.h
#ifndef _Timestamp_Driver_H_
#define _Timestamp_Driver_H_
#include "main.h"typedef enum
{Timestamp_10ms = 0,Timestamp_50ms = 1,Timestamp_100ms = 2,Timestamp_200ms = 3,Timestamp_500ms = 4,Timestamp_1s = 5,Timestamp_2s = 6,Timestamp_10s = 7,
}Timestamp_Flag_EnumDef;typedef struct
{/******************************* bit Annotation:Timestamp_Flag_EnumDef 使用后需自行清零* 7--10s* 6--2s* 5--1s* 4--500ms* 3--200ms* 2--100ms* 1--50ms* 0--10ms* ***************************/uint8_t Flag;uint16_t msCnt;//Max 10s
}Timestamp_User_StructDef;extern void Timestamp_UserInit(Timestamp_User_StructDef *p);
extern void Timestamp_Timer(Timestamp_User_StructDef *p);
extern uint8_t Timestamp_GetStatus(Timestamp_User_StructDef *p,Timestamp_Flag_EnumDef flag);#endif
Timestamp_Driver.c
/**********************************************************************
*file:時(shí)間戳文件
*author:殘夢(mèng)
*date:2022.9.2
*note:注:用戶(hù)禁止使用、更改
為了方便將時(shí)間進(jìn)行計(jì)數(shù)劃分,方便將任務(wù)按實(shí)時(shí)性劃分運(yùn)行,減少消耗
**********************************************************************/
#include "Timestamp_Driver.h"/****************************************
@function:時(shí)間戳初始化
@param:
@return:void
@date:2022.9.2
@note:
****************************************/
void Timestamp_UserInit(Timestamp_User_StructDef *p)
{p->msCnt = 0; p->Flag = 0;
}/****************************************
@function:時(shí)間戳計(jì)時(shí)器
@param:
@return:void
@date:2022.9.2
@note:
****************************************/
void Timestamp_Timer(Timestamp_User_StructDef *p)
{p->msCnt++;p->Flag |= ((((p->msCnt % 10) == 0)?1:0) << Timestamp_10ms);p->Flag |= ((((p->msCnt % 50) == 0)?1:0) << Timestamp_50ms);p->Flag |= ((((p->msCnt % 100) == 0)?1:0) << Timestamp_100ms);p->Flag |= ((((p->msCnt % 200) == 0)?1:0) << Timestamp_200ms);p->Flag |= ((((p->msCnt % 500) == 0)?1:0) << Timestamp_500ms);p->Flag |= ((((p->msCnt % 1000) == 0)?1:0) << Timestamp_1s);p->Flag |= ((((p->msCnt % 2000) == 0)?1:0) << Timestamp_2s);p->Flag |= ((((p->msCnt % 10000) == 0)?1:0) << Timestamp_10s);p->msCnt = (p->msCnt >= 10000)?0:p->msCnt;
}/****************************************
@function:獲取時(shí)間戳x狀態(tài)
@param:flag--Timestamp_Flag_EnumDef
@return:0--無(wú)效,1--有效
@date:2022.8.13
@note:
****************************************/
uint8_t Timestamp_GetStatus(Timestamp_User_StructDef *p,Timestamp_Flag_EnumDef flag)
{uint8_t temp = 0,status = 0;temp = 1 << flag;status = (p->Flag & temp)?1:0;p->Flag &= (~temp);return status;
}
說(shuō)明:此文件其實(shí)就是循環(huán)計(jì)數(shù)1ms計(jì)算時(shí)間是否等于標(biāo)志時(shí)間,沒(méi)什么特別的
3、使用時(shí)間戳
1、添加文件Timestamp_Driver.c到工程
2、定義時(shí)間戳變量
Timestamp_User_StructDef TimestampNRT;//定義時(shí)間戳:SysTick_Handler()調(diào)用計(jì)數(shù)
3、主函數(shù)初始化時(shí)間戳
Timestamp_UserInit(&TimestampNRT);
4、滴答定時(shí)器中斷服務(wù)函數(shù)中調(diào)用時(shí)間戳計(jì)數(shù)函數(shù)
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 */extern Timestamp_User_StructDef TimestampNRT;//時(shí)間戳Timestamp_Timer(&TimestampNRT); //1ms計(jì)數(shù)一次/* USER CODE END SysTick_IRQn 1 */
}
5、main()函數(shù)while中查詢(xún)時(shí)間標(biāo)志并執(zhí)行操作
if(Timestamp_GetStatus(&TimestampNRT,Timestamp_1s))//標(biāo)志會(huì)查詢(xún)后清除{printf("Timestamp_1s\r\n");}