qinyunti 发表于 2022-12-14 17:52

【ST NUCLEO-U575ZI-Q 测评 】HAL/LL库使用之systick时基使用与测试

<h1><b>前言</b></h1>

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

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

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

<h1 ><b>过程</b></h1>

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

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

<h2 ><b>初始化</b></h2>

<p >代码位于stm32u5xx_hal.c中的HAL_Init。</p>

<div class="parsedown-markdown">
<p>HAL_StatusTypeDef HAL_Init(void)</p>

<p >{</p>

<p >&nbsp;&nbsp;/* Configure Flash prefetch */</p>

<p >#if (PREFETCH_ENABLE != 0U)</p>

<p >&nbsp;&nbsp;__HAL_FLASH_PREFETCH_BUFFER_ENABLE();</p>

<p >#endif /* PREFETCH_ENABLE */</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Set Interrupt Group Priority */</p>

<p >&nbsp;&nbsp;HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Update the SystemCoreClock global variable */</p>

<p >&nbsp;&nbsp;SystemCoreClock = HAL_RCC_GetSysClockFreq() &gt;&gt; AHBPrescTable[(RCC-&gt;CFGR2 &amp; RCC_CFGR2_HPRE) &gt;&gt; RCC_CFGR2_HPRE_Pos];</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */</p>

<p >&nbsp;&nbsp;if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)</p>

<p >&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;return HAL_ERROR;</p>

<p >&nbsp;&nbsp;}</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Init the low level hardware */</p>

<p >&nbsp;&nbsp;HAL_MspInit();</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Return function status */</p>

<p >&nbsp;&nbsp;return HAL_OK;</p>

<p >}</p>
</div>

<p >&nbsp;</p>

<p >调用HAL_InitTick进行初始化</p>

<div class="parsedown-markdown">
<p>__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)</p>

<p >{</p>

<p >&nbsp;&nbsp;/* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that don&#39;t take the value zero)*/</p>

<p >&nbsp;&nbsp;if ((uint32_t)uwTickFreq == 0UL)</p>

<p >&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;return HAL_ERROR;</p>

<p >&nbsp;&nbsp;}</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Configure the SysTick to have interrupt in 1ms time basis*/</p>

<p >&nbsp;&nbsp;if (HAL_SYSTICK_Config(SystemCoreClock / (1000UL / (uint32_t)uwTickFreq)) &gt; 0U)</p>

<p >&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;return HAL_ERROR;</p>

<p >&nbsp;&nbsp;}</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Configure the SysTick IRQ priority */</p>

<p >&nbsp;&nbsp;if (TickPriority &lt; (1UL &lt;&lt; __NVIC_PRIO_BITS))</p>

<p >&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;uwTickPrio = TickPriority;</p>

<p >&nbsp;&nbsp;}</p>

<p >&nbsp;&nbsp;else</p>

<p >&nbsp;&nbsp;{</p>

<p >&nbsp;&nbsp;&nbsp;&nbsp;return HAL_ERROR;</p>

<p >&nbsp;&nbsp;}</p>

<p >&nbsp;</p>

<p >&nbsp;&nbsp;/* Return function status */</p>

<p >&nbsp;&nbsp;return HAL_OK;</p>

<p >}</p>
</div>

<p >&nbsp;</p>

<p >其中定时周期由HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; &nbsp;/* 1KHz */定义</p>

<p >默认是</p>

<div class="parsedown-markdown">
<p>typedef enum</p>

<p >{</p>

<p >&nbsp;&nbsp;HAL_TICK_FREQ_10HZ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 100U,</p>

<p >&nbsp;&nbsp;HAL_TICK_FREQ_100HZ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 10U,</p>

<p >&nbsp;&nbsp;HAL_TICK_FREQ_1KHZ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 1U,</p>

<p >&nbsp;&nbsp;HAL_TICK_FREQ_DEFAULT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= HAL_TICK_FREQ_1KHZ</p>

<p >} HAL_TickFreqTypeDef;</p>
</div>

<p >&nbsp;</p>

<p >&nbsp;</p>

<h2 ><b>中断处理</b></h2>

<p >SysTick_Handler调用HAL_IncTick更新计数器。</p>

<div class="parsedown-markdown">
<p>void SysTick_Handler(void)</p>

<p>{</p>

<p>static volatile uint32_t num = 0;</p>

<p>if(num++ &gt;= 1000)</p>

<p>{</p>

<p>LL_GPIO_TogglePin(GPIOB, 1u&lt;&lt;7);</p>

<p>num=0;</p>

<p>}</p>

<p>HAL_IncTick();</p>

<p>}</p>
</div>

<p >&nbsp;</p>

<h2 ><b>测量时间</b></h2>

<p >总的代码</p>

<div class="parsedown-markdown">
<h1>include &quot;stm32u575xx.h&quot;</h1>

<h1>include &quot;stm32u5xx_ll_gpio.h&quot;</h1>

<h1>include &quot;stm32u5xx_ll_bus.h&quot;</h1>

<p>void SysTick_Handler(void)</p>

<p>{</p>

<p>static volatile uint32_t num = 0;</p>

<p>if(num++ &gt;= 1000)</p>

<p>{</p>

<p>LL_GPIO_TogglePin(GPIOB, 1u&lt;&lt;7);</p>

<p>num=0;</p>

<p>}</p>

<p>HAL_IncTick();</p>

<p>}</p>

<p>void delay(uint32_t t)</p>

<p>{</p>

<p>volatile uint32_t timeout = t;</p>

<p>while(t--);</p>

<p>}</p>

<p>int main(void)</p>

<p>{</p>

<p>LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);</p>

<p>LL_GPIO_InitTypeDef GPIO_InitStruct;</p>

<p>//LL_GPIO_StructInit(&amp;GPIO_InitStruct);</p>

<p>GPIO_InitStruct.Pin = LL_GPIO_PIN_7;</p>

<p>GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;</p>

<p>GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;</p>

<p>GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;</p>

<p>GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;</p>

<p>GPIO_InitStruct.Alternate = LL_GPIO_AF_0;</p>

<p>LL_GPIO_Init(GPIOB, &amp;GPIO_InitStruct);</p>

<p>HAL_Init();</p>

<p>while(1)</p>

<p>{</p>

<p>///delay(1000000ul);</p>

<p>///LL_GPIO_TogglePin(GPIOB, 1u&lt;&lt;7);</p>

<p>}</p>

<p>}</p>
</div>

<p >&nbsp;</p>

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

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

<p > &nbsp;</p>

<p >&nbsp;</p>

<h1 ><b>总结</b></h1>

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

damiaa 发表于 2022-12-15 10:00

<p>systick是个好东西。</p>

starcat123 发表于 2022-12-17 00:18

<p>学习了</p>

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

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

qinyunti 发表于 2022-12-17 09:27

starcat123 发表于 2022-12-17 00:18
学习了

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

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

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

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

starcat123 发表于 2022-12-17 15:34

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

比HAL执行更高效,HAL和LL ...

<p>&nbsp;</p>

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

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

<p>&nbsp;</p>

okhxyyo 发表于 2023-1-12 09:42

<p>测评汇总:免费申请|ST NUCLEO-U575ZI-Q https://bbs.eeworld.com.cn/thread-1228653-1-1.html</p>
页: [1]
查看完整版本: 【ST NUCLEO-U575ZI-Q 测评 】HAL/LL库使用之systick时基使用与测试