搜索

[技术问答] 华大MCU HC32F460 Systick

[复制链接]
164|7
 楼主 | 2021-1-18 16:47 | 显示全部楼层 |阅读模式
ck, HC, ic, tc
这次来和大家一起学习华大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. }
复制代码
开始,打开工程就看到了一个这个,这是啥,也太简单了吧





使用特权

评论回复
 楼主 | 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. }
复制代码

这个其实里面就是对一个全局变量进行赋值

使用特权

评论回复
 楼主 | 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
复制代码




使用特权

评论回复
 楼主 | 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的内部中速时钟频率

使用特权

评论回复
 楼主 | 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的中断

使用特权

评论回复
 楼主 | 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. }
复制代码

使用特权

评论回复
| 2021-1-18 22:10 | 显示全部楼层
支持下,,谢谢分享。

使用特权

评论回复
| 2021-1-19 15:22 | 显示全部楼层
很棒,支持下

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

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