Forum: Mikrocontroller und Digitale Elektronik PWM Ausgang erzeugt kein PWM Signal :(


von Hüpfer (Gast)


Lesenswert?

Hallo, ich versuche gerade mit einem STM32F107 Controller am Ausgang PA8 
ein festgelegtes PWM Signal zu erzeugen. Nur Erzeugt der Ausgang nur ein 
High Signal. Habe ich etwas vergessen einzustellen?

Ziel ist es, sobald an PA2 ein High Signal anliegt den Ausgang PA8 mit 
einer festen Frequenz und Tastverhältnis anzusteuern. Nur wie gesagt 
sobald
PA2 == 1 ist PA8 == 1 ohne PWM.
1
void Init_funktion2(void)
2
{
3
4
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO, ENABLE);
5
6
 //Pin PA8 --> Steuersignal für Halbbrücke
7
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;
8
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
10
  GPIO_Init(GPIOA, &GPIO_InitStructure);
11
 
12
13
  /* Time Base configuration */
14
  TIM_TimeBaseStructure.TIM_Prescaler = 1;
15
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
16
  TIM_TimeBaseStructure.TIM_Period = 999;
17
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
18
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
19
20
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
21
22
  /* Channel 1, 2,3 and 4 Configuration in PWM mode */
23
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
24
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
25
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
26
  TIM_OCInitStructure.TIM_Pulse = 50;
27
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
28
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
29
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
30
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
31
32
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
33
34
  // TIM1 counter enable 
35
  TIM_Cmd(TIM1, ENABLE);
36
37
}

Aufruf in der Main
1
int main(void)
2
{
3
  .
4
  .
5
  .
6
 while(ProgFunktion == 2)
7
 {
8
  Init_GPIO();
9
  Init_funktion2();
10
  Init_LED_Port();
11
12
  if (steuereingang == 1)
13
  {
14
    GPIO_ResetBits(GPIOC, GPIO_Pin_5); // LED Einschalten
15
16
    TIM_CtrlPWMOutputs(TIM1, ENABLE)   //PA8 Ausgang
17
  }
18
  else
19
  {
20
    GPIO_SetBits(GPIOC, GPIO_Pin_5);   // LED Abschalten
21
22
    TIM_CtrlPWMOutputs(TIM1, DISABLE)  //PA8 Ausgang 
23
  } 
24
25
}

In den Funktionen Init GPIO() und Init_LED_Port() werden nur die 
Ein/Ausgänge des Steuersignals und der LEDs festgelegt.

Danke schon mal für eure Hilfe.

von Hüpfer (Gast)


Lesenswert?

Hüpfer schrieb:
> //Pin PA8 --> Steuersignal für Halbbrücke
>   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;
>   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
>   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
>   GPIO_Init(GPIOA, &GPIO_InitStructure);

Achso hier habe ich Open Drain genommen, da am Ausgang ein Optokoppler 
sitzt der sobald der Mikrocontroller gegen Masse zieht den Optokoppler 
durchschalten lässt. Und so meine Last schaltet.

von Rene K. (xdraconix)


Lesenswert?

Ich weiß nicht wie dein Programm strukturiert ist... Aber:
1
 while(ProgFunktion == 2)
2
 {
3
  Init_GPIO();
4
  Init_funktion2();
5
  Init_LED_Port();

Bei jedem Schleifendurchgang werden deine Inits neu ausgeführt. Das 
passiert normalerweise nur einmal! Den Timer müsstest du, solltest du 
ihn ändern wollen, auch vorher Stoppen. Das passiert in diesem Fall 
nicht.

Wo hast du &GPIO_InitStructure, &TIM_TimeBaseStructure und 
&TIM_OCInitStructure definiert?

von Hüpfer (Gast)


Lesenswert?

1
void Init_funktion2(void)
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
5
  TIM_OCInitTypeDef TIM_OCInitStructure;
6
7
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO, ENABLE);
8
9
 //Pin PA8 --> Steuersignal für Halbbrücke
10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;
11
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
12
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13
  GPIO_Init(GPIOA, &GPIO_InitStructure);
14
 
15
16
  /* Time Base configuration */
17
  TIM_TimeBaseStructure.TIM_Prescaler = 1;
18
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
19
  TIM_TimeBaseStructure.TIM_Period = 999;
20
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
21
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
22
23
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
24
25
  /* Channel 1, 2,3 and 4 Configuration in PWM mode */
26
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
27
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
28
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
29
  TIM_OCInitStructure.TIM_Pulse = 50;
30
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
31
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
32
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
33
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
34
35
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
36
37
  // TIM1 counter enable 
38
  TIM_Cmd(TIM1, ENABLE);
39
40
}

Hab die Init´s auch gleich aus der While-Schleife raus genommen damit 
die nicht ständig neu Initialisiert werden. Danke für den Tipp
1
int main(void)
2
{
3
  .
4
  Init_GPIO();
5
  Init_funktion2();
6
  Init_LED_Port();
7
8
  while(ProgFunktion == 2)
9
10
  if (steuereingang == 1)
11
  {
12
    GPIO_ResetBits(GPIOC, GPIO_Pin_5); // LED Einschalten
13
14
    TIM_CtrlPWMOutputs(TIM1, ENABLE)   //PA8 Ausgang
15
  }
16
  else
17
  {
18
    GPIO_SetBits(GPIOC, GPIO_Pin_5);   // LED Abschalten
19
20
    TIM_CtrlPWMOutputs(TIM1, DISABLE)  //PA8 Ausgang 
21
  } 
22
23
}

Rene Wie meinst du das mit den Timer stoppen?
Leider hat die Umstrukturierung noch nicht zur Lösung geführt :(

von Rene K. (xdraconix)


Lesenswert?

Hüpfer schrieb:
> Rene Wie meinst du das mit den Timer stoppen?

Es hätte sein können, das dies so gewollt ist wenn der Timer mehrfach 
benutzt wird, das du ihn in dieser Schleife neu setzt. Manche Werte 
werden nur bei ausgeschaltetem Timer in das Timer Register übernommen.

Bist du dir sicher das ProgFunktion immer "2" ist? So das die 
Hauptschleife nicht verlassen wird?

Ist es möglich PA8 mal als PP du deklarieren? Nicht das das OD da nen 
Strich durch die Rechnung macht. Desweiteren denke ich das die 
Timer-Init eigentlich passen müsste.

Im Zeifelsfall einfach mal die Main so ändern das ausschließlich der 
Timer läuft und mit einem Oszi oder einem Freq-Messer mal den Pin 
kontrollieren.

von Hüpfer (Gast)


Lesenswert?

Ja hab mittlerweile alles andere aus der Main rausgenommen, und die 
Variable nochmals direkt vor der While Schleife  auf ProgFunktion = 2, 
gesetzt. Die Schleife wird auch durchlaufen, weil die dort gesetzten 
LED´s auch angehen wenn eigentlich das PWM Signal angesteuert wird. Nur 
wird nur ein reines High Signal ausgegeben (Oszi angeschlossen). Ausgang 
wurde auch auf PP umgeändert, hat aber weiter nix geändert. Ich 
vergleich jetzt nochmal eine Standard Libary von ST mit meinem 
Programmcode.
Vielen Dank dir trotzdem.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Rene K. schrieb:
> Manche Werte
> werden nur bei ausgeschaltetem Timer in das Timer Register übernommen.

Kann man erlauben, wenn man
1
//...standard timer init
2
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
3
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
4
// etc.
5
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
6
// und dann updates erlauben
7
TIM_UpdateRequestConfig(TIM1, TIM_UpdateSource_Global);
8
TIM_UpdateDisableConfig(TIM1,DISABLE);
Desgleichen habe ich gute Erfahrungen mit dieser Zeile als erstes in der 
main gemacht (allerdings beim F100RB des VL Discovery):
1
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
Kann sein, das man das beim F107 nicht braucht. Mein BLDC Drive benutzt 
ebenso PP Ausgänge und nicht OD, also folge mal dem Tipp von René.
Offensichtliche Fehler sehe ich auch nicht, es fehlt noch das DTI, wenn 
du das brauchst und ich zünde mit TIM1 immer eine ISR, es sollte aber 
auch ohne gehen.
Edit: das sieht allerdings merkwürdig aus:

Hüpfer schrieb:
> if (steuereingang == 1)

Wie wird dieser 'steuereingang' gesetzt? Das muss bei dir dann per ISR 
geschehen, denn in der Schleife passiert das nicht.

: Bearbeitet durch User
von Hüpfer (Gast)


Lesenswert?

Matthias S. schrieb:
> Wie wird dieser 'steuereingang' gesetzt? Das muss bei dir dann per ISR
> geschehen, denn in der Schleife passiert das nicht.

Hallo Matthias, ja der Eingang löst eine ISR aus, hab diese aber einfach 
um Fehler auszuschliessen jetzt durch eine einfache Abfrage des Eingangs 
abgeändert.
1
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 1)
2
{
3
  GPIO_ResetBits(GPIOC, GPIO_Pin_5); // LED Einschalten
4
5
  TIM_CtrlPWMOutputs(TIM1, ENABLE)   //PA8 Ausgang
6
}

Zusätzlich habe ich jetzt noch, die von dir Empfohlene Zeile eingefügt.
1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

Die Zeilen bezüglich den Update nimmt er mir nicht an.
1
TIM_UpdateSource_Global
Der Ausgang wurde bereits auf PP umgestellt.

von Rene K. (xdraconix)


Lesenswert?

Hüpfer schrieb:
> Hallo Matthias, ja der Eingang löst eine ISR aus

Ahh.... Infos so Scheibchenweise sind immer doof :-D Wird denn dann der 
Interrupt auch wieder zurückgesetzt in / nach der ISR?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ich weiss, das ich damals auch eine Weile gekämpft habe, ehe das alles 
so funktionierte, allerdings benutze ich auch das DTI und 3 PWM Pärchen.
So sieht das bei mir aus:
1
/* Channel 1, 2 and 3 Configuration in PWM mode */
2
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
3
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
4
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
5
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;   // <<< das ist anders
6
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
7
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
8
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
9
10
TIM_OCInitStructure.TIM_Pulse = 0x0000;
11
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
12
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
13
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
14
// Configure DTI
15
TIM_BDTRStructInit(&TIM_BDTRInitStructure);
16
/* Automatic Output enable, Break, dead time and lock configuration*/
17
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
18
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
19
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
20
TIM_BDTRInitStructure.TIM_DeadTime = deadTime;
21
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
22
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
23
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
24
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

von Hüpfer (Gast)


Lesenswert?

Ja der wurde immer zurück gesetzt am Ende. Hab es aber jetzt um weitere 
Fehler auszuschließen durch
1
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 1)
2
{
3
  GPIO_ResetBits(GPIOC, GPIO_Pin_5); // LED Einschalten
4
5
  TIM_CtrlPWMOutputs(TIM1, ENABLE)   //PA8 Ausgang
6
}
ersetzt und hab den ganzen Handler auskommentiert

von Rene K. (xdraconix)


Lesenswert?

Die LED an C5 schaltet aber ein?!

Übrigens ist TIM_CtrlPWMOutputs für die erweiterten Timer 1 und 8, und 
müssen über BDTR initialisiert werden.

von Hüpfer (Gast)


Lesenswert?

Rene K. schrieb:
> Die LED an C5 schaltet aber ein?!

ja die geht an.

Rene K. schrieb:
> Übrigens ist TIM_CtrlPWMOutputs für die erweiterten Timer 1 und 8, und
> müssen über BDTR initialisiert werden.

das heißt?

von Rene K. (xdraconix)


Lesenswert?


von Hüpfer (Gast)


Lesenswert?

Oh das von Matthias hab ich ganz übersehen.

ich habe jetzt meinen Code um die Zeilen erweitert.
1
TIM_BDTRStructInit(&TIM_BDTRInitStructure);
2
/* Automatic Output enable, Break, dead time and lock configuration*/
3
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
4
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
5
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
6
TIM_BDTRInitStructure.TIM_DeadTime = deadTime;
7
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
8
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
9
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
10
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

oben hab ich noch
1
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
eingefügt.

Was trage ich für deadTime ein bzw ist hier die Zeit die sich aus der 
Off Zeit des Tastverhältnis ergibt nötig?

von Hüpfer (Gast)


Lesenswert?

Aber euch beiden schon mal ein Großes DANKESCHÖN für die tolle Hilfe.

von Rene K. (xdraconix)


Lesenswert?

Ich schnapp mir heute Abend mal mein Nucleo und stell das Mal nach, 
lässt mir ja nun doch keine Ruhe ?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Hüpfer schrieb:
> Was trage ich für deadTime ein bzw ist hier die Zeit die sich aus der
> Off Zeit des Tastverhältnis ergibt nötig?

Du musst die Totzeit nicht aus dem Tastverhältnis ausrechnen. Die 
Totzeit ist auch nur dann relevant, wenn du die Low- und Highside aus 
dem gleichen CCR mit komplementären Signalen gewinnst.
Bei mir steht da schlicht und einfach eine 26 drin, aber ich hatte da 
auch dicke fette Endstufen dran, die etwas Zeit brauchen.

von Martin (Gast)


Lesenswert?

Das Problem ist meistens bei TIM1 und TIM8 (advanced Timer), wenn man 
vergisst, das MOE Bit zu setzen.

Master Output Enable

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Martin schrieb:
> Master Output Enable

Eigentlich 'Main Output Enable'. Sollte beim nächsten Update des Timers 
gesetzt werden, wenn 'Automatic Output Enable' gesetzt ist.

Die Registerbeschreibung ist auf Seite 343/1093 im RM0008 Reference 
Manual für STM32F0x.

von Christopher J. (christopher_j23)


Lesenswert?

Um dir die Fehlersuche mal ein bisschen zu erleichtern habe ich dir 
unten mal ein absolutes Minimalbeispiel angehängt um mit Timer 1 ein 
PWM-Signal zu erzeugen. Die einzelnen Registerzugriffe kannst du dann 
Stück für Stück durch deine eigenen Init-Funktionen ersetzen, bis es 
nicht mehr funktioniert. Dann weißt du zumindest schonmal wo der Fehler 
ist.
1
#include <stm32f1xx.h>
2
3
4
/* 
5
 * This is an example of complementary PWM output with an "advanced timer". 
6
 * We will use the channel 1 of timer 1 and the pins PA8 for CH1 and PB13 for CH1N.
7
 */
8
9
void gpio_init(void) {
10
11
    /*
12
     * Turn on the GPIOA and GPIOB unit,
13
     * -> see section 7.3.7 in the manual
14
     */
15
    RCC->APB2ENR  |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN ;
16
17
18
    /*
19
     * Clear configuration and mode bits of PA8 and PB13
20
     * Set timer pin mode bits to 0b01 -> output mode max. speed 2 MHz
21
     * Set configuration bits to 0b10 -> Alternate function push-pull
22
     * 
23
     * -> see section 9.2.2 in the manual
24
     */
25
    GPIOA->CRH = ((GPIOA->CRH & (~(GPIO_CRH_CNF8 | GPIO_CRH_MODE8))) 
26
                    | GPIO_CRH_MODE8_0
27
                    | GPIO_CRH_CNF8_1);
28
29
    /*
30
     * Repeat procedure to configure PB13. Could be done in one step.
31
     */
32
    GPIOB->CRH = ((GPIOB->CRH & (~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13))) 
33
                    | GPIO_CRH_MODE13_0
34
                    | GPIO_CRH_CNF13_1);
35
}
36
37
38
39
void timer_init(void) {
40
41
    /*
42
     * In this example we have to use at least a "general purpose timer" because
43
     * a "basic timer" has no capture/compare capabilities. 
44
     */
45
46
    /* enable the clock to timer 1 in the APB2 enable register */
47
    RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
48
    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
49
50
    /*
51
     * Timer 1 runs from the APB2 clock which is SCLK, i.e. 72 MHz.
52
     * So we have to divide the APB2 clock by 72000 to get a tick rate
53
     * of 10 kHz. 
54
     */ 
55
    TIM1->PSC = 7200 -1; // timer tick rate = 72.000.000 Hz / (PSC+1) = 10000 Hz
56
57
    /* 
58
     * Set the value to count up to / to count down from.
59
     * This sets the PWM period to 0.2 seconds (= 2000/10000Hz)
60
     */
61
    TIM1->ARR = 2000 -1; 
62
63
64
65
    /*
66
     * Set PWM mode 1
67
     * 
68
     * -> see section 14.4.7 in the manual
69
     */
70
    TIM1->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 );
71
72
73
    /* set the capture compare register to 75% duty cycle for channel 1*/
74
    TIM1->CCR1 = 1500 -1;
75
76
    /* 
77
     * Enable TIM1 CH1 and TIM1 CH1N
78
     * 
79
     * -> see section 14.4.9 in the manual
80
     */
81
    TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE;
82
83
    /*
84
     * Set "main output enable" bit in the "break and dead-time" register of timer 1
85
     * Otherwise you will not see anything at the output.
86
     */
87
    TIM1->BDTR |= TIM_BDTR_MOE;
88
89
    /* 
90
     * Enable the counter by setting the counter enable bit in the control register
91
     * of timer 2.
92
     */
93
    TIM1->CR1 |= TIM_CR1_CEN;
94
95
    /* 
96
     * make timer stop when core is halted while debugging 
97
     * -> see section 31.16.3 in the manual
98
     */
99
    DBGMCU->CR |= DBGMCU_CR_DBG_TIM1_STOP;
100
101
}
102
103
104
/**
105
 * Hello world blinky program with timer hardware pwm
106
 *
107
 */
108
int main(void) {
109
110
    gpio_init();
111
112
    timer_init();
113
114
    while(1);
115
116
}

von Rene K. (xdraconix)


Lesenswert?

Das ist aber die HAL, nicht die StdPeriph oder?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Rene K. schrieb:
> Das ist aber die HAL, nicht die StdPeriph oder?

Weder - noch. Das ist direkte Registerprogrammierung. Kann man auch 
machen, wird aber bei komplexen Sachen, äh, komplex :-)

von Christopher J. (christopher_j23)


Lesenswert?

Ich hatte vergessen zu erwähnen, dass der obige Code implizit davon 
ausgeht, dass bei Aufruf von main() die PLL schon auf 72MHz eingestellt 
ist. Das funktioniert natürlich auch mit 8MHz HSI, nur dann passen die 
Zeitangaben in den Kommentaren nicht mehr und alles läuft um den Faktor 
neun langsamer. Getestet habe ich das auf einem F103 aber das sollte so 
eins zu eins auch auf einem F107 laufen. Man benötigt natürlich noch den 
entsprechenden Header, z.B. stm32f103xb.h für den F103CB. Nutzt man die 
StdPeriphLib hat man den für gewöhnlich sowieso schon.

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.