1.定时与计数的本质
2.滴答定时器的原理
1.向下计数,24位的计数器。滴答定时器属于内核。
每来一个脉冲计数值减一。当为零时。继续把重载寄存器给计数值。然后每来一个脉冲减一。
可以不停重复次操作。
控制寄存器:时钟的选择(bit2),是否开启中断(bit1),滴答定时器是否使能(bit0)
COUNTFLG(bit16)当计数值为0改为为1,当重新把重载寄存器给计数器。改为为0。
3.代码实现
systick.h
#ifndef SYSTICK_H
#define SYSTICK_H
#include <stdint.h>
/* configure systick */
void systick_config(void);
/* delay a time in milliseconds */
void inter_1ms(uint32_t count);
/* delay decrement */
void delay_decrement(void);
#endif /* SYSTICK_H */
systick.c
#include "gd32f10x.h"
#include "systick.h"
#include "LED.h"
volatile static uint32_t delay_reload;
volatile static uint32_t delay_value;
/*!
\brief configure systick
\param[in] none
\param[out] none
\retval none
*/
void systick_config(void)
{
/* setup systick timer for 1000Hz interrupts */
if (SysTick_Config(SystemCoreClock / 1000U)){
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
/*!
\brief delay a time in milliseconds
\param[in] count: count in milliseconds
\param[out] none
\retval none
*/
void inter_1ms(uint32_t count)
{
delay_reload = count;
delay_value = delay_reload;
}
/*!
\brief delay decrement
\param[in] none
\param[out] none
\retval none
*/
void delay_decrement(void)
{
if (0U != delay_value){
delay_value--;
}else{
LED1_Toggle();
LED2_Toggle();
delay_value = delay_reload;
}
}
void SysTick_Handler(void)
{
delay_decrement();
}
SysTick_Config函数是在core_cm3.h里
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* 重载值不是大于2的24次方 */
SysTick->LOAD = ticks - 1; /* 设置重载值 */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* 清零计数值 */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | /* 滴答定时器时钟 */
SysTick_CTRL_TICKINT_Msk | /* 开启中断 */
SysTick_CTRL_ENABLE_Msk; /* 使能定时器 */
return (0); /* Function successful */
}
重载值是根据定时的时间来的:
每一次计数值减一是:1 / SystemCoreClock(频率)秒 转成毫秒:1000/SystemCoreClock.
这时计数值*1000/SystemCoreClock时间。因为计数值是重载值赋值的。
所以重载值*1000/SystemCoreClock 而重载值 SystemCoreClock / 1000 (SysTick_Config调用传递的)
两个相乘就是1ms。每一毫秒计数值为0.然后重载值又给计数值这样循环往复。
main.c
#include "LED.h"
#include "systick.h"
int main(){
LED_Init();
systick_config();
inter_1ms(1000);
while(1){
;
}
}