測試這個延時函數1us示波器看實際是3.多us,時鐘頻率填的72,請教一下這樣的誤差正常嗎,,超過10us以上誤差基本還算正常
單片機源程序如下:
#include "delay.h"
/*
適用于STM32F407系列
*/
static uint8_t fac_us=0; //us延時倍乘數
static uint16_t fac_ms=0; //ms延時倍乘數,在os下,代表每個節拍的ms數
//初始化延遲函數
//SYSTICK的時鐘固定為AHB時鐘的1/8
//SYSCLK:系統時鐘頻率
void delay_init(uint8_t SYSCLK)
{
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8); //SYSTICK_CLKSOURCE_HCLK_DIV8////SYSTICK_CLKSOURCE_HCLK
fac_us=SYSCLK/8; //不論是否使用OS,fac_us都需要使用
fac_ms=(uint16_t)fac_us*1000; //非OS下,代表每個ms需要的systick時鐘數
}
/****************************
** 定時us
** nus: 需要定時的微秒數
**延時nus
**nus為要延時的us數.
**注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21)
*****************************/
void delay_us(int32_t nus)
{
uint32_t temp;
SysTick->LOAD=nus*fac_us; //時間加載
SysTick->VAL=0x00; //清空計數器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //開始倒數
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待時間到達
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}
//延時nms
//注意nms的范圍
//SysTick->LOAD為24位寄存器,所以,最大延時為:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK單位為Hz,nms單位為ms
//對168M條件下,nms<=798ms
void delay_xms(uint16_t nms)
{
uint32_t temp;
SysTick->LOAD=(uint32_t)nms*fac_ms; //時間加載(SysTick->LOAD為24bit)
SysTick->VAL =0x00; //清空計數器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //開始倒數
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待時間到達
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}
/****************************
** 定時ms
** nms: 需要定時的毫秒數
*****************************/
void delay_ms(int32_t nms)
{
uint8_t repeat=nms/540; //這里用540,是考慮到某些客戶可能超頻使用,
//比如超頻到248M的時候,delay_xms最大只能延時541ms左右了
uint16_t remain=nms%540;
while(repeat)
{
delay_xms(540);
repeat--;
}
if(remain)delay_xms(remain);
}
|