Forum: Mikrocontroller und Digitale Elektronik STM32F100 - Timer2_Channel3


von Felix C. (felix_c13)


Lesenswert?

Hallo allerseits,

Zur Ansteuerung von BLDC-Motoren brauche ich 6 PWM Channel. Ich hatte 
mir das so überlegt:

PA1   Motor1   TIM2_CH2
PA6   Motor2   TIM3_CH1
PA7   Motor3   TIM3_CH2
PB0   Motor4   TIM3_CH3
PB1   Motor5   TIM3_CH4
PB10  Motor6   TIM2_CH3

Die PWM's für Motor 1-5 laufen perfekt, nur TIM2_CH3 macht 
Schwierigkeiten. Soll heissen ich krieg einfach kein Signal.

Was die Verdrahtung angeht. Ich arbeite mit dem STM32F100Discovery. Da 
ist nichts an PB10 und PA2 angeschlossen. Wieso PA2??? Komme gleich 
drauf.
Was PA2 und PB10 angeht die leben beide noch, habe ich per simpler 
GPIO-Funktion ausgetestet.

Was nun PA2 angeht:
Da ich mir sicher sein wollte, dass ich im Dussel nicht gerafft habe, 
dass TIM2_CH3 gar nicht auf PB10 liegt, habe ich nochmal ins Datasheet 
geschaut und was? TIM2_CH3 liegt standardmässig auf PB10 und PA2, nicht 
geremappt, einfach so.

Ich bin jetzt ehrlich etwas verwirrt und wäre euch um Unterstützung sehr 
dankbar.

Gruss Felix

Hier noch der Source meiner Init:

void motorinit(void){
  uint32_t temp;
  GPIO_InitTypeDef GPIO_InitStructure;
  TIM_TimeBaseInitTypeDef Timer_InitStructure;

  TIM_OCInitTypeDef Timer_OutputInit;

  //Initialize the needed GPIO's
  GPIO_InitStructure.GPIO_Pin = 
GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_6|GPIO_Pin_7;    /* Motor 1, 2, 3  */
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10;  /* 
Motor 4, 5, 6  */
  //Speed is same.
  //Mode is same.
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /*
  The timer shall run at 50Hz -> Period of 20ms
  at 25MHz this are 500000 ticks per period. We want to have 1000us to 
2000us to be adjustable
  at a resolution of 9bit double resolution of our input. So the period 
needs to have a size of
  20*512 --> 10240. 500'000/10'240 = 48,828. With the prescaler set to 
49 values our period measures
  a bit more than 20ms. This blurres the ratio 512 ticks <--> 1000us, 
but can forget about this
  since we need to adjust the exact range for each motor individually.

  Initially set the CCRx to 0, to pull those pins low.

  Remember f = Ticks_Per_Second/(Register_Value + 1)
  */

  //Initialize TIM2 and TIM3 for PWM
  Timer_InitStructure.TIM_Prescaler = 48;
  Timer_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  Timer_InitStructure.TIM_Period = 10239;
  Timer_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  Timer_InitStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM2, &Timer_InitStructure);

  //Keep everything the same.
  TIM_TimeBaseInit(TIM3, &Timer_InitStructure);

  //ARPE isn't needed since we load the ARR values just a single time.

  Timer_OutputInit.TIM_OCMode = TIM_OCMode_PWM1;
  Timer_OutputInit.TIM_OutputState = TIM_OutputState_Enable;
  Timer_OutputInit.TIM_Pulse = 0x2000;
  Timer_OutputInit.TIM_OCPolarity = TIM_OCPolarity_High;
  Timer_OutputInit.TIM_OCIdleState = TIM_OCIdleState_Reset;

  //TIM2_CH2 --> Motor1
  TIM_OC2Init(TIM2, &Timer_OutputInit);
  //TIM3_CH1 --> Motor2
  TIM_OC1Init(TIM3, &Timer_OutputInit);
  //TIM3_CH2 --> Motor3
  TIM_OC2Init(TIM3, &Timer_OutputInit);
  //TIM3_CH3 --> Motor4
  TIM_OC3Init(TIM3, &Timer_OutputInit);
  //TIM3_CH4 --> Motor5
  TIM_OC4Init(TIM3, &Timer_OutputInit);
  //TIM2_CH3 --> Motor6
  TIM_OC3Init(TIM2, &Timer_OutputInit);

  //Enable CCR preload for all channels
  //TIM2_CH2 --> Motor1
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
  //TIM3_CH1 --> Motor2
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
  //TIM3_CH2 --> Motor3
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
  //TIM3_CH3 --> Motor4
  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
  //TIM3_CH4 --> Motor5
  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
  //TIM2_CH3 --> Motor6
  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);

  //Enable the timers.
  TIM_Cmd(TIM2, ENABLE);
  TIM_Cmd(TIM3, ENABLE);

  // Enable Main Output
  //TIM_CtrlPWMOutputs(TIM2, ENABLE);




}  //End of motorinit()

von aSma>> (Gast)


Lesenswert?

Servus,
nehme den Advanced Timer, denn dieser ist dafür prädestiniert.

mfg

von Felix C. (felix_c13)


Lesenswert?

aSma>> schrieb:
> nehme den Advanced Timer, denn dieser ist dafür prädestiniert.

Timer1? Den wollte ich eigentlich für meine Lampen nehmen. Mit nem 
anderen Prescaler.

Habe das ganze jetzt noch mit dem Cube ausprobiert. Den rühr ich eig nie 
an. Der Scheiss-Channel will einfach nicht.

von aSma>> (Gast)


Lesenswert?

Formatiere mal deinen Code, sonst habe ich kein Bock drüber zu gucken. 
Oder hänge als .c Datei an.

> Timer1?
Jep. Der hat sogar die benötigten komplementär Ausgänge. Da braucht man 
sich nicht die Beide zu verbiegen wie eine H... .

So nebenbei den AFIO clock vermisse ich hier.

von Felix C. (felix_c13)


Angehängte Dateien:

Lesenswert?

aSma>> schrieb:
> Formatiere mal deinen Code, sonst habe ich kein Bock drüber zu gucken.
> Oder hänge als .c Datei an.

Habe dir das c. File angehängt.

Danke für das Angebot!

aSma>> schrieb:
> Jep. Der hat sogar die benötigten komplementär Ausgänge. Da braucht man
> sich nicht die Beide zu verbiegen wie eine H... .

Wieso braucht ich die komplementär Ausgänge?

Wieso brauche ich den AFIO-Clock? Ich remappe ja nicht? Den hatte ich 
nicht eingeschaltet, aber auch mit funzts nicht.

von aSma>> (Gast)


Lesenswert?

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
Fehlt bei dir!

Sonst habe ich schon alles gesagt!
Timer1 für Motor nehmen. Die komplementär Ausgänge nutzen, um die 
Statorströme zu steuern. Dadurch sparst du auch einen Timer!

Sonst muss man die Timer miteinander synchrinisieren.

von Felix C. (felix_c13)


Lesenswert?

aSma>> schrieb:
> RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
> Fehlt bei dir!

Wie gesagt ich hatte es vorher mal reingetan uns es hat trotzdem nicht 
gefunzt. Vor allem, wieso haben die anderen 5 ohne funktioniert?
War grad beim Friseur und hab mir auf dem Weg aus dem Büru noch 2 neue 
Discoverys geholt, vielleicht bringts ja was.

Aber da bin ich beruhigt, wenn das der einzige "Fehler" zu sein scheint.

aSma>> schrieb:
> Timer1 für Motor nehmen. Die komplementär Ausgänge nutzen, um die
> Statorströme zu steuern. Dadurch sparst du auch einen Timer!
>
> Sonst muss man die Timer miteinander synchrinisieren.

Ahaa jetzt weiss ich was du meinst. Nee da denkst du zu weit, ich regel 
die nicht selber, jedenfalls nicht direkt. Ich habe Regler aus dem 
RC-Bereich. denen muss ich grob alle 20ms ein High während 1000-2000us 
geben. Abhängig von der Länge dieses High's, steuert der Regler dann die 
Drehzahl.

von Felix C. (felix_c13)


Lesenswert?

Ok, habe jetzt 2 andere Discoverys getestet. Bei beiden hat es nicht 
funktioniert. Und RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 
ist jetzt drinnen.

von aSma>> (Gast)


Lesenswert?

Servus,
dann guck mal ins Errata. Da spuckt 100 pro USART dir in die Suppe, o.ä.

mfg

von Felix C. (felix_c13)


Lesenswert?

aSma>> schrieb:
> dann guck mal ins Errata. Da spuckt 100 pro USART dir in die Suppe, o.ä.

Scheiss die Wand an. Hab jetzt mal alle Peripherien rausgekickt und 
weisst was? Jetzt gehts... Das isn Scherz.

Dir vielen Dank für deine Unterstützung, vieleicht find da jetzt nen 
Workaround.

Edit: Ja es war der USART

: Bearbeitet durch User
von aSma>> (Gast)


Lesenswert?

Wie kommst du auf diese
> BLDC-Motoren
Bezeichnung?

Anstatt es gleich bei den Namen zu bennen: RC Servo.

Und hier sieht man wieder wunderbar, wenn der ganze Code nicht komplett, 
sondern nur stückweise gezeigt wird, es nahezu unmöglich ist den Fehler 
zu finden.

Bei 6 Servos, das hört sich heimlich nach einer Stewart platform an?

von Felix C. (felix_c13)


Lesenswert?

aSma>> schrieb:
> Wie kommst du auf diese
>> BLDC-Motoren
> Bezeichnung?
>
> Anstatt es gleich bei den Namen zu bennen: RC Servo.

Nein, keine Servos, BLDC's.

Das wäre so ein Regler:
http://www.conrad.ch/ce/de/product/206287/Flugmodell-Brushless-Flugregler-ROXXY-BL-Control-960-6-Belastbarkeit-max-70-A?ref=searchDetail

aSma>> schrieb:
> Und hier sieht man wieder wunderbar, wenn der ganze Code nicht komplett,
> sondern nur stückweise gezeigt wird, es nahezu unmöglich ist den Fehler
> zu finden.

Hatte sowas noch nie. Man muss halt erstmal auf die Schnauze fallen, 
sonst lernt man sowas nicht ;)

Ist für ein ROV --> ferngesteuertes U-Boot.

von aSma>> (Gast)


Lesenswert?

> Ist für ein ROV --> ferngesteuertes U-Boot.

Ich denke der Kalte Krieg ist schon vorbei :P.

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


Lesenswert?

Ist das ein VL Discovery Board? Wenn ja, warum nimmst du nicht den 
'Advanced' Timer 1 und seine bis zu 4 CC Register? Damit ist die 
Ansteuerung ein Kinderspiel - auch bei Sinuskommutierung.

aSma>> schrieb:
>> Ist für ein ROV --> ferngesteuertes U-Boot.
>
> Ich denke der Kalte Krieg ist schon vorbei :P.

So ein Dings baue ich auch gerade - und ist nicht für Krieg gedacht, 
sondern für Unterwasseruntersuchungen.

: 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.