《《《《《正文》》》》》
建议先看SYStick的原理请看:
下面做一个基于systick的延时模块开发:
第一步:当然是时钟的选择,配置函数在misc.c中:
/**
* @brief Configures the SysTick clock source.
* @param SysTick_CLKSource: specifies the SysTick clock source.
* This parameter can be one of the following values:
* @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
* @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
* @retval None
*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
/* Check the parameters */
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
{
SysTick->CTRL |= SysTick_CLKSource_HCLK;
}
else
{
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
}
}
可以看到有2个参数:
第一个是内核时钟的8分频,另一个是外部时钟。
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
我们配置为内核时钟的8分频,并且内核时钟为72Mhz:
初始化函数如下代码:
/****************************************************************************************************
* 函 数: void Delay_Init(void)
* 功 能: 延时函数初始化
* 参 数: 无
* 返回值:无
* 备 注: T(s) = 1/F(Hz) //赫兹时间转换公式
****************************************************************************************************/
void Delay_Init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//先8分频再除以1000000转化为us单位,1us的计数值
D_us = SystemCoreClock/8000000;
D_ms = (uint16_t)D_us * 1000; //1ms的计数值
}
其中的SystemCoreClock如下:
第二步:写us延时函数:
/****************************************************************************************************
* 函 数: void Delay_us(uint32_t nus)
* 功 能: 微秒级延时
* 参 数: nus 传入微秒参数
* 返回值:无
* 备 注: LOAD为24位寄存器,nus 的最大传入值为 2的24次方(0xFFFFFF)/ D_us(9) = 1864135 us
****************************************************************************************************/
void Delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->LOAD = nus*D_us; //延时重装载值
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL|= 0x01 ; //启动SysTick定时器
do
{
temp=SysTick->CTRL;
//这里的(1<<16指CTRL的第16位,是倒计到0时会置1)
}while((temp&0x01)&&!(temp&(1<<16))); //等待延时结束
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->VAL = 0X00; //清空计数器
}
第三步:写ms延时函数:
/****************************************************************************************************
* 函 数: void Delay_ms(uint32_t nms)
* 功 能: 毫秒级延时
* 参 数: nms 传入微秒参数
* 返回值:无
* 备 注: LOAD为24位寄存器,nms 的最大传入值为 2的24次方(0xFFFFFF)/ D_ms(9) = 1864 ms
****************************************************************************************************/
void Delay_ms(uint32_t nms)
{
uint32_t temp;
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->LOAD = nms*D_ms; //延时重装载值
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL|= 0x01 ; //启动SysTick定时器
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待延时结束
SysTick->CTRL = 0x00; //关闭SysTick定时器
SysTick->VAL = 0X00; //清空计数器
}
《《《《《END》》》》》