目录
一、简介
1.1、开发环境
1.2、实现功能
1.3、思路解析
二、系统时钟周期为100us
2.1、重新定义初始化函数
2.2、重新定义中断调用的函数
三、系统时钟周期为10ms
3.1、重新定义初始化函数
3.2、重新定义中断调用的函数
STM32CubeIDE V1.9。
使用STM32CubeIDE配置完后,分别修改系统时钟周期为100us和10ms,并使用。
STM32CubeIDE V1.9的“Device Configuration Tool”(即STM32CubeMX),默认打开系统时钟(SysTick),无需配置,也无法配置系统时钟周期。所以要修改系统时钟周期,只能通过程序实现。
“Device Configuration Tool”生成的程序:
(1)初始化过程会调用函数“HAL_InitTick”;
(2)系统时钟产生中断后,会调用函数“HAL_IncTick”。
这两个函数均为已经定义函数主体的弱函数,可重新定义这两个函数,来修改和使用系统时钟。
函数“HAL_InitTick”中,主要由语句“1000U / uwTickFreq”确定系统时钟频率,具体修改方案为:
(1)系统时钟周期小于1ms,以100us为例,改为“10000U / uwTickFreq”;系统时钟中断调用的函数“HAL_IncTick”,需要每1ms执行1次“uwTick += uwTickFreq”;
(2)系统时钟周期大于1ms,以10ms为例,令 uwTickFreq = 10。
所有系统时钟周期小于1ms,均可参照本案例进行修改。
修改内容:将原函数的“1000U / uwTickFreq”,改为“10000U / uwTickFreq”。
“1000U / uwTickFreq”的计算结果,为系统时钟的频率,uwTickFreq的值默认为1。
重新定义“HAL_InitTick”函数:
/*
* 功能:重新定义HAL_InitTick,修改系统时钟周期为100us
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/* Configure the SysTick to have interrupt in 100us time basis*/
if (HAL_SYSTICK_Config(SystemCoreClock / (10000U / uwTickFreq)) > 0U) //修改处
{
return HAL_ERROR;
}
/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
return HAL_ERROR;
}
/* Return function status */
return HAL_OK;
}
HAL库的“HAL_IncTick”原函数比较简单,具体如下:
__weak void HAL_IncTick(void)
{
uwTick += uwTickFreq;
}
重新定义的“HAL_IncTick”函数:
struct SystemClock //系统时钟
{
uint16_t t100us;
uint16_t t1ms;
}
stSC;
void HAL_IncTick()
{
/*100us****************************************************/
//填写100us累加的变量
/*100us****************************************************/
if(++ stSC.t100us > 9)
{
stSC.t100us = 0;
uwTick += uwTickFreq;
/*1ms****************************************************/
//填写1ms累加的变量
/*1ms****************************************************/
if(++ stSC.t1ms > 999)
{
stSC.t1ms = 0;
/*1s****************************************************/
//填写1s累加的变量
/*1s****************************************************/
}
}
}
注:为保证其余调用“HAL_GetTick”函数,时钟周期不会发生变化,所以每1ms操作1次“uwTick += uwTickFreq”语句。
所有系统时钟周期大于1ms,均可参照本案例进行修改。
修改内容:令 uwTickFreq = 10。
重新定义“HAL_InitTick”函数:
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/* Configure the SysTick to have interrupt in 10ms time basis*/
uwTickFreq = 10; //修改处
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
{
return HAL_ERROR;
}
/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
return HAL_ERROR;
}
/* Return function status */
return HAL_OK;
}
重新定义“HAL_InitTick”函数:
struct SystemClock //系统时钟
{
uint16_t t10ms;
}
stSC;
void HAL_IncTick()
{
uwTick += uwTickFreq;
/*10ms***************************************************/
//填写10ms累加变量
/*10ms***************************************************/
if(++ stSC.t10ms > 99)
{
stSC.t10ms = 0;
/*1s****************************************************/
//填写1s累加变量
/*1s****************************************************/
}
}
由于uwTickFreq = 10,系统时钟每10ms产生中断,操作1次uwTick += uwTickFreq,即uwTick每10ms累加10,相当于每1ms累加1,所以能够保证其余调用“HAL_GetTick”函数,时钟周期不会发生变化。
不得不佩服STM的工程师的思路!