需要对系统时钟进行初始化,时钟树一般不做分频都是72M赫兹工作,那么此处对于延时函数的初始化,对系统时钟进行8分频,使得时钟9M计时。
uint16_t g_fac_us;
void Delay_Init(uint16_t systclk)
{
SysTick->CTRL=0;
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
g_fac_us = systclk/8;//9M速度计时
}
下面是微妙延时的函数,由于9Mhz的时钟计时1us需要9次,所以初始化时候计算得到的g_fac_us变量就是为9,因此此处只需要将延时的us数值乘以g_fac_us即可得到延时nus需要的计数值,将其传递给LOAD寄存器进行计时器计数值装载。同时再当前计数值清零0,CTRL的第一位置为1启动计时,计时过程中CTRL最低位时钟为1,等待计时完成则,CTRL第16就为1,进行一个while判断退出计时。然后再关闭时钟计时实能完成计时。
void delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->LOAD=nus*g_fac_us;
SysTick->VAL=0x00;
SysTick->CTRL|=1<<0;
do{
temp = SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~(1<<0);
SysTick->VAL=0x00;
}
接下来的ms延时函数,除了可以使用hal自带的HAL_Delay,我们也可以根据我们编写的us延时函数进行,代码如下。
void delay_ms(uint16_t nms)
{
uint32_t repeat = nms/1000;
uint32_t remain = nms%1000;
while(repeat)
{
delay_us(1000*1000);
repeat--;
}
if(remain)
{
delay_us(remain*1000);
}
}
上面代码对于小于1s的可以直接计算,大于一秒的先取整进行一个delay_us(1000*1000),然后再取余进行一个小数位的延时。
使用STLINK连接stm32,将时钟设置为72M。
点击STLINKdebug,首先将延时函数初始化传入参数72,然后调用500ms延时,同时打一个断点,点击运行程序。
观察运行到断点后时候为0.12多,接着跳出延时观察时间
大概为0.62,满足500ms延时,完成了一个延时简单测试。