HAL_Dalay()是毫秒級(jí)延時(shí),為了使用微秒級(jí)延時(shí)最近學(xué)習(xí)了一下,總結(jié)如下,推薦使用最后一種方式。
/*
* 本文件包括四種延時(shí)方式:
* 1. 原來的HAL庫(kù)函數(shù)HAL_Delay() 2. 采用定時(shí)器2設(shè)置延時(shí)函數(shù) 3. 采用系統(tǒng)滴答中斷方式的ms和us級(jí)延時(shí)
* 4. 采用系統(tǒng)滴答非中斷方式的ms和us級(jí)延時(shí)(在一次計(jì)數(shù)值范圍內(nèi)的延時(shí))
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l1xx_hal.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
volatile unsigned int timenum; //必須要加volatile?。?!
volatile unsigned long time_delay; // 延時(shí)時(shí)間,注意定義為全局變量
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
HAL_StatusTypeDef delay_10us(uint32_t num);
void delay_us(volatile unsigned long nms);
void delay_ms(volatile unsigned long nms);
void delay_ms2(int32_t nms);
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* 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();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/*##-1- Start the TIM Base generation in interrupt mode ####################*/
//HAL_TIM_Base_Start_IT(&htim2);
printf("Testing timer2\n");
HAL_Delay(1000);
printf("Testing timer2\n");
HAL_Delay(1000);
printf("Testing timer2\n");
HAL_Delay(1000);
printf("Testing timer2\n");
HAL_Delay(1000);
printf("Testing timer2\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
delay_ms2(500);
printf("12\n");
//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
//delay_us(500000);
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); //注意這里HAL庫(kù)重裝了系統(tǒng)計(jì)數(shù)器的值,使美1ms中斷一次?。?/p>
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USER CODE BEGIN 4 */
/**
* @brief Period elapsed callback in non blocking mode
* @param htim: TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定時(shí)器2中斷處理函數(shù)
{
if (htim->Instance == htim2.Instance)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
if(timenum)
{
timenum--;
//printf("%d\n", timenum);
}
}
}
HAL_StatusTypeDef delay_10us(uint32_t num)//自定義的定時(shí)器2實(shí)現(xiàn)延時(shí)的函數(shù)
{
timenum = num;
HAL_TIM_Base_Start_IT(&htim2);
while(timenum) //為什么一直停在這個(gè)循環(huán)中???3-2-1-2-3……怎么會(huì)這樣?。。?-volatile!
;
HAL_TIM_Base_Stop_IT(&htim2);
return HAL_OK;
}
//SysTick實(shí)現(xiàn)延時(shí)n_ms,中斷方式
void delay_ms(volatile unsigned long nms)
{
//SYSTICK分頻--1ms的系統(tǒng)時(shí)鐘中斷
if (SysTick_Config(HAL_RCC_GetHCLKFreq()/1000))
{
while (1);
}
time_delay=nms;//讀取定時(shí)時(shí)間
while(time_delay);
SysTick->CTRL=0x00; //關(guān)閉計(jì)數(shù)器
SysTick->VAL =0X00; //清空計(jì)數(shù)器
}
//SysTick實(shí)現(xiàn)延時(shí)n_us,中斷方式
void delay_us(volatile unsigned long nus)
{
//SYSTICK分頻--1us的系統(tǒng)時(shí)鐘中斷
if (SysTick_Config(HAL_RCC_GetHCLKFreq()/1000000))
{
while (1);
}
time_delay=nus;//讀取定時(shí)時(shí)間
while(time_delay);
SysTick->CTRL=0x00; //關(guān)閉計(jì)數(shù)器
SysTick->VAL =0X00; //清空計(jì)數(shù)器
}
//SysTick實(shí)現(xiàn)延時(shí)中斷方式的中斷處理函數(shù)
//在中斷中將time_delay遞減。實(shí)現(xiàn)延時(shí)
//void SysTick_Handler(void)
//{
// if(time_delay)
// time_delay--;
//}
//void HAL_SYSTICK_Callback(void)//原cube HAL庫(kù)中中斷處理回調(diào)函數(shù)重寫
//{
// if(time_delay)
// time_delay--;
//}
//void HAL_IncTick(void)//原cube HAL庫(kù)中,重寫
//{
// if(time_delay)
// time_delay--;
//}
/********************************* 優(yōu)選的方式 ***********************************************************************/
/*一次填充系統(tǒng)計(jì)時(shí)器以實(shí)現(xiàn)非中斷延遲,受限系統(tǒng)計(jì)時(shí)器stmtick只有24位,所以最長(zhǎng)計(jì)時(shí)有所限制*/
void delay_ms2(int32_t nms)
{
int32_t temp;
SysTick->LOAD = 8000*nms;
SysTick->VAL=0X00;//清空計(jì)數(shù)器
SysTick->CTRL=0X01;//使能,減到零是無動(dòng)作,采用外部時(shí)鐘源
do
{
temp=SysTick->CTRL;//讀取當(dāng)前倒計(jì)數(shù)值
}while((temp&0x01)&&(!(temp&(1<<16))));//等待時(shí)間到達(dá)
SysTick->CTRL=0x00; //關(guān)閉計(jì)數(shù)器
SysTick->VAL =0X00; //清空計(jì)數(shù)器
}
/* USER CODE END 4 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
/*********************************************************************************************************************/
/*********************************************************************************************************************/
/*********************************************************************************************************************/
/*如果自寫系統(tǒng)時(shí)鐘中斷處理函數(shù),需要在stml1xx_it.c中注釋掉一下函數(shù)*/
/**
* @brief This function handles System tick timer.
*/
#if 1
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
#endif
上一篇:STM32 CubeMX如何生成微秒(us)級(jí)延時(shí)
下一篇:STM32F401 SDIO HAL driver初始化SD卡
推薦閱讀
史海拾趣
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- Alif 大幅增強(qiáng)邊緣 AI 處理器性能
- VS Code+PlatformIO搭建ESP32 Arduino開發(fā)環(huán)境
- ESP32學(xué)習(xí)筆記(49)——RFID RC522使用
- Esp32環(huán)境離線搭建參考
- ESP32使用舵機(jī)庫(kù)時(shí)的錯(cuò)誤
- ESP32 S3接ST7789屏幕線序
- Arduino IDE安裝ESP32開發(fā)環(huán)境的最簡(jiǎn)單方法
- 基于S3C44B0X和μC/OS-Ⅱ智能家居嵌入式系統(tǒng)設(shè)計(jì)
- 8位還能打,新唐推出全新工業(yè)級(jí)MCU
- 半導(dǎo)體關(guān)稅可能會(huì)使您的下一輛汽車更加昂貴
- 潮起!人形機(jī)器人成本的20%-30%——靈巧手,國(guó)產(chǎn)3大廠商正快速產(chǎn)業(yè)化!
- AB Dynamics發(fā)布用于無人駕駛測(cè)試的物體檢測(cè)系統(tǒng)
- AI重構(gòu)出行:高階輔助駕駛的破局之路
- 廣汽即將發(fā)布全新星源增程技術(shù)
- Yole表示,到2030年,數(shù)據(jù)中心芯片市場(chǎng)規(guī)模將達(dá)到5000億美元
- 綠色節(jié)能趨勢(shì)下的延時(shí)繼電器發(fā)展:低功耗設(shè)計(jì)與環(huán)保材料應(yīng)用
- 國(guó)內(nèi)車企在固態(tài)電池領(lǐng)域的挑戰(zhàn)和技術(shù)方案
- 資本熱捧 + 政策護(hù)航,2025 人形機(jī)器人能否叩開 “量產(chǎn)元年” 大門?
- 耐世特推出用于智能運(yùn)動(dòng)控制的 MotionIQ?軟件套件
- TE有獎(jiǎng)活動(dòng)|如何有效應(yīng)對(duì)當(dāng)下測(cè)試測(cè)量領(lǐng)域的挑戰(zhàn)
- 下載Intel白皮書們,贏禮品獲新知
- 數(shù)據(jù)采集系統(tǒng)設(shè)計(jì)原則與基本方法
- 新春尋寶記,泰克送福利!快來開啟你的尋寶之旅~
- 喜迎新年,EE喊你搶新年福袋啦!
- TE助力數(shù)據(jù)中心設(shè)計(jì),縮短你與奧運(yùn)的距離,猜猜它屬于哪個(gè)“奧運(yùn)場(chǎng)館”贏大禮!
- 有獎(jiǎng)直播:Keysight World Tech Day 2024 汽車分論壇|汽車自動(dòng)駕駛與新能源
- 瑞薩電子顛覆傳統(tǒng)理念的嵌入式開發(fā)平臺(tái) Renesas Synergy™ 評(píng)估套件震撼來襲!答題即可免費(fèi)申請(qǐng)!
- [直播預(yù)報(bào)名] TI 最新藍(lán)牙技術(shù)培訓(xùn),2017 震撼首發(fā)!
- 【汽車電子版塊6月-聊聊汽車軟件】從AUTOSAR到軟件定義汽車
- 錘子宣布8月20日發(fā)布新機(jī):將搭載驍龍710
- 華為Mate 20 Lite渲染圖曝光:頗有保時(shí)捷設(shè)計(jì)版風(fēng)范
- 蘋果三款新iPhone有望全部支持無線充!
- 尷尬:研究發(fā)現(xiàn)很多安卓手機(jī)在開賣時(shí)就有安全漏洞
- 三星Galaxy Watch上手:生態(tài)匱乏 續(xù)航是亮點(diǎn)
- 小米手表Lite已獲BIS認(rèn)證 預(yù)計(jì)很快在印度推出
- 三星Watch 4和Apple Watch 7或?qū)⒛軠y(cè)量血糖
- 摩托羅拉Edge S真機(jī)照解密,后置矩形四攝
- STM32串口自動(dòng)識(shí)別波特率
- 三星新Exynos芯片在開發(fā)中,目標(biāo)追趕蘋果A14