Forum: Mikrocontroller und Digitale Elektronik stm32f103 3phase-generator


von grundschüler (Gast)


Angehängte Dateien:

Lesenswert?

Ich versuche mich an der Ansteuerung eines FU-ICs mittels Stm32f103C8. 
Anbei die main.c der ersten lauffähigen Version.

Frage zur Deadtime: Diese braucht es beim Umschalten von positiver auf 
negative Halbwelle, damit es keinen Kurzschluss gibt. Bei meiner 
Sinustabelle ist der erste Wert der positiven Halbphase Null. Also von 
48 Werten sind nur 23 größer alws null. Dadurch kann es zwichen den um 
24 Steps versetzten Halbphasen niemals zu einem Kurzschluss kommen.

Kann man die Totzeitberechnung dann einfach weglassen?

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


Lesenswert?

grundschüler schrieb:
> Kann man die Totzeitberechnung dann einfach weglassen?

Warum macht du es dir so schwer? Timer 1 und Timer 8 im STM32F103 sind 
Advanced Timer und haben jeweils 3 PWM Kanäle mit komplementären 
Ausgängen und einem Deadband Unit pro PWM. Ein einziger Timer erzeugt 
ohne Klimmzüge alle 3 Phasen mit einstellbarer Totzeit.

Je nach Gehäuse hat evtl. nur ein Timer der beiden alle Anschlüsse 
herasugeführt, aber das findest du anhand des Datenblattes schnell raus.

von grundschüler (Gast)


Lesenswert?

Matthias S. schrieb:
> Warum macht du es dir so schwer?

Gerade einfach hast du es dir mit dem AVR ja auch nicht gemacht. Am 
einfachsten wäre es, deinen code zu nehmen und keine Fragen mehr zu 
stellen. Ich habe da ein Verständnisproblem von dem ich nicht weiß, ob 
es an mir (wahrscheinlich) oder ob es an deinem code (unwahrscheinlich) 
liegt. Ich will halt wissen, wie es funktioniert.

Der Stm-Tim1 ist sehr komplex. Es gibt fertigen code - 
https://arm-stm.blogspot.de/2015/01/3-phase-sinusoidal-pulse-width.html 
- den ich noch nicht ausprobiert habe.

Mit tim2, tim3, + tim4 geht es halt sehr einfach weil genug 
Rechenleistung da ist und weil dise tims einfach zu handeln sind. Also 
mache ich es mir eher so einfach wie möglich.

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


Lesenswert?

grundschüler schrieb:
> Gerade einfach hast du es dir mit dem AVR ja auch nicht gemacht.

So einfach wie möglich. Der kleine AVR8 hat nun mal keinen Timer mit 3 
PWM Kanälen, sondern nur 3 Timer mit je 1 PWM Kanal. Deswegen die 
Klimmzüge beim 3 Phasen Generator.
Die STM32 und XMega hingegen haben fertige Blöcke für den Betrieb von 
Motoren, die man nur benutzen muss.

grundschüler schrieb:
> Also
> mache ich es mir eher so einfach wie möglich.

Nö. Mit einem Advanced Timer brauchst du nur eine ISR, um alles zu 
laden. Mein BLDC Antrieb mit Sinusmodulation auf dem STM32 ist deutlich 
unkomplizierter als der gleiche Antrieb lt. AVR447. Vllt. portiere ich 
den 3-Phasen Generator mal aufs VL Discovery - die liegen hier im Moment 
sowieso nur rum.

von noreply@noreply.com (Gast)


Lesenswert?

@grundschüler

Hier ein Ansatz von St, den ich nur mal vorsichtshalber gezogen habe.
http://www.st.com/en/embedded-software/stsw-stm32100.html

Die beschriebene Software habe ich in einen chinesischen Forum gefunden, 
aber noch nicht evaluiert. Sind zwei *.exe. Die würden nach genauer 
Untersuchung verlangen. Deswegen kein Link.

von noreply@noreply.com (Gast)


Lesenswert?

Nachtrag.

Man bekommt auch Software von ST. Da muß man erst Java-Script zulassen 
und diverse Lizenzen unterschreiben und Namen angeben.

von grundschüler (Gast)


Lesenswert?

Hier mal der Versuch, alles in den advanced timer zu packen 
/Ukmschaltung nur eine Phase. Ich brauche ja 6 um jeweils 60° versetzte 
Halbphasen. Tim1 hat aber nur 3*2+1 channel. Ganz zufrieden bin ich mit 
dem Ergebnis noch nicht. Nach dem Umschalten scheint der abgeschaltete 
Channel nachzuschwingen.

1
void TIM1_CC_IRQHandler(void)
2
{
3
  period= speedmult*255/speeddiv;
4
  pulse_vh= speedmult*sinetable[step]/speeddiv;
5
  pulse_uh= speedmult*sinetable[step+8]/speeddiv;
6
  pulse_wh= speedmult*sinetable[step+16]/speeddiv;
7
  TIM1->ARR = period;
8
  TIM1->CCR1 = pulse_uh;
9
  TIM1->CCR2 = pulse_vh;
10
  TIM1->CCR3 = pulse_wh;
11
12
switch (step)
13
{
14
  case (0)://change ch1n to ch1
15
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
16
  TIM_OCInitStructure.TIM_OutputNState= TIM_OutputNState_Disable;
17
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
18
    ;
19
    break;
20
21
  case (48)://change ch1 to ch1n
22
    TIM1->CCER&=~(1<<0);//CC1E löschen
23
        TIM1->CCER|=(1<<2);//CC1NE setzen
24
/**/
25
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputNState_Disable;
26
  TIM_OCInitStructure.TIM_OutputNState= TIM_OutputState_Enable;
27
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
28
   ;
29
    break;
30
31
  default:
32
    ;
33
    break;
34
}
35
36
37
zl_tim1++;
38
39
step++;
40
if(step>(47)){
41
  step=0;
42
  led1_tog;
43
  speed_ctrl++;
44
}
45
46
TIM_ClearFlag(TIM1,TIM_FLAG_CC1);
47
}

noreply@noreply.com schrieb:
> http://www.st.com/en/embedded-software/stsw-stm32100.html

Hab ich installiert, c-code wär mir aber lieber.

von Vincent H. (vinci)


Lesenswert?

Ich hab mal einen FU mit einem STM32F405 und dessen TIM1 gebaut. Code 
für den Timer ist hier:
https://gitlab.com/higaski/stm32f405_vfd/blob/master/Src/Periph/pwm.c

Deadtime hab ich damals keine gebraucht, da die in Hardware realisiert 
war. Jeder brauchbare Treiber bietet aber mittlerweile solche Optionen 
an.

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


Lesenswert?

Vincent H. schrieb:
> Ich hab mal einen FU mit einem STM32F405 und dessen TIM1 gebaut.

Sieht allerdings mehr nach einem BLDC Antrieb für Motoren mit 
Hallsensoren aus.
Der STM32F1xx hat eine Deadtime Unit:
1
void UpdateDTI(u8 deadTime){
2
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
3
4
TIM_BDTRStructInit(&TIM_BDTRInitStructure);
5
/* Automatic Output enable, Break, dead time and lock configuration*/
6
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
7
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
8
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
9
TIM_BDTRInitStructure.TIM_DeadTime = deadTime;
10
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
11
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
12
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
13
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
14
}

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Als Hilfe poste ich dir mal die Init von Timer 1 für 3 PWM Kanäle:
1
/* init the main PWM Timer 1 with 3 channels and dead time insertion
2
 *
3
 */
4
void TimerInit(u8 deadTime) {
5
6
RCC_APB2PeriphClockCmd(TIM1_CLK, ENABLE);
7
/* Initialize basic structures to default */
8
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
9
TIM_OCStructInit(&TIM_OCInitStructure);
10
/* Time base configuration */
11
12
TIM_TimeBaseStructure.TIM_Prescaler = 256;
13
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
14
TIM_TimeBaseStructure.TIM_Period = 0x00FF;
15
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
16
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
17
18
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
19
TIM_UpdateRequestConfig(TIM1, TIM_UpdateSource_Global);
20
TIM_UpdateDisableConfig(TIM1,DISABLE);
21
22
/* Channel 1, 2 and 3 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_OCPolarity = TIM_OCPolarity_High;
27
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
28
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
29
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;
30
31
TIM_OCInitStructure.TIM_Pulse = 0x0000;
32
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
33
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
34
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
35
36
UpdateDTI(deadTime);
37
}

Und so initialisiere ich die 6 PWM Ausgänge:
1
// from setup.h
2
#define TIM1_CLK                    RCC_APB2Periph_TIM1
3
// Channel 1
4
#define PHASE_UL_GPIO_PORT                GPIOA
5
#define PHASE_UL_GPIO_PIN                 GPIO_Pin_8
6
// Channel 2
7
#define PHASE_VL_GPIO_PORT                GPIOA
8
#define PHASE_VL_GPIO_PIN                 GPIO_Pin_9
9
// Channel 3
10
#define PHASE_WL_GPIO_PORT                GPIOA
11
#define PHASE_WL_GPIO_PIN                 GPIO_Pin_10
12
// Group configuration
13
#define LOWSIDE_PINS PHASE_UL_GPIO_PIN | PHASE_VL_GPIO_PIN | PHASE_WL_GPIO_PIN
14
// Complementary N Outputs
15
#define PHASE_UH_GPIO_PORT                GPIOB
16
#define PHASE_UH_GPIO_PIN                 GPIO_Pin_13
17
//
18
#define PHASE_VH_GPIO_PORT                GPIOB
19
#define PHASE_VH_GPIO_PIN                 GPIO_Pin_14
20
//
21
#define PHASE_WH_GPIO_PORT                GPIOB
22
#define PHASE_WH_GPIO_PIN                 GPIO_Pin_15
23
// Group configuration
24
#define HIGHSIDE_PINS PHASE_UH_GPIO_PIN | PHASE_VH_GPIO_PIN | PHASE_WH_GPIO_PIN
25
// define Motor Port properties for the two needed ports
26
#define PHASE_UH_GPIO_CLK RCC_APB2Periph_GPIOA
27
#define PHASE_UL_GPIO_CLK RCC_APB2Periph_GPIOB
28
// end from setup.h 
29
//*****************************************************
30
// in main.c
31
void PortInit(void)
32
{
33
GPIO_InitTypeDef  GPIO_InitStructure;
34
/* Motor Port setup for all six phases */
35
// Port A
36
RCC_APB2PeriphClockCmd(PHASE_UH_GPIO_CLK, ENABLE);
37
// Port B
38
RCC_APB2PeriphClockCmd(PHASE_UL_GPIO_CLK, ENABLE);
39
// Highsides are on Port A
40
GPIO_InitStructure.GPIO_Pin = HIGHSIDE_PINS ;
41
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
42
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
43
GPIO_Init(PHASE_UH_GPIO_PORT, &GPIO_InitStructure);
44
// Preset to Off
45
GPIO_ResetBits(PHASE_UH_GPIO_PORT, HIGHSIDE_PINS);
46
// LowSides are on Port B
47
GPIO_InitStructure.GPIO_Pin = LOWSIDE_PINS ;
48
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
49
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
50
GPIO_Init(PHASE_UL_GPIO_PORT, &GPIO_InitStructure);
51
// Preset to Off
52
GPIO_ResetBits(PHASE_UL_GPIO_PORT,LOWSIDE_PINS) ;
53
}

Und hier Timer 1 Interrupt Config:
1
void EnableInterrupts(void){
2
NVIC_InitTypeDef NVIC_InitStructure;
3
// Timer interrupt
4
/* TIM Interrupts enable */
5
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
6
/* TIM1 counter enable */
7
/* Enable and set TIM1 Interrupt to the lowest priority */
8
/* Enable the TIM1 global Interrupt */
9
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM16_IRQn;
10
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
11
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
12
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
13
NVIC_Init(&NVIC_InitStructure);
14
TIM_Cmd(TIM1, ENABLE);
15
/* Main Output Enable */
16
//TIM_CtrlPWMOutputs(TIM1, ENABLE);
17
TIM_ClearITPendingBit(TIM1,TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3);
18
}

Der Timer 1 Interrupt ist bei mir motorspezifisch, aber das Prinzip ist 
das gleiche wie beim AVR Frequenzumrichter. Also inco addieren, Zeiger 
in die Tabelle berechnen, Werte aus der Tabelle skalieren und dann auf 
alle 3 OC Register schicken.

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Matthias S. schrieb:
> Vincent H. schrieb:
>> Ich hab mal einen FU mit einem STM32F405 und dessen TIM1 gebaut.
>
> Sieht allerdings mehr nach einem BLDC Antrieb für Motoren mit
> Hallsensoren aus.
> Der STM32F1xx hat eine Deadtime Unit:
>
1
> 
2
> void UpdateDTI(u8 deadTime){
3
> TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
4
> 
5
> TIM_BDTRStructInit(&TIM_BDTRInitStructure);
6
> /* Automatic Output enable, Break, dead time and lock configuration*/
7
> TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
8
> TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
9
> TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
10
> TIM_BDTRInitStructure.TIM_DeadTime = deadTime;
11
> TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
12
> TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
13
> TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
14
> TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
15
> }
16
>


Woran soll man das sehen?
Ich seh keine Initialisierung für Hallsensoren?
Drehgeber hab ich damals glaub ich benutzt, aber die sind woanders 
initialisiert.

Hab mir meinen Code grad nochmal angesehn und die Deadtime ist sogar 
drin... auch wenn meine Treiber die damals wie gesagt inkludiert hatten.

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


Lesenswert?

Vincent H. schrieb:
> Woran soll man das sehen?

Du erwähnst die Messung des Motorstroms im Programm und durchläufst die 
für BLDC typischen 6 Sektoren.

von Vincent H. (vinci)


Lesenswert?

Matthias S. schrieb:
> Vincent H. schrieb:
>> Woran soll man das sehen?
>
> Du erwähnst die Messung des Motorstroms im Programm und durchläufst die
> für BLDC typischen 6 Sektoren.


Achso, ja der Eindruck täuscht. Die "6 Sektoren" entstehen durch die 
Schaltzeiten der Brücke und bilden die möglichen Zustände aller 6 
Schalter ab. Je nachdem welche Schalter gerade offen bzw. zu sind, wird 
ein anderer Phasenstrom gemessen.

von grundschüler (Gast)


Lesenswert?

Vielen Dank für die Beiträge.

Vincent H. schrieb:
> Ich hab mal einen FU mit einem STM32F405 und dessen TIM1 gebaut.

Wenn ichs richtig verstehe, werden die Halbbrücken blockweise - also 
nicht mit einem trägerfrequenzmodulierten Sinus angesteuert?



Matthias S. schrieb:
> Als Hilfe poste ich dir mal die Init von Timer 1 für 3 PWM Kanäle:

Ich würde ja deinen avr-code komplett auf arm umsetzen, wenn ich ihn 
verstehen würde.


Nach meinem Konzept wird die positive Halbbrücke jeder Phase sinusförmig 
mit einem Ausgang angesteuert während der korrespondierende Ausgang der 
negativen Halbbrücke aus ist und keinen Puls generiert. Ich brauche 
jeweils 6 unterschiedliche Werte aus der Sinetable.

Nach deinem code
1
      InsertDeadband(tempU, &compareHigh, &compareLow);
2
  OCR0A = compareHigh;
3
  OCR0B = compareLow;

scheinen beide Halbbrücken gleichzeitig invertiert angesteuert zu 
werden? Du brauchst nur 3Werte aus der Sinetable.


Ist mein Konzept grundsätzlich falsch?

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


Lesenswert?

grundschüler schrieb:
> Nach deinem code
>       InsertDeadband(tempU, &compareHigh, &compareLow);
>   OCR0A = compareHigh;
>   OCR0B = compareLow;
> scheinen beide Halbbrücken gleichzeitig invertiert angesteuert zu
> werden? Du brauchst nur 3Werte aus der Sinetable.

Richtig 3 Werte, 'InsertDeadband()' berechnet die Werte für compareHigh 
und compareLow aus tempU. Das gleiche passiert gleich darauf auch für 
tempV und tempW.
Beim STM32 kannst du darauf verzichten, wenn du das DTI benutzt - das 
Dings fügt von alleine eine Totzeit zwischen den low und High Ausgängen 
ein.
Du musst auch leglich CCR1 schreiben und nicht wie beim AVR OC0A und 
OC0B.

Die Kernroutine im Timer1 Interrupt sieht dann so aus:
1
      uint8_t tempU, tempV, tempW;
2
      {
3
        uint8_t sineTablePtr ;
4
        AdjustSineTableIndex(sineTableIncrement);
5
// Add sine table offset to pointer. Must be multiplied by 3, since one 
6
// value for each phase is stored in the table.
7
        sineTablePtr =(uint8_t)(sineTableIndex >> 8) * 3;
8
        tempU = sineTable[sineTablePtr++];
9
        if (GetDesiredDirection() == DIRECTION_REVERSE)
10
        {
11
          tempV = sineTable[sineTablePtr++];
12
          tempW = sineTable[sineTablePtr];
13
        }
14
        else
15
        {
16
          tempW = sineTable[sineTablePtr++];
17
          tempV = sineTable[sineTablePtr];
18
        }
19
      }
20
/* Scale sine modulation values to the current amplitude
21
 * and poke them into the Compare registers
22
 */
23
      TIM_SetCompare1(TIM1,(uint16_t)(amplitude * tempU) >> 8);
24
      TIM_SetCompare2(TIM1,(uint16_t)(amplitude * tempV) >> 8);
25
      TIM_SetCompare3(TIM1,(uint16_t)(amplitude * tempW) >> 8);

: Bearbeitet durch User
von grundschüler (Gast)


Lesenswert?

Also ist mein 6-werte-Ansatz grundsätzlich falsch?

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


Lesenswert?

grundschüler schrieb:
> Also ist mein 6-werte-Ansatz grundsätzlich falsch?

Er ist unnötig redundant. Sowohl die AVR Software als auch der STM32 
brauchen nur 3 Werte. Der AVR macht daraus mit InsertDeadband() zwei 
Werte (für High und Low) und beim STM32 machts das DTI und die gewählte 
Polarität der PWM Ausgänge aus einem Wert pro Phase.

von grundschüler (Gast)


Lesenswert?

Matthias S. schrieb:


Dein code läuft ja bei mir  auf einem m328. Ich werd mir das mal mit 
einem la anschauen, was da an Werten konkret rauskommt. Der 
6-werte-Modus hat halt den Vorteil, dass er den Sinus direkt nachbildet 
und unkompliziert zu programmieren ist.

von Vincent H. (vinci)


Lesenswert?

grundschüler schrieb:
> Vielen Dank für die Beiträge.
>
> Vincent H. schrieb:
>> Ich hab mal einen FU mit einem STM32F405 und dessen TIM1 gebaut.
>
> Wenn ichs richtig verstehe, werden die Halbbrücken blockweise - also
> nicht mit einem trägerfrequenzmodulierten Sinus angesteuert?


Nein, der Code verwendet nur keine Sinus-Tabelle, erzeugt aber genauso 
einen Drehvektor. In Zeile 316 steht der Sinus sogar als Funktionsaufruf 
drin. Ein STM32F405 hat mehr als genug Saft um die nötigen Sinus-Werte 
"on demand" zu berechnen. (sogar in double...)

Ob das jetzt sinnvoll ist oder nicht, sei mal dahingestellt.

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


Lesenswert?

grundschüler schrieb:
> Der
> 6-werte-Modus hat halt den Vorteil, dass er den Sinus direkt nachbildet
> und unkompliziert zu programmieren ist.

Ich sehe das nicht so als Vorteil. Denn du bist dann fix auf Totzeit 
etc. festgelegt.

Vincent H. schrieb:
> Ein STM32F405 hat mehr als genug Saft um die nötigen Sinus-Werte
> "on demand" zu berechnen.

Sicher richtig, vor allem, wenn man die Hardware FPU benutzt. Wir 
spielen hier in der Liga STM32F1nn, wo man das leider nicht so hat und 
meist auch nur mit 25MHz taktet.

von grundschüler (Gast)


Lesenswert?

Matthias S. schrieb:
> Wir
> spielen hier in der Liga STM32F1nn

Das stm32f426-disco kostet unter 30€. Angesichts des Aufwands - den wir 
ohnehin alle betreiben - sollten 30€ für die bestmögliche mcu kein 
Hindernis sein.

Ich hatte mir für das avr-Projekt extra einen 328pb - mit zusätzlichen 
Timern - zugelegt.


Vincent H. schrieb:
> In Zeile 316 steht der Sinus sogar als Funktionsaufruf
> drin.

Ich werde deinen code auch mal ausprobieren.

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


Lesenswert?

grundschüler schrieb:
> Das stm32f426-disco kostet unter 30€

So etwas gibt es nicht. Es gibt ein F407 Discovery und ein F429 Dicovery 
Board.
http://www.st.com/en/evaluation-tools/stm32-mcu-discovery-kits.html?querycriteria=productId=LN1848
Ausserdem ist es hilfreich, sich vor der Beschaffung mal eine 
Pinbelegung des Boards anzuschauen, denn die meisten Ports sind auf den 
Disco Boards belegt:
http://mikrocontroller.bplaced.net/wordpress/?page_id=46
http://mikrocontroller.bplaced.net/wordpress/?page_id=2848

Ich habe mit beiden Boards und dem VL-Discovery mit STM32F100 
gearbeitet. Für einen Motorantrieb oder FU ist das VL-Disco gut 
geeignet, weil es billig ist und alle Ports verfügbar sind.
http://www.st.com/en/evaluation-tools/stm32vldiscovery.html

: Bearbeitet durch User
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.