You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

125 lines
3.6 KiB

/**
* @file delay.c
* @author Nations
* @version v1.0.0
*
* @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
*/
#include "delay.h"
#include <stdio.h>
/**
* @brief 基于SysTick定时器的微秒级延时函数
*
* @param nus 延时的微秒数
*
* @note 该函数使用SysTick定时器实现微秒级的延时。它首先配置SysTick定时器使用系统时钟,
* 然后根据需要延时的微秒数和系统核心时钟计算重载值,开始倒计时,并在每次循环中读取
* 定时器的控制寄存器值,直到倒计时结束。延时结束后,关闭定时器并清除其值。
*/
void systick_delay_us(u32 nus)
{
u32 temp;
// 选择系统时钟作为SysTick定时器的时钟源
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
// 根据需要延时的微秒数和系统核心时钟计算SysTick定时器的重载值
SysTick->LOAD=nus*(SystemCoreClock/1000000);
// 清除SysTick定时器的当前值
SysTick->VAL=0x00;
// 启动SysTick定时器的倒计时
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
// 等待直到SysTick定时器倒计时结束
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));
// 关闭SysTick定时器的倒计时
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
// 再次清除SysTick定时器的当前值
SysTick->VAL =0X00;
}
/**
* @brief 延时指定的毫秒数
*
* 本函数通过SysTick定时器实现精确的毫秒级延时。在延时期间,处理器将进入等待状态,
* 直到SysTick定时器计数达到预设的毫秒数。此函数阻塞程序的执行直到延时结束。
*
* @param nms 要延时的毫秒数
*/
void systick_delay_ms(u16 nms)
{
u32 temp;
// 选择系统时钟作为SysTick定时器的时钟源
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
// 根据输入的毫秒数和系统时钟频率计算SysTick定时器的重载值
// 注意SysTick->LOAD是24位的
SysTick->LOAD=(u32)nms*((SystemCoreClock/1000000)*1000);
// 清除SysTick定时器的当前值,即重置计数器
SysTick->VAL =0x00;
// 启动SysTick定时器计数
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
// 等待直到延时结束
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16))); // 检查定时器状态,确保延时完成
// 关闭SysTick定时器计数
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
// 再次清除定时器值,为下一次延时做准备
SysTick->VAL =0X00;
}
// void delay_ms(u16 nms)
// {
// u16 count = nms/100;
// while(count--) {
// systick_delay_ms(100);
// }
// systick_delay_ms(nms%100);
// }
/**
* delay_ms_test函数用于实现指定毫秒数的延时。
*
* @param nms 延时的毫秒数。
*
* 该函数通过编译级的忙等待实现延时,适合于对延时精度要求不高的场合。
* 注意:这种延时方法并不是精确的延时,其延时的精度会受到处理器速度和当前负载的影响。
*/
void delay_ms(u16 nms)
{
// 初始化计数变量
u16 i = 0, j = 0, k = 0;
// 设置计数变量i,j,k的初始值
i = 0;
j = 0;
k = 0;
// 根据指定的毫秒数nms进行延时
for(i = 0; i < nms; i++) {
k = 0;
// 内层循环用于增加延时的总循环次数,以达到近似的延时效果
for(j = 0; j < 9600; j++) {
k++;
}
}
}