Forum: Mikrocontroller und Digitale Elektronik STM32F4: Hilfe bei der Timer Konfiguration


von Christian J. (Gast)


Lesenswert?

Hallo,

auch wenn ich das Datenblatt noch 10 Mal lese wird mir das nicht klarer, 
da die Timer ja eierlegende Wollmilchsäue sind, die auf 150 Seiten 
beschrieben werden :-(

Ich möchte nur eine Infrarot Diode betreiben, die mit 40khz moduliert 
wird und an einem Pin angeschlossen ist, der diese ausgibt. Durch 
einfaches Einschalten soll die Frequenz ausgespruckt werden. Bei einem 
PIC oder AVR würde mir sofort einfallen die Compare Funktion zu 
verwenden und einem Prescaler, etwas rumrechnen und dann wäre es das. 
Der Pin müsste einfach nur toggeln.

Weiss jemand wie man das einem General Pupose Timer beibringt, dass er 
sich so verhält? Oder vielleicht ne Doku, schön auf Deutsch am besten?

Gruss,
Christian

von Manuel W. (multisync)


Lesenswert?

Hallo!

Also die einfachste und billigste Möglichkeit wäre wohl, auf die ganze 
Funktionalität des Timer zu verzichten und sich einfach in regelmäßigen 
Abständen einen Interrupt geben zu lassen, der dann ein Umschalten des 
Pin auslöst.


Für den TIM2 müsste es in etwa so gehen: (Das ist eine reduzierte Form 
des Codes der bei mir läuft, ohne Pistole und Gewähr)
1
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
2
        TIM_CounterModeConfig(TIM2, TIM_CounterMode_Up); // vielleicht nicht notwendig
3
        TIM_ARRPreloadConfig(TIM2, ENABLE); // wohl nicht notwendig, bewirkt, dass die neue Frequenz immer erst bei Start einer neuen Periode übernommen wird.
4
        TIM_PrescalerConfig(TIM2, 0, TIM_PSCReloadMode_Update); // PRESCALER hier anpassen
5
        TIM_SetAutoreload(TIM2, 6000); // Interruptfrequenz hier anpassen
6
7
        /* timer shall generate interrupt at when counter==value */
8
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
9
10
        /* enable timer module */
11
        TIM_Cmd(TIM2, ENABLE);

Dann noch die Interrupt-Routine:
1
void TIM2_IRQHandler()
2
{
3
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) ) {
4
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
5
        }
6
7
        pinToggle();
8
}

In deinem Fall, wenn du wirklich nur eine einzige Art von Interrupt 
bekommst (Update-Interrupt), kannst du dir die Abfrage des 
TIM_GetITStatus() auch sparen.

: Bearbeitet durch User
von ukw (Gast)


Lesenswert?

Schau Dir einfach IRSND an. Da ist auch die Erzeugung der Modulation 
für den STM32 drin. Da muss man kein Bit in der ISR togglen. Das geht 
eleganter.

von Christian J. (Gast)


Lesenswert?

ukw schrieb:
> Das geht
> eleganter.

Das denke ich mir auch, unelegant ist auch unbefriedigend. Schaue ich 
mir mal an. Den Systick will ich auch nicht missbrauchen.

PS: Also ich sehe da nichts von STM32...... für AVR kriege ich das auch 
hin.
Ich denke ich setze einfach ein Testprojekt mal auf und fange an mit den 
Timern zu spielen, Debuggen usw. Dann wird irgendwann mal das Aha kommen 
hoffe ich....

von N. C. (nixchecker)


Lesenswert?

ukw schrieb:
> Das geht eleganter.

Die Aufgabe hört sich für mich wie ein PWM mit 50% an.

von Christian J. (Gast)


Lesenswert?

N. C. schrieb:
> Die Aufgabe hört sich für mich wie ein PWM mit 50% an.

Ja, wenn man es so sieht. Glaube man stellt da einen Comparewert ein und 
sagt, dass dann ein Pin toggelt und ein Reset auf 0 stattfindet. Also 
kein Durchlauf bis Oberkante. PWM ist ja Periode und Teilerverhältnis.

von N. C. (nixchecker)


Lesenswert?


von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian J. schrieb:
> PS: Also ich sehe da nichts von STM32...... für AVR kriege ich das auch
> hin.

IRSND läuft nicht nur auf AVR.

Zitat direkt oben im Artikel:

"Es gibt aber auch Portierungen auf diverse PIC µCs - für den CCS- und 
C18-Compiler. Auch ist IRSND mittlerweile auf ARM STM32 lauffähig."

Musst Du überlesen haben.

Hier ein direkter Link auf irsnd.c:

  https://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup

Den Link auf den Source findest Du auch im Artikel, nämlich unter:

  https://www.mikrocontroller.net/articles/IRSND#Source-Code

In irsnd.c einfach nach STM32 suchen.

P.S.
Im Moment scheint der SVN-Server von µC.net offline zu sein, so dass man 
sich irsnd.c nicht direkt im Browser öffnen kann.

Dann lade Dir das IRSND.zip unter Download herunter, öffne irsnd.c und 
suche darin nach STM32.

: Bearbeitet durch Moderator
von Christian J. (Gast)


Lesenswert?

Frank M. schrieb:
> P.S.
> Im Moment scheint der SVN-Server von µC.net offline zu sein, so dass man
> sich irsnd.c nicht direkt im Browser öffnen kann.

Das hier ist die Stelle:
1
 elif defined (ARM_STM32)                             // STM32
2
519          TIM_SelectOCxM(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_OCMode_PWM1); // enable PWM as OC-mode
3
520          TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);      // enable OC-output (is being disabled in TIM_SelectOCxM())
4
521          TIM_Cmd(IRSND_TIMER, ENABLE);                   // enable counter

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Jaja, der Timerfrust auf dem STM32.
Die Dinger sind sehr mächtig und subtile Unterschiede zwischen den 
einzelnen Varianten erfordern eine gewisse Aufmerksamkeit.

Sag mal an, welcher Chip (e.g. STM32F407VG), Timer/Kanal (TIM4_CH1), Pin 
(PD12). Vielleicht postet Dir "jemand" ein Stückchen Code.

Varianten:
-das Teil auf PWM mit 40kHz Update-Rate zu parametrieren und dann nur 
das CCRx-Register umzuschreiben.

- Du kannst aber auch den Timer starten und stoppen.

- der STM kann aber auch sowas:
 o Dein Bitstrom liegt als TIMy-CCRx Daten im SRAM
 o TIMz ist auf die Bitrate eingestellt
 o bei Update von TIMz wird ein DMA-Request ausgelöst, der die neuen 
CCRx-   Daten in das TIMy-CCRx-register schreibt
 o Interrupt wenn DMA-Sequenz fertig

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
Noch kein Account? Hier anmelden.