今天编写的是利用系统计时器SysTick编写us级精确延时函数和ms级精确延时函数。参考了一下以前写的STM32的SysTick的程序完成了此项工作,就是初始化不太一样,核心代码还是一样的。另外,由于STM32有的是Cortex-M3,且选择是的时钟是72MHz,而HT32F52352用是Cortex-M0,且选择的是外部参考时钟HSI(8MHz),因此在程序内部相关库函数的形参值设定的也不一样。由于SysTick属于内核里的,因此就没有硬件的封装了。为了验证代码的准确性,利用编写好的延时函数也成功实现了LED的闪烁。详情见代码。LED的封装见(https://blog.csdn.net/Unlimited_Bit/article/details/86657366)。
主要的代码:
#include "ht32_cm0plus_misc.h"
void Systick_Delay_ms(u32 ms)
{
u32 i;
/* SYSTICK configuration */
SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK); // 即默认选择了外部参考时钟HSI(8MHz/8)
SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000); // (CK_SYS/8/1000) = 1ms
SYSTICK_IntConfig(DISABLE); // 不开启中断
/* 打开SysTick计数器 */
SYSTICK_CounterCmd(SYSTICK_COUNTER_CLEAR);
SYSTICK_CounterCmd(SYSTICK_COUNTER_ENABLE);
for( i = 0;i < ms;i++ )
{
while( !( (SysTick->CTRL) & (1<<16) ) );
}
/* 关闭SysTick计数器 */
SYSTICK_CounterCmd(SYSTICK_COUNTER_DISABLE);
/* 复位SysTick计数器 */
SYSTICK_CounterCmd(SYSTICK_COUNTER_CLEAR);
}
void Systick_Delay_us(u32 us)
{
u32 i;
/* SYSTICK configuration */
SYSTICK_ClockSourceConfig(SYSTICK_SRC_STCLK); // 即默认选择了外部参考时钟HSI(8MHz/8)
SYSTICK_SetReloadValue(SystemCoreClock / 8 / 1000000); // (CK_SYS/8/1000000) = 1us
SYSTICK_IntConfig(DISABLE); // 不开启中断
/* 打开SysTick计数器 */
SYSTICK_CounterCmd(SYSTICK_COUNTER_CLEAR);
SYSTICK_CounterCmd(SYSTICK_COUNTER_ENABLE);
for( i = 0;i < us;i++ )
{
while( !( (SysTick->CTRL) & (1<<16) ) );
}
/* 关闭SysTick计数器 */
SYSTICK_CounterCmd(SYSTICK_COUNTER_DISABLE);
/* 复位SysTick计数器 */
SYSTICK_CounterCmd(SYSTICK_COUNTER_CLEAR);
}
用到的库函数:
(1)时钟源选择库函数:
/*********************************************************************************************************//**
* @brief Configure the SysTick clock source.
* @param SysTick_ClockSource: Specify the SysTick clock source.
* This parameter can be one of the following values:
* @arg SYSTICK_SRC_STCLK : External reference clock is selected as SysTick clock source.
* @arg SYSTICK_SRC_FCLK : AHB clock is selected as SysTick clock source.
* @retval None
***********************************************************************************************************/
void SYSTICK_ClockSourceConfig(u32 SysTick_ClockSource)
(2)计数器初值/重装载值设定
/*********************************************************************************************************//**
* @brief Set SysTick counter reload value.
* @param SysTick_Reload: SysTick reload new value.
* This parameter must be a number between 1 and 0xFFFFFF.
* @retval None
***********************************************************************************************************/
void SYSTICK_SetReloadValue(u32 SysTick_Reload)
(3)SysTick中断使能函数
/*********************************************************************************************************//**
* @brief Enable or Disable the SysTick Interrupt.
* @param NewState: new state of the SysTick Interrupt.
* This parameter can be: ENABLE or DISABLE.
* @retval None
***********************************************************************************************************/
void SYSTICK_IntConfig(ControlStatus NewState)
(4)SysTick使能函数
/*********************************************************************************************************//**
* @brief Enable or Disable the SysTick counter.
* @param SysTick_Counter: new state of the SysTick counter.
* This parameter can be one of the following values:
* @arg SYSTICK_COUNTER_DISABLE : Disable counter
* @arg SYSTICK_COUNTER_ENABLE : Enable counter
* @arg SYSTICK_COUNTER_CLEAR : Clear counter value to 0
* @retval None
***********************************************************************************************************/
void SYSTICK_CounterCmd(u32 SysTick_Counter)
(5)SysTick_Type结构体
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
在此说明下相关寄存器的配置。相关的库函数都是配置了SysTick控制及状态寄存器(SysTick Control and Status Register)、SysTick重装载数值寄存器(SysTick Reload Value Register)、SysTick当前函数值寄存器( SysTick Current Value Register)
这是Cortex™-M0通用用户手册,只有英文版。下图是STM32资料里面的,两份配合一起看更容易了解。