华大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: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: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 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的内部中速时钟频率
/**
*******************************************************************************
** \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的中断 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; //清空计数器
} 支持下,,谢谢分享。 很棒,支持下 hc32f460中,systick具体延时时间怎么计算的? 是否有Systick工程文件可以借鉴呢? HC32F460 怎么开启systick定时器 和某T的很像啊 能不能把Systick帖子整合一下? systick中断逻辑包括哪些? Systick允许的最长和最短定时是多少? SysTick的优先级是高还是低? HC32F460 如何使用Systic(库函数) Systick的精度怎么样 为什么芯片不多设计一个定时器,而要添加Systick呢? 感觉Systick比定时器差太多了。
页:
[1]
2