[英]How to generate exact 1us interrupt on STM32f7xx using Hardware Timers
我是基於中斷的編程的新手。 在我當前的項目中,我需要恰好以 1us 間隔生成中斷。 下面是 CubeMX 中時鍾配置選項卡的屏幕截圖。 我正在使用 TIM3 定時器,因為它可以產生 1us 的時鍾頻率。
下面是 TIM3 配置代碼。
static void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 1-1 ;//0x00;// 0x36; || 0x00//1-1
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 0xffff-1; //0x64; || 0xd7 //0xffff-1
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
我在叫計時器
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);
我看到產生了持續時間為 1.2ms 的中斷。 誰能告訴我為什么會發生這種情況,我怎樣才能將中斷減少到 1us 持續時間? 定時器頻率需要改變嗎?
我也在使用 freeRTOS,其他應用程序也在微控制器上運行。
對此的任何幫助都將受到高度贊賞。
提前致謝
如果您的要求 output 是一個准確的 500KHz 1:1 標記/空間信號(即 1us 高,1us 低),那么通過中斷來做到這一點,同時期望您的系統做其他有用的工作既不切實際也是不必要的。 通用定時器具有輸出比較 function,可直接驅動 GPIO 引腳,無需中斷或軟件開銷。
只有某些引腳連接到 Timer OC 通道,因此在這種情況下要驅動 PB6,您需要使用 TIM4 通道 1。
此外,您應該使用可用的 HAL RCC 時鍾函數(在這種情況下為HAL_RCC_GetPCLK1Freq()
)來計算值以避免錯誤,而不是確定和硬編碼定時器重載和脈沖,這樣代碼就可以移植到其他系統或如果您更改時鍾配置,它將正常工作。
static void MX_TIM4_Init(void)
{
cost uint32_t PULSE_WIDTH = HAL_RCC_GetPCLK1Freq() * 2 / 1000000 ;
htim4.Instance = TIM4 ;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP ;
htim4.Init.Period = PULSE_WIDTH * 2 ;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1 ;
HAL_TIM_PWM_Init( &htim4 ) ;
TIM_MasterConfigTypeDef sMasterConfig ;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
TIM_OC_InitTypeDef sConfigOC ;
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = PULSE_WIDTH ;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
}
然后在其他地方您需要將 PB6 配置為 output 並啟動計時器:
LL_GPIO_InitTypeDef GPIO_InitStruct = {0} ;
GPIO_InitStruct.Pin = GPIO_PIN_6 ;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE ;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW ;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL ;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO ;
GPIO_InitStruct.Alternate = LL_GPIO_AF_2 ;
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB)
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_TIM_PWM_Start( &htim4, TIM_CHANNEL_1 ) ;
此后,信號將無限期地保持在 PB6 上,沒有 GPIO 訪問或中斷處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.