本帖最后由 shenxiaolin 于 2023-8-15 07:38 编辑
前段时间出差,没有顾得上更新帖子,今天来更新一下,今天和大家要分享的是定时器的使用,
在使用定时器之前,需要我们吧HAL库的配置更改一下,首先是我们的STM32H5xx_HAL_CONF.h文件
我们这里把通用的模块都使能了,这样的话后面就不用做更改了,后期用到哪个模块就使能哪个模块。
我们这里把串口,定时器、RTC都使能了。
HAL库之所以这样做是因为我们只对使用的模块进行编译,缩短了整体编译的时间,同时也缩小了整体的代码大小。
通过查看我们的H563的数据手册,我们可以找到TIM1的时钟主频为250MHZ,这样的话可以方便我们对整个系统的时钟有所了解。
然后还有一个地方需要修改的,就是外部的晶振的频率值,原理图上给的是25M的,而程序内部使用的是8M的数值,这个地方需要注意一下,否则包括串口,定时器、CAN总线等和通信相关的都是有问题的。
(这个地方就是25M)
然后就是定时器的初始化了,定时器的初始化的时候我们可以跟踪到初始化的结构体内部,定时器的初始化结构体对结构体内部变量的大小以及取值都做了详细的说明,在编程的时候应当有所注意。
然后我查了一下STM32H563的定时器的例程,但是并没有发现有关于定时器基础应用的案例,不知道是懒得写还是怎么的,让人很头疼……然后自己根据以前的经验,写了一下,发现真的有点头疼……
Hall没有查看Hall中断标志位的函数,也没有清除中断标志位的函数,所以这个比较麻烦。只有从.h文件里面去找了。
但是按照原有的代码以及思想去看的话,实验效果存在问题,我们本来是想1s翻转一次,但是实际仿真的时候是6-7s才完成一个计数,导致实际翻转的值反而变成了6000-7000s看来这就是时钟配置的问题了。原始代码如下:void Tim1_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
unsigned int ERR_Count=0;
__HAL_RCC_TIM1_CLK_ENABLE();//--使能时钟--
//--
htim1.Instance = TIM1;
htim1.Init.Prescaler =1;//-取值范围0-0xFFFF-----250分频-得到1M的时钟
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;//--向上计数模式
htim1.Init.Period =250;//--这里设置定时器时间为1ms-- 1/1M*1000=1ms
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//--主时钟不分频
htim1.Init.RepetitionCounter = 1000-1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//--使能自动重载--TIM_AUTORELOAD_PRELOAD_DISABLE TIM_AUTORELOAD_PRELOAD_ENABLE
// HAL_TIM_Base_Init(&htim1);
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
while(1)
{
ERR_Count++;
HAL_Delay(1000);
}
}
//使能定时器中断
HAL_TIM_Base_Start_IT(&htim1);//--使能中断--
HAL_TIM_Base_Start(&htim1);//--使能定时器
HAL_NVIC_SetPriority(TIM1_UP_IRQn, 1, 0); /* -设置中断优先级 */
HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);/*-- 使能中断 --*/
}
这个是h5的RCC的是时钟树,然后查看了这个章节的关于配置的时钟的一些注意事项,我将跟大家一起来。
然后查找了一下RCC时钟的设置问题,发现RCC的时钟设置存在问题,所以就比较恼火了。
问题找到了,那么明天的时候来再来修改,先睡觉了,然后来张图镇楼,真的是边喝酒边写代码,电脑干蓝屏了。
然后经过仔细的查找,发现时晶振不起振……不知道是不是哪里配置错误了……
然后就查找硬件,就发现一个问题……就是下面这个图
先比大家一看就知道是怎么回事了,使用板载的25M的晶振需要短接SB3和SB4,然后后就是SB49,也需要去掉,避免STlink的干扰(主要是我的STLInk有问题),好吧,与那里是在这个地方等着我……不知道论坛其他网友有没有发现这个问题。
然后修改一下我们的RCC的配置代码
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON ;//--RCC_HSE_BYPASS_DIGITAL RCC_HSE_BYPASS RCC_HSE_ON
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;//--25M/25=1M
RCC_OscInitStruct.PLL.PLLN = 250;//--1*250=250M
RCC_OscInitStruct.PLL.PLLP = 1; //--250M
//--时钟计算公式:(HSE/PLLM*PLLN)/PLLP=((25/25)*250)/1=250M
RCC_OscInitStruct.PLL.PLLQ = 1; //
RCC_OscInitStruct.PLL.PLLR = 1; //
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;//--宽范围的晶振:192 and 836 MHz
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
while(1)
{
i++;
}
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK3;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
while(1)
{
i++;
}
}
}
我们的板子最终可以运行在250M的时钟下了。
下面是最终的定时器的代码
void Tim1_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
unsigned int ERR_Count=0;
__HAL_RCC_TIM1_CLK_ENABLE();//--使能时钟--
//--
htim1.Instance = TIM1;
htim1.Init.Prescaler =0;//-取值范围0-0xFFFF-----0分频-得到500M的时钟
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;//--向上计数模式
htim1.Init.Period =249;//--这里设置定时器时间为1ms-- 1/1M*1000=1ms
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//--主时钟不分频
htim1.Init.RepetitionCounter = 1000-1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//--使能自动重载--TIM_AUTORELOAD_PRELOAD_DISABLE TIM_AUTORELOAD_PRELOAD_ENABLE
// HAL_TIM_Base_Init(&htim1);
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
while(1)
{
ERR_Count++;
HAL_Delay(1000);
}
}
//使能定时器中断
HAL_TIM_Base_Start_IT(&htim1);//--使能中断--
HAL_TIM_Base_Start(&htim1);//--使能定时器
HAL_NVIC_SetPriority(TIM1_UP_IRQn, 1, 0); /* -设置中断优先级 */
HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);/*-- 使能中断 --*/
}
好了,板子完美运行,这下可以放心的Happy了,只要时钟的问题解决,那么我们就可以开心的玩其他的接口了。
下面就来看看点灯效果。
|