Forum: Mikrocontroller und Digitale Elektronik STM32F4 Rechteck-Signal


von Frank (Gast)


Lesenswert?

Hallo zusammen,

ich unternehme die ersten Schritte mit der STM32F4 CPU auf dem 
Discovery-Board. Mein Ziel ist es ein Rechtecksignal mit variabler 
Frequenz zu erzeugen (damit sollen später Sensorwerte für eine Data 
Acquisition Unit
übertragen werden).
Die Initialisierung der GPIO`s und der Timer klappt soweit. Des Weiteren 
habe ich auch die Takterzeugung auf den externen 8MHz Quarz vom Board 
angepasst, sodass auch die Frequenzeinstellung des Ausgangspins sich 
nachvollziehen lässt.
Wenn ich das Referenzbuch richtig verstande habe dann zählt der Counter 
bis zu dem Wert der im ARR abgelegt ist und setzt dann beim Erreichen 
des Endwerts das UG-Bit, geniert also ein Update.
Meine Idee war es die Werte im ARR entsprechend zu ändern und somit auch 
andere Frequenzen zu erhalten. Wenn ich das mit festen Werten machen 
bekomme ich auch die entsprechenden Ergebnisse. Lass ich das wie im Code 
in eine Schleife laufen, so ändert sich die Frequenz des Ausgangs 
allerdings nicht von 25Hz nach 10Hz, sondern springt.
Meine Vermutung wenn ich im Debugger schrittweise vorgehe ist, dass der 
Counter letztendlich ja schon läuft nach dem ich das ARR mit einem neuen 
Wert beschrieben habe. Leider finde ich keine Möglichkeit den Counter an 
dieser Stelle explizit wieder bei Null starten zu lassen.
Vielleicht bin ich ja völlig auf den Holzweg was meine Vorgehenweise 
betrifft. Für einen hilfreichen Hinweis zur Problematik wäre ich 
dankbar.
1
GPIO_InitTypeDef  GPIO_InitStructure;
2
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
3
4
void TIMER_Config(void);
5
void GPIO_Config(void);
6
int i=0;
7
8
int main(void) {
9
  TIMER_Config();          // timer configuration
10
  GPIO_Config();           // GPIO configuration
11
12
  while (1) {
13
    for(i=0 ; i<600; i++) {
14
    TIM3->ARR = 999-i;
15
      if (TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) == SET) {  // EGR UG-Bit
16
        TIM_ClearFlag(TIM3, TIM_IT_Update);                   // TIM_DIER UIE-Bit
17
        GPIO_ToggleBits(GPIOD, GPIO_Pin_12);                        
18
        }
19
      }
20
    }
21
}
22
23
void TIMER_Config(void) {
24
  RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3, ENABLE);       // TIM3 clock enable
25
26
  TIM_TimeBaseStructInit (&TIM_TimeBaseStructure);
27
  TIM_TimeBaseStructure.TIM_Prescaler = 4200-1;               // 84Mhz --> 20KHz
28
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
29
  //TIM_TimeBaseStructure.TIM_Period = 400-1;                // 20KH --> 50Hz
30
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
31
  TIM_TimeBaseInit (TIM3, &TIM_TimeBaseStructure);
32
33
  TIM_Cmd(TIM3, ENABLE);                                     // TIM3 enable counter
34
}
35
36
void GPIO_Config(void) {
37
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);     // GPIO "D" clock enable
38
39
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                // LED green
40
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;             // output
41
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;            // pushpull mode
42
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
43
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;          
44
  GPIO_Init(GPIOD, &GPIO_InitStructure);
45
}

von Thomas W. (ratos)


Lesenswert?

Dass die Frequenz springt ist ja auch nicht weiter verwunderlich, wenn 
du in die while(1)-Schleife einfach die for-Schleife reinschreibst. Wenn 
dann darfst du i beispielsweise nur alle 10ms incrementieren, um eine 
"langsame" Veränderung der Frequenz zu erreichen.

von Frank B. (frankbw)


Lesenswert?

Das Problem mit dem Springen ist halt folgendes: Die Frequenz ändert 
sich halt nicht kontinuierlich (ich inkrementiere beispielsweise alle 
10ms) in der Form 10, 11, 12 .... 20Hz, sondern als Beispiel von 15 nach 
11 und dann 18.  Deshalb war meine eigentliche Frage in der Richtung des 
laufenden Counters gerichtet wie ich diesen nach Laden des ARR bei Null 
starten kann (Das Register einfach mit Null beschreiben lässt dann den 
Counter auch dort stehen). Ich denke dort liegt mein eigentliches 
Probelm bzw. habe den Timer mit seinen Counter noch nicht richtig 
verstanden.

von Thomas W. (ratos)


Lesenswert?

Da stellt sich mir dann die Frage:
Springt die Frequenz nur für eine Periode auf einen anderen Wert oder 
länger (wie lange)?
Ohne weitere detaillierte Informationen kann ich dein Problem nicht 
verstehen.
Wenn du den Counter nicht mit 0 beschreiben kannst, dann mach doch 
einfach mal ein Update-Interrupt, in dem ARR beschrieben wird. Dann ist 
der Counter ja sowieso bei 0.

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.