蓝桥杯嵌入式之Systick

前言:

SysTick可以给系统提供一个单独的时钟节拍(时基),并且HAL_Delay函数也是用他来进行精准延时,所有理论上可以用其作为定时器来用。这里我不会讲太多原理,就提出大致的配置步骤,对于蓝桥杯来说具体的意义我们可以不做过多了解。(后续所有模块都会写一下文章和代码,各位大大可以点个关注以免走丢)

功能:

1.SysTick是CM4内核的系统定时器,是一个24位的向下递减计数器,理论上可以计数2^24个值,当重装载寄存器的值减为0时就产生一次中断
2.STMCubeMX生成的工程,把Systick配置成1ms中断的定时器,并在中断函数里,将变量uwTick每1ms增加1

时钟配置:

虽然说外部时钟一般比内部时钟精准,不过现在来说各大厂商的内部晶振做的也都很ok,所以我个人喜欢用内部时钟进行设置

在这里插入图片描述
首先我们可以看到外部时钟是24MHZ,所有CubeMX的外部时钟我们设置为24
在这里插入图片描述
系统主频这块,我们可以发现,选择HSI或者HSE,系统的主频会是16MHZ或24MHZ,因为后续的任务可能需要更高的主频,所有我们需要选择第三个PLLCLK,来进行分频处理,以此提高主频,按照蓝桥杯官方例子,一般习惯设置为80MHZ
在这里插入图片描述
设置好主频时钟后就可以来生成代码了,我们接下来讲解SysTick时钟原理。首先跳转HAL_Init();

在这里插入图片描述
这里是使用SysTick作为基准时间源,并配置1ms tick(重置后的默认时钟为HSI)
在这里插入图片描述

if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) == 0U)语句作用是
配置SysTick在1ms的时间基础上中断

在这里插入图片描述

通过配置LOAD的寄存器来控制1ms定时,ticks-1UL因为ticks减到零再继续减就会溢出,这里还设置了中断优先级,装载初值等,了解一下即可,总之,通过配置这些参数来实现1ms定时中断的效果。

在这里插入图片描述
而SysTick定时中断会进行相应的中断函数
在这里插入图片描述

具体就是把变量uwTick += uwTickFreq,其中uwTickFreq的值默认设置的就是1,当然你也可以跳转到宏定义的地方去修改,这里就不去跳转了。
在这里插入图片描述

到这里,我们可以来看一看延时函数,它就是利用变量uwTick来进行延时,用while死等,所以造成了cpu空跑。我们完全可以用uwTick变量来进行自己想要的定时,其中HAL_GetTick()的返回值就是uwTick。
在这里插入图片描述
在这里插入图片描述
下面就用一个例子来实践一下,在LED_Process()里面,如果不到500ms,函数就会一直执行return;达到条件后会记住当前uwTick的值,为下一个500ms做判断。

main.c文件


void LED_Control(u8 led_ctrl)
{
 // HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOC, 0xff00, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  
   HAL_GPIO_WritePin(GPIOC, led_ctrl<<8, GPIO_PIN_RESET);
   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}


void LED_Process(void)
{
  if(uwTick - ledTick < 500)return; //每0.5s不满足if条件,跳过return
  ledTick = uwTick;                 //将此时的uwTick赋值给ledTick,记住新的值
  LED_Control(led_ctrl);            //点亮LED
  led_ctrl = ~led_ctrl;  
}

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  LCD_Init();
  while (1)
  {
   LED_Process();
  }
  
 }

效果展示:

在这里插入图片描述

  • 47
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值