系统(嘀嗒)定时器
2024-01-08 06:02:01
一.简介
SysTick---系统(嘀嗒)定时器,内核外设,是一个24位的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK。
当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。
系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
二.寄存器
校准寄存器一般不用。?
?三.实验(闪光灯)
编程步骤:
- 设置重装载寄存器的值;
- 清除当前数值寄存器的值;
- 配置控制与状态寄存器。
延时思路:
systick
的
counter
从
reload
值往下递减到
0
的时候,CTRL
寄存器的位
16:countflag
会置
1
,且读取该位的值可清
0
,所有我们可以使用软件查询的方法来实现延时。
?
systick.c
#include "systick.h"
#if 0
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// 判断 tick 的值是否大于 2^24,如果大于,则不符合规则
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
// 初始化reload寄存器的值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
// 配置中断优先级,配置为15,默认为最低的优先级
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
// 初始化counter的值为0
SysTick->VAL = 0;
// 配置 systick 的时钟为 72M
// 使能中断
// 使能systick
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
#endif
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72);
for(i=0; i<us; i++)
{
// 当计数器的值减小到 0 的时候,CRTL 寄存器的位 16 会置 1
while( !((SysTick->CTRL) & (1<<16)) );
}
// 关闭 SysTick 定时器
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_ms(uint32_t ms)
{
uint32_t i;
SysTick_Config(72000);
for(i=0; i<ms; i++)
{
// 当计数器的值减小到 0 的时候,CRTL 寄存器的位 16 会置 1
// 当置 1 时,读取该位会清 0
while( !((SysTick->CTRL) & (1<<16)) );
}
// 关闭 SysTick 定时器
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
SysTick 中断时间的计算:SysTick_Config(SystemCoreClock / 100000)
SysTick
定时器的计数器是向下递减计数的,计数一次的时间
T
DEC
=1/CLK
AHB
,当重装载寄存器中的值 VALUE
LOAD
减到
0
的时候,产生中断,可知中断一次的时间
T
INT
=VALUE
LOAD *
T
DEC
= VALUELOAD
/CLK
AHB
,其中
CLK
AHB
=72MHZ
。如果设置
VALUE
LOAD
为
72
,那中断一次的时间 TINT
=72/72M=1us
。不过
1us
的中断没啥意义,整个程序的重心都花在进出中断上了,根本没有时间处理其他的任务。
systick.h
#ifndef _SYSTICK_H
#define _SYSTICK_H
#include "stm32f10x.h"
#include "core_cm3.h"
void SysTick_Delay_us(uint32_t us);
void SysTick_Delay_ms(uint32_t ms);
#endif
led.c
#include "led.h"
void led_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(LED0_GPIO_CLK,ENABLE);//注意需要用到的总线
GPIO_InitStruct.GPIO_Pin = LED0_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED0_GPIO_PORT,&GPIO_InitStruct);
GPIO_ResetBits(LED0_GPIO_PORT,LED0_GPIO_PIN);
}
led.h
#ifndef _LED_H
#define _LED_H
#include "stm32f10x.h"
#define LED0_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED0_GPIO_PORT GPIOB
#define LED0_GPIO_PIN GPIO_Pin_5
/******************************************************************************************/
/* LED端口定义 */
#define LED0(x) do{ x ? \
GPIO_SetBits(LED0_GPIO_PORT, LED0_GPIO_PIN) : \
GPIO_ResetBits(LED0_GPIO_PORT, LED0_GPIO_PIN); \
}while(0) /* LED0翻转 */
#define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态
#define LED0_Toggle digitalToggle(LED0_GPIO_PORT,LED0_GPIO_PIN)
void led_gpio_init(void);
#endif
main.c
#include "stm32f10x.h"
#include "led.h"
#include "systick.h"
int main()
{
// 来到这里的时候,系统的时钟已经被配置成72M。
led_gpio_init();
while(1)
{
LED0(1);
SysTick_Delay_ms(500);
LED0(0);
SysTick_Delay_ms(500);
}
}
文章来源:https://blog.csdn.net/m0_58575898/article/details/135347796
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!