簡體   English   中英

如何使用硬件定時器在 STM32f7xx 上生成精確的 1us 中斷

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM