Nucleo-F411RE (STM32F411)LL库体验 5 - 通用定时器TIM2的使用
1、简述
设定TIM2,计数周期为10KHZ,即计时1s需要10000次,通过shell命令动态修改reload值,来更改定时器的频率。
假定设定TIM2 counter clock = 10K,那么TIM2 prescaler = (SystemCoreClock /10 KHz) - 1,代码中通过
__LL_TIM_CALC_PSC(SystemCoreClock, 10000)来计算得到。
假定 100ms进入一次中断,即freq=10HZ,那么tim2的autoreload的值通过下面的函数得到。
InitialAutoreload = __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM2), 10);
(InitialAutoreload即是hal库的period值)
2、TIM2的初始化
a、时钟初始化
b、TIM初始化
// 初始化TIM2 控制LED灯的闪烁,默认100ms一次
static void BOARD_Tim2Init(void)
{
uint32_t InitialAutoreload = 0;
/* Set counter mode */
/* Reset value is LL_TIM_COUNTERMODE_UP */
//LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
/* Set the pre-scaler value to have TIM2 counter clock equal to 10 kHz */
/*
In this example TIM2 input clock (TIM2CLK) is set to APB1 clock (PCLK1),
since APB1 prescaler is equal to 1.
TIM2CLK = PCLK1
PCLK1 = HCLK
=> TIM2CLK = HCLK = SystemCoreClock
To get TIM2 counter clock at 10 KHz, the Prescaler is computed as following:
Prescaler = (TIM2CLK / TIM2 counter clock) - 1
Prescaler = (SystemCoreClock /10 KHz) - 1
设置TIM2 counter clock at 10 KHz,即1s需要10000次,那么100ms需要计数1000次。
所以autoReload=1000-1时,100ms进中断一次。
*/
LL_TIM_SetPrescaler(TIM2, __LL_TIM_CALC_PSC(SystemCoreClock, 10000));
/* Set the auto-reload value to have an initial update event frequency of 10 Hz */
/* TIM2CLK = SystemCoreClock / (APB prescaler & multiplier) */
InitialAutoreload = __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM2), 10);
LL_TIM_SetAutoReload(TIM2, InitialAutoreload);
/* Enable the update interrupt */
LL_TIM_EnableIT_UPDATE(TIM2);
/* Configure the NVIC to handle TIM2 update interrupt */
NVIC_SetPriority(TIM2_IRQn, 0);
NVIC_EnableIRQ(TIM2_IRQn);
/* Enable counter */
LL_TIM_EnableCounter(TIM2);
/* Force update generation */
LL_TIM_GenerateEvent_UPDATE(TIM2);
}
c、中断处理函数
3、shell的调试
a、shell命令添加
volatile static uint32_t InitialAutoreload = 0;
volatile static uint32_t Freq = 10;
int Tim_Control(int argc,char *argv[])
{
if (argc == 2)
{
if (!strncmp(argv[1],"On",2))
{
LL_TIM_EnableCounter(TIM2);
}
else if (!strncmp(argv[1],"Off",3))
{
LL_TIM_DisableCounter(TIM2);
}
else
{
printf("error,please use / TIM On/TIM Off\r\n");
return -1;
}
}
else if (argc == 3)
{
if (!strncmp(argv[1],"Freq",4))
{
Freq = strtol(argv[2],NULL,10);
if (Freq > 0)
{
LL_TIM_DisableCounter(TIM2);
InitialAutoreload = __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM2), Freq);
LL_TIM_SetAutoReload(TIM2, InitialAutoreload);
LL_TIM_EnableCounter(TIM2);
LL_TIM_GenerateEvent_UPDATE(TIM2);
}
else
{
printf("please use TIM Freq 10 \r\n");
LL_TIM_DisableCounter(TIM2);
return -1;
}
}
else
{
printf("error,please use / TIM On/TIM Off\r\n");
}
}
else
{
printf("error,please use / TIM On/TIM Off\r\n");
return -1;
}
return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), TIM, Tim_Control, Tim_Control);
TIM On 打开定时器
TIM Off 关闭定时器
TIM Freq xx 更改定时器的频率,1-10K之间.
4、代码
代码下载