binoo7 发表于 2021-1-18 16:47

华大MCU HC32F460 Systick

这次来和大家一起学习华大MCU HC32F460 Systick部分,这部分其实华大给的PDF文档里的内容很少,但是我在例程看到了相关的内容,跟大家一起分享一下吧,废话不多说,开始喽

/**
*******************************************************************************
** \brief SysTick interrupt callback function.
**
** \param None
**
** \retval None
**
******************************************************************************/
void SysTick_IrqHandler(void)
{
    SysTick_IncTick();
}
开始,打开工程就看到了一个这个,这是啥,也太简单了吧





binoo7 发表于 2021-1-18 17:35

本帖最后由 binoo7 于 2021-1-18 17:37 编辑

别着急,我继续更新
/**
*******************************************************************************
** \brief This function is called to increment a global variable "u32TickCount".
** \noteThis variable is incremented in SysTick ISR.
**
** \param None
**
** \retval None
**
******************************************************************************/
__WEAKDEF void SysTick_IncTick(void)
{
    m_u32TickCount += m_u32TickStep;
}

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

binoo7 发表于 2021-1-18 17:38

本帖最后由 binoo7 于 2021-1-18 17:46 编辑

/* SysTick configuration */
    SysTick_Init(1000u);
这个函数是初始化Systick
/**
*******************************************************************************
** \brief This function Initializes the interrupt frequency of the SysTick.
**
** \param u32Freq               SysTick interrupt frequency (1 to 1000).
**
** \retval Ok                        SysTick Initializes succeed
** \retval Error                     SysTick Initializes failed
**
******************************************************************************/
__WEAKDEF en_result_t SysTick_Init(uint32_t u32Freq)
{
    en_result_t enRet = Error;

    if ((0UL != u32Freq) && (u32Freq <= 1000UL))
    {
      m_u32TickStep = 1000UL / u32Freq;
      /* Configure the SysTick interrupt */
      if (0UL == SysTick_Config(SystemCoreClock / u32Freq))
      {
            enRet = Ok;
      }
    }

    return enRet;
}

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

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

/**
\brief   System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
         Counter is in free running mode to generate periodic interrupts.
\param ticksNumber of ticks between two interrupts.
\return          0Function succeeded.
\return          1Function failed.
\note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
         function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
         must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
    return (1UL);                                                   /* Reload value impossible */
}

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

#endif



binoo7 发表于 2021-1-18 17:47

本帖最后由 binoo7 于 2021-1-18 18:03 编辑

/**
\briefStructure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)SysTick Control and Status Register */
__IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)SysTick Reload Value Register */
__IOM uint32_t VAL;                  /*!< Offset: 0x008 (R/W)SysTick Current Value Register */
__IMuint32_t CALIB;                  /*!< Offset: 0x00C (R/ )SysTick Calibration Register */
} SysTick_Type;
看到上一个初始化是怎么做的了吧,就是给SysTick结构体里的内容赋值,
#define MRC_VALUE ((uint32_t)8000000)   /*!< Internal middle speed RC freq. */初始化的时候用到了一个时钟的一个全局变量,这个变量的赋值是根据这个数来的,8000000就是8M的内部中速时钟频率

binoo7 发表于 2021-1-18 19:10

/**
*******************************************************************************
** \brief This function provides minimum delay (in milliseconds).
**
** \param u32Delay                Delay specifies the delay time.
**
** \retval None
**
******************************************************************************/
__WEAKDEF void SysTick_Delay(uint32_t u32Delay)
{
    const uint32_t tickStart = SysTick_GetTick();
    uint32_t tickEnd;
    uint32_t tickMax;

    if (m_u32TickStep != 0UL)
    {
      tickMax = 0xFFFFFFFFUL / m_u32TickStep * m_u32TickStep;
      /* Add a freq to guarantee minimum wait */
      if ((u32Delay >= tickMax) || ((tickMax - u32Delay) < m_u32TickStep))
      {
            tickEnd = tickMax;
      }
      else
      {
            tickEnd = u32Delay + m_u32TickStep;
      }

      while ((SysTick_GetTick() - tickStart) < tickEnd)
      {
      }
    }
}
这是延时函数,一直在判断设定时间是否与延时的时间是否相同,如果达到后就停止,如果不相同就一直等待,没有用到Systick的中断

binoo7 发表于 2021-1-18 19:20

STM32是怎么做的呢?下面讲解一下正点原子的方法SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟HCLK/8
        fac_us=SystemCoreClock/8000000;                                //为系统时钟的1/8
fac_ms=(u16)fac_us*1000;                                        //非OS下,代表每个ms需要的systick时钟数   
void delay_us(u32 nus)
{               
        u32 temp;                 
        SysTick->LOAD=nus*fac_us;                                         //时间加载                         
        SysTick->VAL=0x00;                                              //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数          
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
        SysTick->VAL =0X00;                                             //清空计数器       
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{                                   
        u32 temp;                  
        SysTick->LOAD=(u32)nms*fac_ms;                                //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                                                        //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
        SysTick->VAL =0X00;                                               //清空计数器                    
}

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比定时器差太多了。
页: [1] 2
查看完整版本: 华大MCU HC32F460 Systick