[技术问答] 华大MCU HC32F460 Systick

[复制链接]
 楼主| binoo7 发表于 2021-1-18 16:47 | 显示全部楼层 |阅读模式
这次来和大家一起学习华大MCU HC32F460 Systick部分,这部分其实华大给的PDF文档里的内容很少,但是我在例程看到了相关的内容,跟大家一起分享一下吧,废话不多说,开始喽

  1. /**
  2. *******************************************************************************
  3. ** \brief SysTick interrupt callback function.
  4. **
  5. ** \param None
  6. **
  7. ** \retval None
  8. **
  9. ******************************************************************************/
  10. void SysTick_IrqHandler(void)
  11. {
  12.     SysTick_IncTick();
  13. }
开始,打开工程就看到了一个这个,这是啥,也太简单了吧





 楼主| binoo7 发表于 2021-1-18 17:35 | 显示全部楼层
本帖最后由 binoo7 于 2021-1-18 17:37 编辑

别着急,我继续更新
  1. /**
  2. *******************************************************************************
  3. ** \brief This function is called to increment a global variable "u32TickCount".
  4. ** \note  This variable is incremented in SysTick ISR.
  5. **
  6. ** \param None
  7. **
  8. ** \retval None
  9. **
  10. ******************************************************************************/
  11. __WEAKDEF void SysTick_IncTick(void)
  12. {
  13.     m_u32TickCount += m_u32TickStep;
  14. }

这个其实里面就是对一个全局变量进行赋值
 楼主| binoo7 发表于 2021-1-18 17:38 | 显示全部楼层
本帖最后由 binoo7 于 2021-1-18 17:46 编辑

/* SysTick configuration */
    SysTick_Init(1000u);
这个函数是初始化Systick
  1. /**
  2. *******************************************************************************
  3. ** \brief This function Initializes the interrupt frequency of the SysTick.
  4. **
  5. ** \param [in] u32Freq                 SysTick interrupt frequency (1 to 1000).
  6. **
  7. ** \retval Ok                          SysTick Initializes succeed
  8. ** \retval Error                       SysTick Initializes failed
  9. **
  10. ******************************************************************************/
  11. __WEAKDEF en_result_t SysTick_Init(uint32_t u32Freq)
  12. {
  13.     en_result_t enRet = Error;

  14.     if ((0UL != u32Freq) && (u32Freq <= 1000UL))
  15.     {
  16.         m_u32TickStep = 1000UL / u32Freq;
  17.         /* Configure the SysTick interrupt */
  18.         if (0UL == SysTick_Config(SystemCoreClock / u32Freq))
  19.         {
  20.             enRet = Ok;
  21.         }
  22.     }

  23.     return enRet;
  24. }


仔细分析一下这个函数
这函数的关键是这里
SysTick_Config(SystemCoreClock / u32Freq)
这是什么意思啊,再次打开 SysTick_Config这个函数看一下
  1. /* ##################################    SysTick function  ############################################ */
  2. /**
  3.   \ingroup  CMSIS_Core_FunctionInterface
  4.   \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
  5.   \brief    Functions that configure the System.
  6.   @{
  7. */

  8. #if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)

  9. /**
  10.   \brief   System Tick Configuration
  11.   \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
  12.            Counter is in free running mode to generate periodic interrupts.
  13.   \param [in]  ticks  Number of ticks between two interrupts.
  14.   \return          0  Function succeeded.
  15.   \return          1  Function failed.
  16.   \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
  17.            function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
  18.            must contain a vendor-specific implementation of this function.
  19. */
  20. __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
  21. {
  22.   if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  23.   {
  24.     return (1UL);                                                   /* Reload value impossible */
  25.   }

  26.   SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
  27.   NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  28.   SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  29.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
  30.                    SysTick_CTRL_TICKINT_Msk   |
  31.                    SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  32.   return (0UL);                                                     /* Function successful */
  33. }

  34. #endif




评论

SysTick_Config 这个函数默认是屏蔽的。官方的专门的 嘀嗒定时器里程居然也是屏蔽的。 那么疑问就来了 没有这个函数的定义 编译为啥不报错?  发表于 2022-11-28 16:52
 楼主| binoo7 发表于 2021-1-18 17:47 | 显示全部楼层
本帖最后由 binoo7 于 2021-1-18 18:03 编辑
  1. /**
  2.   \brief  Structure type to access the System Timer (SysTick).
  3. */
  4. typedef struct
  5. {
  6.   __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  7.   __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  8.   __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  9.   __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
  10. } SysTick_Type;

看到上一个初始化是怎么做的了吧,就是给SysTick结构体里的内容赋值,
  1. #define MRC_VALUE ((uint32_t)8000000)   /*!< Internal middle speed RC freq. */
初始化的时候用到了一个时钟的一个全局变量,这个变量的赋值是根据这个数来的,8000000就是8M的内部中速时钟频率

 楼主| binoo7 发表于 2021-1-18 19:10 | 显示全部楼层
  1. /**
  2. *******************************************************************************
  3. ** \brief This function provides minimum delay (in milliseconds).
  4. **
  5. ** \param [in] u32Delay                Delay specifies the delay time.
  6. **
  7. ** \retval None
  8. **
  9. ******************************************************************************/
  10. __WEAKDEF void SysTick_Delay(uint32_t u32Delay)
  11. {
  12.     const uint32_t tickStart = SysTick_GetTick();
  13.     uint32_t tickEnd;
  14.     uint32_t tickMax;

  15.     if (m_u32TickStep != 0UL)
  16.     {
  17.         tickMax = 0xFFFFFFFFUL / m_u32TickStep * m_u32TickStep;
  18.         /* Add a freq to guarantee minimum wait */
  19.         if ((u32Delay >= tickMax) || ((tickMax - u32Delay) < m_u32TickStep))
  20.         {
  21.             tickEnd = tickMax;
  22.         }
  23.         else
  24.         {
  25.             tickEnd = u32Delay + m_u32TickStep;
  26.         }

  27.         while ((SysTick_GetTick() - tickStart) < tickEnd)
  28.         {
  29.         }
  30.     }
  31. }

这是延时函数,一直在判断设定时间是否与延时的时间是否相同,如果达到后就停止,如果不相同就一直等待,没有用到Systick的中断

评论

这个 嘀嗒定时器 官方 注明了 最大频率 1000Hz “ SysTick interrupt frequency (1 to 1000). “ 没办法微妙级延时吗  发表于 2022-11-28 16:54
 楼主| binoo7 发表于 2021-1-18 19:20 | 显示全部楼层
STM32是怎么做的呢?下面讲解一下正点原子的方法
  1. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK/8
  2.         fac_us=SystemCoreClock/8000000;                                //为系统时钟的1/8  
  1. fac_ms=(u16)fac_us*1000;                                        //非OS下,代表每个ms需要的systick时钟数   
  1. void delay_us(u32 nus)
  2. {               
  3.         u32 temp;                     
  4.         SysTick->LOAD=nus*fac_us;                                         //时间加载                           
  5.         SysTick->VAL=0x00;                                                //清空计数器
  6.         SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数          
  7.         do
  8.         {
  9.                 temp=SysTick->CTRL;
  10.         }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
  11.         SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
  12.         SysTick->VAL =0X00;                                               //清空计数器         
  13. }
  14. //延时nms
  15. //注意nms的范围
  16. //SysTick->LOAD为24位寄存器,所以,最大延时为:
  17. //nms<=0xffffff*8*1000/SYSCLK
  18. //SYSCLK单位为Hz,nms单位为ms
  19. //对72M条件下,nms<=1864
  20. void delay_ms(u16 nms)
  21. {                                     
  22.         u32 temp;                  
  23.         SysTick->LOAD=(u32)nms*fac_ms;                                //时间加载(SysTick->LOAD为24bit)
  24.         SysTick->VAL =0x00;                                                        //清空计数器
  25.         SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数  
  26.         do
  27.         {
  28.                 temp=SysTick->CTRL;
  29.         }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
  30.         SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
  31.         SysTick->VAL =0X00;                                               //清空计数器                      
  32. }
xyz549040622 发表于 2021-1-18 22:10 来自手机 | 显示全部楼层
支持下,,谢谢分享。
麻花油条 发表于 2021-1-19 15:22 | 显示全部楼层
很棒,支持下
wwppd 发表于 2022-12-1 17:10 | 显示全部楼层
hc32f460中,systick具体延时时间怎么计算的?
51xlf 发表于 2022-12-1 19:13 | 显示全部楼层
是否有Systick工程文件可以借鉴呢?
mattlincoln 发表于 2022-12-1 19:42 | 显示全部楼层
HC32F460 怎么开启systick定时器
caigang13 发表于 2022-12-1 19:55 来自手机 | 显示全部楼层
和某T的很像啊
ulystronglll 发表于 2022-12-1 20:13 | 显示全部楼层
能不能把Systick帖子整合一下?
lzbf 发表于 2022-12-1 21:15 | 显示全部楼层
systick中断逻辑包括哪些?     
iyoum 发表于 2022-12-1 22:06 | 显示全部楼层
Systick允许的最长和最短定时是多少?  
mikewalpole 发表于 2022-12-2 19:30 | 显示全部楼层
SysTick的优先级是高还是低?  
ccook11 发表于 2022-12-2 20:12 | 显示全部楼层
HC32F460 如何使用Systic(库函数)
bartonalfred 发表于 2022-12-6 13:20 | 显示全部楼层
Systick的精度怎么样              
earlmax 发表于 2022-12-6 14:20 | 显示全部楼层
为什么芯片不多设计一个定时器,而要添加Systick呢?
janewood 发表于 2022-12-6 15:01 | 显示全部楼层
感觉Systick比定时器差太多了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

457

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部

49

主题

457

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部