Mit STM32-HAL-Timer und Einstellen des Duty-Cycle eines PWM-Signals

Benutzte ich die STM32Cube-Initialisierung-code-generator zum erzeugen eines initialisierten Timer-Funktion. Zum generieren einer festen Tastverhältnis PWM-signal, fügte ich HAL_TIM_Base_Start(&htim1); //Starts the TIM Base generation und HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1)//Starts the PWM signal generation an der Timer-Initialisierung-Funktion, wie unten gezeigt.

/* Private variables ---------------------------------------------------------*/
int pulse_width=0;

/* TIM1 init function */
static void MX_TIM1_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 0;//we want a max frequency for timer, so we set prescaller to 0         
  //And our timer will have tick frequency
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 1066;//max value for timer is 16bit = 65535, TIM_Period = timer_tick_frequency /PWM_frequency - 1  
  //In our case, for 15Khz PWM_frequency, set Period to TIM_Period = 16MHz /15KHz - 1 = 1066
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)/* to use the Timer to generate a simple time base for TIM1 */
  {
    Error_Handler();
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;//the default clock is the internal clock from the APBx, using this function
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)//Initializes the TIM PWM Time Base according to the specified
//parameters in the TIM_HandleTypeDef and create the associated handle.
  {
    Error_Handler();
  }

  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  //sConfig: TIM PWM configuration structure
  //set duty cycle: pulse_length = ((1066 + 1) * duty_cycle) /(100 - 1)
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = pulse_width;/* 50% duty cycle is 538, set to 0 initially*///
  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();
  }

  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_TIM_MspPostInit(&htim1);//output pin assignment
    HAL_TIM_Base_Start(&htim1); //Starts the TIM Base generation
  if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)//Starts the PWM signal generation
  {
    /* PWM Generation Error */
    Error_Handler();
  }

  /* Start channel 2 */
  if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2) != HAL_OK)
  {
    /* PWM Generation Error */
    Error_Handler();
  }

}

Dies ist genug, um die PWM auf einen festen duty cycle angegeben in den Kommentaren oben, wenn ich schwer code auf den richtigen Wert zu ersetzen pulse_width Wert insConfigOC.Pulse = pulse_width.
In einer anderen Funktion, ich habe ein Algorithmus, der aktualisiert werden würde, die pulse_width Globale variable. Die Funktion wird aufgerufen: adjust_PWM();. Der Algorithmus berechnen gemessenen Werte aus dem ADC und gespeichert werden als Globale Variablen. Diese Funktion aufgerufen wird: Data_Update();. In main() nach werden alle Funktionen initialisiert. Ich nenne diese drei Funktionen endlos

Data_Update();
adjust_PWM();   
MX_TIM1_Init(); 

Ich habe versucht, und erhalten komisch Wellenformen auf dem Oszilloskop, aber das könnte sein, weil Der ADC-pins, wo Sie schweben, verursacht floating-Messungen zu stören, die mit dem Arbeitszyklus durch den Algorithmus. Auch eingedenk der Initialisierung der timer ständig unterbrechen würden das PWM-signal. Gibt es eine bessere Möglichkeit zum ändern der Einschaltdauer beim ausführen der code ohne die Verwendung von globalen Variablen, oder ohne Initialisierung der timer jedes mal, wenn ich aktualisieren möchten, die Pflicht-Zyklus. Jeder link wäre sehr hilfreich.

Der beste Weg ist, um loszuwerden, die ST "HAL" bloatware und direkt die Register programmiert werden. Das spart die Hälfte der code tatsächlich weniger Aufwand.
direkt die Register programmiert? können Sie näher erläutern für jemanden, der mehr hardware orientiert?
Lesen Sie das Referenz-Handbuch (müssen Sie sowieso), nur die CMSIS und registrieren definition-Header von ST und direkt schreiben/Lesen der Register der Peripherie-Module. Als hardware-orientierte person, diese sollte auch passen Sie viel besser. Auf diese Weise müssen Sie nicht haben, um Geige mit dieser bloatware und die hardware, sondern nur die hardware.
Ich konnte nicht mehr Zustimmen, @Olaf 's Aussage über das fallen der code der Bibliothek. Es ist bestenfalls ein Chaos, und im schlimmsten Fall eine Haftung. Arbeiten aus dem Datenblatt und setzen der Peripheriegeräte bis Ihr selbst, Sie wissen genau, was Los ist. Wenn es eine Plattform, die Sie gehen, um zu arbeiten mit viele werden Sie schließlich am Ende mit Ihrem eigenen HAL-Bibliothek sowieso.
Anstelle von aufrufen MX_TIM1_Init() wiederholt, haben Sie versucht, Sie anzurufen, HAL_TIM_PWM_ConfigChannel() mit der neuen pulse_width Wert?

InformationsquelleAutor Nadim | 2017-04-18

Schreibe einen Kommentar