1845|5

501

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

【ST NUCLEO-U575ZI-Q 测评 】HAL/LL库使用之systick时基使用与测试 [复制链接]

前言

Systick是CORTEX-M系列单片机的标准内核外设。

一般用于时间基准,时间戳,或者rtos的滴答定时中断。

我们基于上一篇的GPIO可以测试systick的时间是否正确,在systick中断中翻转IO,用示波器/逻辑分析仪测量IO的波形周期即可测试时间是否准确。

过程

systick可以参考CORTEX-M3的内核架构文档这里不再赘述。直接看代码。

HAL库也使用了systick作为定时器,延时等操作都依赖于systick。

初始化

代码位于stm32u5xx_hal.c中的HAL_Init。

HAL_StatusTypeDef HAL_Init(void)

{

  /* Configure Flash prefetch */

#if (PREFETCH_ENABLE != 0U)

  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();

#endif /* PREFETCH_ENABLE */

 

  /* Set Interrupt Group Priority */

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

 

  /* Update the SystemCoreClock global variable */

  SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];

 

  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */

  if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)

  {

    return HAL_ERROR;

  }

 

  /* Init the low level hardware */

  HAL_MspInit();

 

  /* Return function status */

  return HAL_OK;

}

 

调用HAL_InitTick进行初始化

__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

{

  /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that don't take the value zero)*/

  if ((uint32_t)uwTickFreq == 0UL)

  {

    return HAL_ERROR;

  }

 

  /* Configure the SysTick to have interrupt in 1ms time basis*/

  if (HAL_SYSTICK_Config(SystemCoreClock / (1000UL / (uint32_t)uwTickFreq)) > 0U)

  {

    return HAL_ERROR;

  }

 

  /* Configure the SysTick IRQ priority */

  if (TickPriority < (1UL << __NVIC_PRIO_BITS))

  {

    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);

    uwTickPrio = TickPriority;

  }

  else

  {

    return HAL_ERROR;

  }

 

  /* Return function status */

  return HAL_OK;

}

 

其中定时周期由HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */定义

默认是

typedef enum

{

  HAL_TICK_FREQ_10HZ         = 100U,

  HAL_TICK_FREQ_100HZ        = 10U,

  HAL_TICK_FREQ_1KHZ         = 1U,

  HAL_TICK_FREQ_DEFAULT      = HAL_TICK_FREQ_1KHZ

} HAL_TickFreqTypeDef;

 

 

中断处理

SysTick_Handler调用HAL_IncTick更新计数器。

void SysTick_Handler(void)

{

static volatile uint32_t num = 0;

if(num++ >= 1000)

{

LL_GPIO_TogglePin(GPIOB, 1u<<7);

num=0;

}

HAL_IncTick();

}

 

测量时间

总的代码

include "stm32u575xx.h"

include "stm32u5xx_ll_gpio.h"

include "stm32u5xx_ll_bus.h"

void SysTick_Handler(void)

{

static volatile uint32_t num = 0;

if(num++ >= 1000)

{

LL_GPIO_TogglePin(GPIOB, 1u<<7);

num=0;

}

HAL_IncTick();

}

void delay(uint32_t t)

{

volatile uint32_t timeout = t;

while(t--);

}

int main(void)

{

LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);

LL_GPIO_InitTypeDef GPIO_InitStruct;

//LL_GPIO_StructInit(&GPIO_InitStruct);

GPIO_InitStruct.Pin = LL_GPIO_PIN_7;

GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;

GPIO_InitStruct.Alternate = LL_GPIO_AF_0;

LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

HAL_Init();

while(1)

{

///delay(1000000ul);

///LL_GPIO_TogglePin(GPIOB, 1u<<7);

}

}

 

使用逻辑分析仪测量,IO翻转时间为1.982917488/2=0.991458744S.

由于中断响应,执行处理代码要一定时间所以有一些误差。

 

 

总结

本篇介绍了systick的使用,测试了其准确度,后面会经常用到时间基准,延时等等。得益于官方的库,几行代码就可以搞定很高效。

此帖出自stm32/stm8论坛

最新回复

测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html   详情 回复 发表于 2023-1-12 09:42
点赞 关注
 

回复
举报

6069

帖子

4

TA的资源

版主

沙发
 

systick是个好东西。

此帖出自stm32/stm8论坛
 
 

回复

224

帖子

0

TA的资源

一粒金砂(高级)

板凳
 

学习了

不是太明白有了HAL库,为啥还要搞个LL库

移植FreeRTOS时,要屏蔽PendSV,SVHC和Systick 3个中断

此帖出自stm32/stm8论坛

点评

LL大部分是使用内联函数对寄存器操作进行封装,也就是相当于直接操作寄存器, 比HAL执行更高效,HAL和LL可以混合使用。  详情 回复 发表于 2022-12-17 09:27
 
 

回复

501

帖子

4

TA的资源

纯净的硅(高级)

4
 
starcat123 发表于 2022-12-17 00:18 学习了 不是太明白有了HAL库,为啥还要搞个LL库 移植FreeRTOS时,要屏蔽PendSV,SVHC和Systick 3个中 ...

LL大部分是使用内联函数对寄存器操作进行封装,也就是相当于直接操作寄存器,

比HAL执行更高效,HAL和LL可以混合使用。

此帖出自stm32/stm8论坛

点评

  哦,听大佬这么一解释,好像豁然开朗 inline我还是知道是怎么回事儿的,学C51的时候就有,为了更进一步优化代码速度    详情 回复 发表于 2022-12-17 15:34
 
 
 

回复

224

帖子

0

TA的资源

一粒金砂(高级)

5
 
qinyunti 发表于 2022-12-17 09:27 LL大部分是使用内联函数对寄存器操作进行封装,也就是相当于直接操作寄存器, 比HAL执行更高效,HAL和LL ...

 

哦,听大佬这么一解释,好像豁然开朗

inline我还是知道是怎么回事儿的,学C51的时候就有,为了更进一步优化代码速度

 

此帖出自stm32/stm8论坛
 
 
 

回复

1万

帖子

2854

TA的资源

管理员

6
 

测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html

此帖出自stm32/stm8论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

玩板看这里:

https://bbs.eeworld.com.cn/elecplay.html

EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表