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.
126 lines
3.6 KiB
126 lines
3.6 KiB
2 days ago
|
/**
|
||
|
* @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++;
|
||
|
}
|
||
|
}
|
||
|
}
|