【STM32F103笔记】6、Systick——做个精确的延时

【STM32F103笔记】2、单片机中的HelloWorld——流水灯中我们曾写过一个简单的延时函数,利用空操作函数__nop()并大致计算延时时间,但这个函数并不精确,有兴趣的朋友可以再把那一篇中的程序运行结果和标准时钟比较一下。

这一篇中将使用Cortex-M3内核自带的系统时钟System Time)设计精确的延时函数。

SysTick

Cortex-M3内核自带一个24位的降序计数器,也就是SysTick,通常Systick是用于给实时操作系统提供准确的滴答时钟。
在这里插入图片描述
在这里将SysTick用于精确的计时,先介绍一下2个SysTick相关的寄存器:

  • SysTick control and status register (STK_CTRL):控制和状态寄存器,下图是这个寄存器每一位的说明:
    在这里插入图片描述
    • Bit 16 COUNTFLAG:每次计数器向下自减到0的时候会自动置1,表示计数完成;
    • Bit 2 CLKSOURCE:时钟来源选择,可以看出SysTick的时钟源是AHB,在第二篇中可知,系统初始化后AHB时钟为72MHz,通过这一位可以选择AHB时钟不分频或者8分频作为Systick的时钟;
    • Bit 1 TICKINT:是否触发中断,触发中断则会进入SysTick_Handler函数(stm32f10x_it.c文件中);
    • Bit 0 ENABLE:SysTick使能位,置1则使能SysTick,开始自减计数,清0则禁用SysTick。
  • SysTick reload value register (STK_LOAD):计数器加载值寄存器,每次SysTick计数器重新开始计数时,将读取这个寄存器中的值,也就是说,计多少个数由这个寄存器控制。

由于SysTick的计数器自减操作不受其它干扰和影响,完全由其时钟决定,若时钟源选择AHB 72MHz,那么当计数器从72计数到0,相当于时间1us,因此可以使用SysTick来精确计算时间。

程序设计

程序设计思路是,首先初始化SysTick,设置固定的计数(比如720),并且每次计数完成后触发中断,这样每次触发中断就是固定的事件(10us)。

初始化SysTick——SysTick_Config库函数

同样,官方库中提供了用于SysTick配置初始化的函数:

/**
 * @brief  Initialize and start the SysTick counter and its interrupt.
 *
 * @param   ticks   number of ticks between two interrupts
 * @return  1 = failed, 0 = successful
 *
 * 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)
{
    
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   = 
### STM32F103C8T6 HAL库使用指南 #### 关于STM32F103C8T6及其HAL库简介 STM32F103C8T6是一款基于ARM Cortex-M3内核的高性能微控制器,具有丰富的外设接口。为了简化开发过程并提高代码可移植性,意法半导体提供了硬件抽象层(HAL)库来支持该系列芯片的操作[^1]。 #### 获取官方文档和支持资源的方法 开发者可以从ST官方网站下载到完整的HAL库以及配套的应用笔记和技术手册。这些材料不仅涵盖了初始化配置、GPIO操作、中断处理等方面的基础知识,还包含了更多高级特性的实现细节[^2]。 #### 示例程序展示如何利用HAL库控制LED灯闪烁 下面是一个简单的例子,展示了怎样通过调用HAL函数点亮连接至PA5引脚上的发光二极管: ```c #include "stm32f1xx_hal.h" int main(void){ // 初始化系统时钟 HAL_Init(); // 配置SysTick定时器用于延迟功能 HAL_Delay(100); // 设置GPIOA端口模式为推挽输出 __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); while (1){ // 控制LED亮起 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // 延迟一段时间 HAL_Delay(500); // 控制LED熄灭 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 再次延时等待下一次循环 HAL_Delay(500); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值