在 stm32 f767zit 上未正确生成 PWM 信号

Posted

技术标签:

【中文标题】在 stm32 f767zit 上未正确生成 PWM 信号【英文标题】:PWM Signals not generating correctly on stm32 f767zit 【发布时间】:2021-06-16 04:47:58 【问题描述】:

我正在使用 stm32 f767zit,我正在尝试生成 PWM 信号来控制伺服系统,但它们无法正确生成。我从这里Deep Blue Embedded 学习了教程,并且能够在 stm32 f103rb 上很好地生成 PWM 信号,但我切换到 f767zit 因为我需要更多的 PWM 输出。我已经查看了 HAL 文档并对两者进行了比较,据我所知,应该如何生成 pwm 信号没有任何区别。

我已经使用 stm32 板完成了几个项目,但我仍然是一个菜鸟。我已经寻找了很多小时的解决方案,但我找不到一个。抱歉,这实际上只是我缺少的一些简单和基本的东西。

这是 pwm 输出的屏幕截图。如您所见,f103rb 正常生成它们,50hz 和 3.3v 峰值的方波。 f767 上的 pwm 信号由许多尖峰组成,峰值为 10mV。虽然,它们似乎确实以正确的脉冲长度产生

PWM Output of f103rb

PWM Output of f767

在我的代码中,我要做的就是初始化伺服系统并将它们设置为一个位置。有 12 个伺服系统,它们使用计时器 1-4。具体的通道和管脚可以在伺服配置代码中看到。我的主要代码初始化所有的外围,然后调用initServos(),它为SERVO_CfgParam 中的每个伺服器调用SERVO_init()。然后我的主循环调用SERVO_moveto()。我只在主代码中移动了一个伺服器,但我已经测试了我正在使用的每个引脚并得到相同的结果。

我在我的 f013rb 上使用相同的肉类和代码来控制 3 个伺服系统,没有任何问题。我不知道 f767zit 有什么不同。

主代码

int main(void)

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_SPI1_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
  initServos();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  

    SERVO_MoveTo(11,90);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  
  /* USER CODE END 3 */

伺服配置。

typedef struct

    GPIO_TypeDef * SERVO_GPIO;
    uint16_t       SERVO_PIN;
    TIM_TypeDef*   TIM_Instance;
    uint32_t*      TIM_CCRx;
    uint32_t       PWM_TIM_CH;
    uint32_t       TIM_CLK;
    float          MinPulse;
    float          MaxPulse;
SERVO_CfgType;

const SERVO_CfgType SERVO_CfgParam[SERVO_NUM] =

    // Servo Motor 1 Configurations
    
        GPIOE,
        GPIO_PIN_9,
        TIM1,
        &TIM1->CCR1,
        TIM_CHANNEL_1,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 2 Configurations
    
        GPIOE,
        GPIO_PIN_11,
        TIM1,
        &TIM1->CCR2,
        TIM_CHANNEL_2,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 3 Configurations
    
        GPIOE,
        GPIO_PIN_13,
        TIM1,
        &TIM1->CCR3,
        TIM_CHANNEL_3,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 4 Configurations
    
        GPIOE,
        GPIO_PIN_14,
        TIM1,
        &TIM1->CCR4,
        TIM_CHANNEL_4,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 5 Configurations
    
        GPIOA,
        GPIO_PIN_15,
        TIM2,
        &TIM2->CCR1,
        TIM_CHANNEL_1,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 6 Configurations
    
        GPIOB,
        GPIO_PIN_10,
        TIM2,
        &TIM2->CCR2,
        TIM_CHANNEL_3,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 7 Configurations
    
        GPIOB,
        GPIO_PIN_11,
        TIM2,
        &TIM2->CCR4,
        TIM_CHANNEL_4,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 8 Configurations
    
        GPIOC,
        GPIO_PIN_6,
        TIM3,
        &TIM3->CCR1,
        TIM_CHANNEL_1,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 9 Configurations
    
        GPIOC,
        GPIO_PIN_7,
        TIM3,
        &TIM3->CCR2,
        TIM_CHANNEL_2,
        72000000,
        0.65,
        2.3
    ,
// Servo Motor 10 Configurations
    
        GPIOC,
        GPIO_PIN_8,
        TIM3,
        &TIM3->CCR3,
        TIM_CHANNEL_3,
        72000000,
        0.65,
        2.3
    ,
    // Servo Motor 11 Configurations
    
        GPIOC,
        GPIO_PIN_9,
        TIM3,
        &TIM3->CCR4,
        TIM_CHANNEL_4,
        72000000,
        0.65,
        2.3
    ,
// Servo Motor 12 Configurations
    
        GPIOB,
        GPIO_PIN_6,
        TIM4,
        &TIM4->CCR1,
        TIM_CHANNEL_1,
        72000000,
        0.65,
        2.3
    
;

伺服初始化函数

void SERVO_Init(uint16_t au16_SERVO_Instance)

    GPIO_InitTypeDef GPIO_InitStruct = 0;
    TIM_ClockConfigTypeDef sClockSourceConfig = 0;
    TIM_MasterConfigTypeDef sMasterConfig = 0;
    TIM_OC_InitTypeDef sConfigOC = 0;
    TIM_HandleTypeDef htim;
    uint32_t PSC_Value = 0;
    uint32_t ARR_Value = 0;
    //DWT_Delay_Init();

    /*--------[ Configure The Servo PWM GPIO Pin ]-------*/

    if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOA)
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOB)
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOC)
    
        __HAL_RCC_GPIOC_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOD)
    
        __HAL_RCC_GPIOD_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOE)
    
        __HAL_RCC_GPIOE_CLK_ENABLE();
    
    GPIO_InitStruct.Pin = SERVO_CfgParam[au16_SERVO_Instance].SERVO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO, &GPIO_InitStruct);

    /*--------[ Calculate The PSC & ARR Values To Maximize PWM Resolution ]-------*/

    /* Those Equations Sets The F_pwm = 50Hz & Maximizes The Resolution*/
    PSC_Value = (uint32_t) (SERVO_CfgParam[au16_SERVO_Instance].TIM_CLK / 3276800.0);
    ARR_Value = (uint32_t) ((SERVO_CfgParam[au16_SERVO_Instance].TIM_CLK / (50.0*(PSC_Value+1.0)))-1.0);

    /*--------[ Configure The Servo PWM Timer Channel ]-------*/

    /*--[Check The Timer & Enable Its Clock]--*/
    if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM1)
    
        __HAL_RCC_TIM1_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM2)
    
        __HAL_RCC_TIM2_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM3)
    
        __HAL_RCC_TIM3_CLK_ENABLE();
    
    else if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM4)
    
        __HAL_RCC_TIM4_CLK_ENABLE();
    

    htim.Instance = SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance;
    htim.Init.Prescaler = PSC_Value;
    htim.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim.Init.Period = ARR_Value;
    htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    HAL_TIM_Base_Init(&htim);
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    HAL_TIM_ConfigClockSource(&htim, &sClockSourceConfig);
    HAL_TIM_PWM_Init(&htim);
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig);
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, SERVO_CfgParam[au16_SERVO_Instance].PWM_TIM_CH);

    /*--------[ Calculate & Save The Servo Pulse Information ]-------*/

    gs_SERVO_info[au16_SERVO_Instance].Period_Min = (uint16_t) (ARR_Value * (SERVO_CfgParam[au16_SERVO_Instance].MinPulse/20.0));
    gs_SERVO_info[au16_SERVO_Instance].Period_Max = (uint16_t) (ARR_Value * (SERVO_CfgParam[au16_SERVO_Instance].MaxPulse/20.0));

    /*--------[ Start The PWM Channel ]-------*/

    HAL_TIM_PWM_Start(&htim, SERVO_CfgParam[au16_SERVO_Instance].PWM_TIM_CH);

移动舵机

/* Moves A Specific Motor To A Specific Degree That Can Be Float Number */
void SERVO_MoveTo(uint16_t au16_SERVO_Instance, float af_Angle)

    uint16_t au16_Pulse = 0;

    au16_Pulse = ((af_Angle*(gs_SERVO_info[au16_SERVO_Instance].Period_Max - gs_SERVO_info[au16_SERVO_Instance].Period_Min))/180.0)
            + gs_SERVO_info[au16_SERVO_Instance].Period_Min;

    *(SERVO_CfgParam[au16_SERVO_Instance].TIM_CCRx) = au16_Pulse;

GPIO 和定时器初始化

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)

  GPIO_InitTypeDef GPIO_InitStruct = 0;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : USER_Btn_Pin */
  GPIO_InitStruct.Pin = USER_Btn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : RMII_MDC_Pin RMII_RXD0_Pin RMII_RXD1_Pin */
  GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : RMII_REF_CLK_Pin RMII_MDIO_Pin RMII_CRS_DV_Pin */
  GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : LD1_Pin LD3_Pin LD2_Pin */
  GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : RMII_TXD1_Pin */
  GPIO_InitStruct.Pin = RMII_TXD1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
  HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_PowerSwitchOn_Pin */
  GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_OverCurrent_Pin */
  GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : RMII_TX_EN_Pin RMII_TXD0_Pin */
  GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);



static void MX_TIM1_Init(void)


  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = 0;
  TIM_OC_InitTypeDef sConfigOC = 0;
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = 0;

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 65535;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
  
    Error_Handler();
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  
    Error_Handler();
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  
    Error_Handler();
  
  sBreakDeadTimeConfig.OffStateRunMode = TIM_Os-s-r_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.BreakFilter = 0;
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);



/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)


  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = 0;
  TIM_OC_InitTypeDef sConfigOC = 0;

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 65535;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
  
    Error_Handler();
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  
    Error_Handler();
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */
  HAL_TIM_MspPostInit(&htim2);



/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)


  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = 0;
  TIM_OC_InitTypeDef sConfigOC = 0;

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 65535;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  
    Error_Handler();
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  
    Error_Handler();
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  
    Error_Handler();
  
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);



/**
  * @brief TIM4 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM4_Init(void)


  /* USER CODE BEGIN TIM4_Init 0 */

  /* USER CODE END TIM4_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = 0;
  TIM_OC_InitTypeDef sConfigOC = 0;

  /* USER CODE BEGIN TIM4_Init 1 */

  /* USER CODE END TIM4_Init 1 */
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 0;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 65535;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
  
    Error_Handler();
  
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  
    Error_Handler();
  
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  
    Error_Handler();
  
  /* USER CODE BEGIN TIM4_Init 2 */

  /* USER CODE END TIM4_Init 2 */
  HAL_TIM_MspPostInit(&htim4);


如果您需要更多信息,请告诉我。

【问题讨论】:

请尝试在 SERVO_MoveTo 函数中为 au16_pulse 变量添加 uint16_t 类型转换。 @recep 我添加了这个,但它确实解决了我的问题 【参考方案1】:

我认为您的问题可能是由于备用函数映射。 F767 数据表在第 89 页上有一个表格,列出了您应该将哪些值放入 GPIOn.AFR 寄存器(我假设 HAL 中的 GPIO_InitStruct.Alternate)以在引脚上获得正确的外围设备。看起来这些引脚的定时器通道都是AF1,而且你还没有定义在SERVO_Init 例程中使用哪个 AF。填写结构的每个成员可能是个好主意,即使您认为没有必要,也可以确保不会遗漏任何看似重要的内容。

【讨论】:

我添加了GPIO_InitStruct.Alternate = GPIO_AF1_TIM1,PWM 信号开始生成,但仅在 1.3 分钟后。我测量了几次,它非常一致。你知道为什么会这样吗? 没什么突出的。我期待看到一些忙着等待的人。你能附加一个调试器吗?尝试在 SERVO_Init 函数中的 HAL_TIM_PWM_Start 行上设置断点。如果需要 1.3 分钟才能中断,那就是代码问题。如果它很快到达那里,但之后仍然需要一分钟才能看到波形,这可能是配置或硬件问题。

以上是关于在 stm32 f767zit 上未正确生成 PWM 信号的主要内容,如果未能解决你的问题,请参考以下文章

带有 HAL 库的 STM32F4-Discovery (STM32F429ZIT6) 上的 RS232 (UART)?

STM32-F429ZIT6-开发流程

STM32F767ZI nucleo板没有连接USB

STM32-F429ZIT6-关于驱动安装

定时器触发的STM32F767ZI双ADC模式

stm32f767的adc采样率是多少