SysTick简介、功能框图讲解、SysTick定时实验讲解
SysTick:系统滴答定时器,24位,只能递减,存在于内核中,嵌套在NVIC中,所有的Cortex-M内核的单片机都具有这个定时器。
(内核中的外设)
功能框图:STK_CLK(72M/9M) -》STK_VAL递减计数器
^
|
STK_LOAD重装载寄存器
递减计数器counter在时钟的驱动下,从reload初值开始往下递减计数到0,
产生中断和置位COUNTFLAG标志了然后又从reload值开始重新递减,如此循环。
SysTick中的几个寄存器:
SysTick控制及状态寄存器CTRL:
位段 名称 类型 复位值 描述
16 COUNTFLAG R/W 0 如果上次读取本寄存器后,SysTick已经到了0,则该位位1
2 CLKSOURCE R/W 0 时钟源选择位,0=AHB/8,1=处理器时钟AHB72M
(就是说,SysTick的CTRL寄存器中的第16位,如果为1,说明上次读取数值后Systick有到了0了,完成一次tick滴答了)
SysTick重装载数值寄存器LOAD:
位段 名称 类型 复位值 描述
23:0 RELOAD R/W 0 当倒数计数至0,将被重新装载赋值
SysTick当前数值寄存器VAL:
位段 名称 类型 复位值 描述
23:0 CURRENT R/W 0 读取时返回当前倒计数的值,写它则是指清零
Systick定时时间计算:
1-t:一个计数循环时间,跟reload和CLK有关
2-CLK:72M或者9M,由CTRL寄存器配置
3-RELOAD:24位,用户自己配置
t=reload*(1/clk)
clk=72M 时,t=72 * (1/72M) = 1us 微妙
clk=72M 时,t=7200 * (1/72M) = 1ms 毫秒
1s = 10^3ms = 10^6us = 10^9ns
SysTick属于内核的外设,它的中断优先级和片上的外设的中断优先级相比,哪一个高?
答:根据中断向量表查看中断优先级;
中断优先级的分组队内核和外设同样适用。当比较的时候,
只需要把内核外设的中断优先级的四个位按照外设的中断优先级来
分组即可,即人为的分出【抢占优先级】和【子优先级】
实验:编写微秒级的延时函数 LED闪烁
固件库函数:
/**
* @brief Initialize and start the SysTick counter and its interrupt.
* 简述:初始化并且开启系统滴答定时器及其中断
* @param ticks number of ticks between two interrupts
参数: ticks :两次中断的滴答数
* @return 1 = failed, 0 = successful
返回值:1=失败,0=成功
*
* Initialise the system tick timer and its interrupt and start the
* system tick timer / counter in free running mode to generate
* periodical interrupts.
初始化系统计时器及其中断,并在自由运行模式下
启动系统计时计时器/计数器,以生成周期性中断
*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
//判断tick的值是否大于2^24,如果大于,则不符合规则
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
//初始化reload寄存器的值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
//配置中断优先级,配置为15,默认为最底的优先级
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
//初始化counter的值为0
SysTick->VAL = 0; /* Load the SysTick Counter Value */
//配置systick的时钟为72M;使能中断;使能systick开始计数
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
自己编写函数:
/*
* param:us:微妙数,us=1000,则该函数产生一个1000us的延时
*/
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72);
for(i = 0 ;i < us;i++)
{
//counter会从reload的值下减到0
//当计数器的值减小到0的时候,CTRL寄存器的16位会置1,
//循环判断SysTick的CTRL的16位是否为1 ,如果是,则说明达到1微妙,跳出循环
while( !((SysTick->CTRL) & (1<<16)) );
}
//跳出循环说明时间到,SysTick清零
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
【STM32】F103学习笔记:SysTick
猜你喜欢
转载自blog.csdn.net/zDavid_2018/article/details/103783160
今日推荐
周排行