Hallo STM32-Fans! Hier die Beschreibung einer Situation, die vermutlich nur für mich als STM32-Einsteiger ein Problem darstellt. Gegeben ist: Controller: STM32F407VG Hardware: STM32F407-Discovery IDE: CooCox 1.5.0 ARM GCC Toolchain: 4.6 2012q2 ST-Library: STM32F4xx_DSP_StdPeriph_Lib_V1.0.1 Es geht um das banale Thema PWM-Ausgabe auf einem Port. Das unten aufgeführte Listing funktioniert. Es verwendet den GPIOC-Pin 6, Timer 3 und dessen Channel 1. Wenn GPIOC-Pin 7 verwendet werden soll, muss Channel 2 gesetzt werden, damit es funktioniert. Die Wahl eines beliebigen Ports ist anscheinend nicht möglich. Die Doku zum Controller lässt jedoch anderes vermuten. Daher die Frage: Ist die Ausgabe eines PWM-Signals an bestimmte Ports gebunden? Wenn ja, wo finde Informationen dazu? Hier das Listing: /** ************************************************************************ ****** * @file Test_PWM_STM32F407VG/main.c * @author Rainer Reusch, based on source from Andrew Markham * @version V1.0.0 * @date 14-Sept-2012 * @brief Main program body ************************************************************************ ****** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_conf.h" #include <stdio.h> /* Definitions ---------------------------------------------------------------*/ #define PWM_PORT GPIOC // used port for PWM output #define PWM_PIN 6 // used pin for PWM output #define RCC_AHB1Periph_PWM_PORT RCC_AHB1Periph_GPIOC // clock for used port /* Private typedef -----------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Private functions ---------------------------------------------------------*/ /** * @brief Configure the TIM3 Output Channels * @param None * @retval None */ void TIM_ConfigDiscovery(void) { GPIO_InitTypeDef GPIO_InitStructure; /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIO clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_PWM_PORT, ENABLE); /* GPIO Configuration: TIM3 CH1 */ GPIO_InitStructure.GPIO_Pin = 1<<PWM_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(PWM_PORT, &GPIO_InitStructure); /* Connect TIM3 pins to AF2 */ #if (PWM_PIN<8) PWM_PORT->AFR[0]=2<<(PWM_PIN<<2); // Pin 0..7 #else PWM_PORT->AFR[1]=2<<((PWM_PIN-8)<<2); // Pin 8..15 #endif } void PWM_Config(int period) { uint16_t PrescalerValue = 0; /* Compute the prescaler value */ PrescalerValue = 16; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = period; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); // TIM3 enable counter TIM_Cmd(TIM3, ENABLE); } /** * @brief Main program * @param None * @retval None */ int main(void) { SCB->VTOR = SRAM_BASE; // Vector Table Relocation in Internal SRAM TIM_ConfigDiscovery(); // configure Timer PWM_Config(800); // PWM Configuration TIM3->CCR1 = 100; // set duty cycle while (1) { } }
> Wenn ja, wo finde Informationen dazu?
Wo, wenn nicht im Datenblatt oder RefMan?
Es gibt meistens noch einen alternativen Pin aber ansonsten ist die Ausgabe an einen bestimmten Pin gebunden -> RefMan
Die Bemerkung von Toralf und ein gefundener Hinweis im Reference Manual haben die Lösung gebracht. Die GPIOx->AFR Register bieten vom Konzept her zwar die Möglichkeit, eine PWM (oder eine andere Funktion) an jeden beliebigen GPIO-Pin zu legen, in der Praxis funktionieren jedoch nur wenige. Welche, das steht im Datenblatt zum Controller. Für den im Beispiel verwendeten Timer 3 und dessen Channel 1 beim STM32F407VG können PA6, PB4 und PC6 für die PWM-Ausgabe verwendet werden. Für andere Channels und andere Timer gelten andere Ports. Fazit: Im Reference Manual steht nicht alles und der STM32 ist auch keine Wundertüte mit den endlosen Möglichkeiten!
Rainer Reusch schrieb: > der STM32 ist auch > keine Wundertüte mit den endlosen Möglichkeiten! Die muss erst noch Erfunden werden. Wer schon heute eine findet, lasst es mich wissen :-)
Rainer Reusch schrieb: > Fazit: Im Reference Manual steht nicht alles und der STM32 ist auch > keine Wundertüte mit den endlosen Möglichkeiten! Wer hat denn dies als Wundertüte verkauft :-) Wäre aber schon an einem STM32F4DIL interessiert. PPS cross bars gibt's bei einigen PIC32. M. W. tendenziell eher bei den Chips, welche wenig Pins haben. Die mit vielen Pins haben m. W. dann wiederum eher keine Crossbar. Der genannte stm32f407 hat ca. 15 Timer und reichlich Rechenpower, da kann eine SW PWM in einer ISR an jeden Pin gebunden werden.
Eine Software-PWM ist und bleibt eine Notlösung. Auch wenn man viel
Rechenpower hat, wird man die meistens besser zu nutzen wissen.
> Wäre aber schon an einem STM32F4DIL interessiert.
Das ist zumindest schon mal angedacht. Wenn, dann allerdings wohl "nur"
mit dem STM32F405RGT6. Der hat 64 Pins.
Für mein nächsten Projekt ist dieser vermutlich zu klein. Deshalb ist
die Motivation, ein Modul für den Dual-In-Line-Sockel zu entwickeln,
z.Zt. nicht sehr ausgeprägt. Es sei denn, so ein Modul stößt auf
allgemeines Interesse. Wer will, kann mir über die E-Mail-Adresse
stm32f4dil@reworld.eu sein Interesse bekunden (bitte nur Ernst
gemeinte). Sollte es das Modul dann tatsächlich mal geben, würde ich die
Interessenten informieren.
Wo hat ihr im "RM0090 Reference manual" eingentlich diese Mapping gefunden? Ich kann das nicht finden ..... :-( Danke -Marco
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.