我试着在stm32f103r6t上做我自己的毫秒计时器,我使用了计时器2,在经过一段时间后中断,然后我把计数器增加了一步。时钟频率为64 The (APB1 1&2也为64 the ),预调用者为127,周期值设置为500。我通过在中断上切换一个引脚进行测试,在示波器上我得到了1ms的半周期(这是预料中的)。我所做的另一个测试是将它与__Hal_get_ticks()进行比较,并将其发送到uart。__Hal_get_ticks()似乎更快,而且它们之间的差异随着时间的推移而不断增加。我已经发布了下面的代码,虽然我确实初始化了更多的外围设备,但我还没有使用它们。
长HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* milliseconds=0){ HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);milliseconds++;}
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_CAN_Init();
MX_SPI1_Init();
MX_TIM2_Init();
MX_TIM3_Init();
stm32_uart2_set_state(1);
HAL_TIM_Base_Start_IT(&htim2);
// MX_WWDG_Init();
/* USER CODE BEGIN 2 */
char string[100]={0};
int index=0;
/* Infinite loop */
while (1)
{
uint32_t hall_tick=HAL_GetTick();
sprintf(string,"It:%lu\tHt:%lu\n\r",milliseconds,hall_tick);
stm32_uart2_send_string(string, strlen(string));
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 127; //prescaller is zero-based (0 means clk/1)
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 500;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}编辑:这是hal计数器的默认init函数,默认情况下中断优先级为15,我尝试将其设置为0,但结果是相同的。我测量了HAL_get_tick()和它的998 its的周期,而不是1ms。
_weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/* Configure the SysTick to have interrupt in 1ms time basis*/
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;}
发布于 2022-10-14 09:31:58
我认为您可能希望将您的TIM2周期设置为499。它是零基的,就像预定标器一样。从手册中:
在超数模式下,计数器计数从0到自动重新加载值( TIMx_ARR寄存器的内容),然后从0重新启动并生成计数器溢出事件。
您希望计数从0到499,然后重置为零。
这就解释了为什么你每毫秒就有2美元被淘汰。
https://stackoverflow.com/questions/74055617
复制相似问题