Ich versuche, zu den ST HAL-Bibliotheken zu wechseln, und kann die PWM anscheinend nicht zum Laufen bringen. Kompiliert gut, startet einfach nicht.
In meinem main () rufe ich die Timer-Initialisierungsfunktion auf:
/* TIM3 init function */
void MX_TIM3_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 1300;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim3);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_SET;
sConfigOC.Pulse = 650;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4);
HAL_TIM_PWM_MspInit(&htim3);
}
Das GPIO wird in der HAL_TIM_PWM_MspInit()
Funktion initialisiert :
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(htim_pwm->Instance==TIM3)
{
/* Peripheral clock enable */
__TIM3_CLK_ENABLE();
/**TIM3 GPIO Configuration
PC9 ------> TIM3_CH4
PC8 ------> TIM3_CH3
PC7 ------> TIM3_CH2
PC6 ------> TIM3_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
}}
Schließlich sieht mein main () folgendermaßen aus: (Ich rufe SystemInit () von main auf, weil ich STCube-generierte Dateien mit coocox coide verwende.)
int main(void)
{
SystemInit() ;
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_TIM3_Init();
MX_GPIO_Init();
MX_LWIP_Init();
while (1)
{
}
}
pwm
stm32f4
stm32cubemx
hal-library
Oboist B.
quelle
quelle
Antworten:
Ich bin zu spät zur Party, aber ich befand mich in einer ähnlichen Situation und habe die richtige Antwort oder zumindest die Antwort, die ich persönlich überprüft habe, um mit meinem eigenen STM32-Board und den STM32CubeMx-Treibern zu arbeiten.
memset(&sConfigOC, 0, sizeof(sConfigOC));
Lokale Variablen werden nicht automatisch initialisiert und Sie haben eine unerwartete / unbeabsichtigte Konfiguration, da die HAL basierend auf diesen Handle-Variablen sehr grundlegende Annahmen über den Peripheriezustand trifft. Es ist besonders ärgerlich, wenn sich das Verhalten von Kompilieren zu Kompilieren oder von Funktionsaufruf zu Funktionsaufruf ändert, wenn sich der Stapelspeicher ändert.HAL_TIM_PWM_MspInit()
manuell an. Es wird automatisch aufgerufen, wenn Sie aufrufenHAL_TIM_PWM_Init()
, aber Sie müssen sicherstellen, dass Ihre Handle-Variablen ordnungsgemäß initialisiert sind (siehe Nr. 1 oben).HAL_TIMEx_MasterConfigSynchronization()
wenn Sie nicht von der Standardkonfiguration (nicht verkettet / synchronisiert) wechseln. Es wird nichts schaden, aber es ist auch nicht notwendig.MspInit()
Funktion ist gut, außer dass Sie auch die Uhr des GPIOC-Peripheriegeräts aktivieren sollten.Und die Magie, die verhindert, dass es funktioniert:
HAL_TIM_PWM_Start()
nach jedem AnrufHAL_TIM_PWM_ConfigChannel()
- das erste , wasHAL_TIM_PWM_ConfigChannel()
tut , ist die Timer - Ausgänge (die deaktivierenCCxE
Bits inTIMx_CCER
).HAL_TIM_PWM_ConfigChannel()
aktiviert die Timer-Ausgänge nicht wieder!Da die einzige HAL-Methode zum manuellen Aktualisieren des PWM-Arbeitszyklus abgeschlossen ist
HAL_TIM_PWM_ConfigChannel()
, müssen Sie immer anrufen, daHAL_TIM_PWM_Start()
Sie sonst keinen PWM-Ausgang haben. Ich denke, dies geschieht, weil die normale Arbeitsweise mit PWM darin besteht, die_IT()
oder_DMA()
Varianten von zu verwendenHAL_TIM_PWM_Start()
, und Sie daher den Arbeitszyklus sozusagen "im Hintergrund" aktualisieren.Einige der anderen Antworten (einschließlich der, die Sie als akzeptiert markiert haben) sind falsch:
HAL_TIM_Base_Start()
wederHAL_TIM_Base_Init()
noch andere Nicht-PWM-Anrufe an. Erstens ruft die HAL IhrePWM_MspInit()
Funktion nicht auf, da sich das Peripherie-Handle nicht mehr im Reset-Zustand befindet. Noch wichtiger ist jedoch, dass die PWM (und OC und andere Varianten) die internen Funktionen auf niedriger Ebene ordnungsgemäß aufrufen, ohne dass Sie dies manuell tun. Der ganze Sinn der HAL ist es, sich nicht so sehr um die Details kümmern zu müssen, aber Sie müssen einen guten Überblick darüber haben, was die HAL tut und was sie erwartet. Die vollständige Quelle ist verfügbar und ziemlich gut dokumentiert. Sie müssen es nur lesen.HAL_TIMEx_PWMN_Start()
der anderenTIMEx
Funktionen aufrufen, es sei denn, Sie verwenden die kostenlosen Ausgänge. Auch dies ist in der HAL-Quelle ziemlich gut dokumentiert.quelle
Ich verwende STCubeMX und die generierten HAL-Initialisierungsdateien. Prozess auf meinem F302 Nucleo Board überprüft. Ich habe den erweiterten Timer 1 (TIM1) mit einem normalen und komplementären Ausgang ohne Totzeit eingerichtet.
So habe ich PWM in CubeMX konfiguriert:
Nachdem der Code generiert wurde, müssen wir die PWM noch starten. Dies erfolgt durch Aufrufen der folgenden Funktionen in der Benutzercode-Region vor while (1) in main ():
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); //starts PWM on CH1 pin HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1); //starts PWM on CH1N pin
Verwenden Sie die folgenden Makros in stm32f3xx_hal_tim.h, um die Konfigurationseinstellungen zu ändern.
HAL_TIM_PWM_ConfigChannel()
ist nicht die einzige Möglichkeit, die PWM-Einstellung manuell zu aktualisieren, wie von @akohlsmith angegeben.__HAL_TIM_GET_AUTORELOAD(&htim1); //gets the Period set for PWm __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, dutyCycle); //sets the PWM duty cycle (Capture Compare Value)
Sie müssen nicht erneut anrufen
HAL_TIM_PWM_Start()
. Diese Makros ändern die Einstellung zur Laufzeit.quelle
Bei Verwendung von Cube Mx initialisiert der generierte Code das Timer-Peripheriegerät, startet es jedoch nicht. Die Lösung ist wie von anderen vorgeschlagen: Fügen Sie die Startfunktionen hinzu.
Platzieren Sie diesen Code im Abschnitt "USER CODE" nach dem generierten Code, der aufgerufen wird
MX_TIM3_Init()
.quelle
TIM_CHANNEL_ALL
, aberTIM_CHANNEL1
stattdessen funktioniert (es hat die tatsächliche PWM-Ausgabe am Ausgangspin gestartet). In ähnlicher Weise für die anderen Kanäle 3, unter Verwendung vonTIM_CHANNEL2
,TIM_CHANNEL3
undTIM_CHANNEL14
jeweils in dem AufrufHAL_TIM_PWM_Start()
(SO4 Anrufe in allHAL_TIM_PWM_Start()
).HAL_TIM_Base_Start(&htim3);
wird nicht benötigt (empirisch ermittelt und auch in Akohlsmiths Antwort ).Sie müssen zuerst den Timer starten. Fügen Sie die nächste Zeile hinzu
main()
, um timer3 zu startenCH1
:quelle
Dieser Code funktioniert in CooCox mit Standardbibliotheken STM32f0xx_yyy. Sie müssen auch die GPIOC-Uhr in GPIO init aktivieren.
quelle
Ich denke, Sie müssen die GPIO-Uhr durch einen Anruf initialisieren
__GPIOC_CLK_ENABLE();
Ich habe ähnlichen Code - aber ich habe das Master-Konfigurationsmaterial weggelassen.
Im Ordner stm32g-eval gibt es ein Beispiel, das an das Discovery Board angepasst werden kann (wenn dies das Board ist, das Sie verwenden).
quelle
Sie müssen dazu:
quelle