Hallo Liebe Forum Mitglieder, ich Arbeite momentan mit einem Stm32 Cortex M3 Chip das Thema mit dem ich mich befasse geht über einen Bürstenlosen DC Motor, den ich mittels PWM Signal ansteuern will. Da die STM32 Library ein Beispiel beinhaltet über ein 6 Stufen PWM Signal habe ich dieses zum Start benutzt. Das Problem liegt nun, dass wenn ich den Code auf meinen uC lade werden die PWM Signale nicht so ausgegeben wie auf dem hoch geladenen Bild. In der read.txt steht drinnen das man ein COM Signal mit der Software erstellen soll, dies mache ich mit dem TIM_GenerateEvent(TIM1, TIM_EventSource_COM); Befehl. Aber wenn ich nun meine Signale auf dem Oszilloskop anschaue dann kommt nur eine konstante Spannung von 3,3V und es entsteht kein PWM Signal. Meine Frage ist nun, ob mir jemand sagen kann was der Fehler ist bzw. was ich Falsch mache. Wenn ihr weitere Details benötigt könnt ihr mir bescheid geben. Ich Bedanke mich schon mal im Voraus Mit freundlichen Grüßen Fabian
poste deine Init-function sonst kann man hier nur raten... prinzipell: 1) Clock einschalten (für timer und Ports) 2) Timer init 3) Timer OC init für alle drei channels --> high + Low 4) Totzeit setzen 5) Evtl noch ADC an den Timer koppeln Gruß ert
Danke für deine schnelle Antwort :) Es wird nur die stm32f10x.h noch benutzt. Die Totzeit stell ich doch mit folgendem Code ein oder? /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 1; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; Also mit dem Befehl: TIM_BDTRInitStructure.TIM_DeadTime = 1;
jaein. Musst schon den Stuct der BDTRConfig übergeben. Für den ersten Test lass ermal die Totzeit weg (und die B6 Brücke natürlich auch) 1b) ist natürlich die alternate function den Pins zuzuweisen.
Danke für deine Antwort. Die struct wird am ende der BDTRConfig übergeben hab es nur nicht mit reinkopiert. Die Pins sind auch auf Alternate Function push pull gesetzt. Ich denke das Problem liegt bei dem COM event was man per Software setzen soll oder per Hardware Aus der Read.txt : "The COM event can be generated by software by setting the COM bit in the TIM1_EGR register or by hardware (on TRGI rising edge)." Um das COM event zu generieren benutze ich die Funktion TIM_GenerateEvent(TIM1, TIM_EventSource_COM); Die Funktion setze ich am Ende des Codes. Um die Channel der Timer für das PWM einzustellen ist in dem Example Code TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; eingestellt. Ich habe das auf TIM_OCMode_PWM1 eingestellt damit überhaupt ein PWM Signal kommt. Sobald ich TIM_OCMode_PWM1 eingestellt habe und TIM_GenerateEvent(TIM1, TIM_EventSource_COM); gesetzt habe, bekomme ich auf dem Oszilloskop auch nur noch konstant die 3,3V angezeigt.
Ich poste hier mal eine komplett lauffähige Init für Timer 1 und drei PWM Kanäle. Lediglich der Interrupt ist hier nicht initialisiert. Vergleich das mal mit deinem Code. Auch denke dran das die Clock für den PWM Port angeschaltet werden muss:
1 | // 3 PWM Channels. Use UpdateDTI() to set the deadtime
|
2 | void TimerInit(void) { |
3 | |
4 | RCC_APB2PeriphClockCmd(TIM1_CLK, ENABLE); |
5 | /* Initialize basic structures to default */
|
6 | TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); |
7 | TIM_OCStructInit(&TIM_OCInitStructure); |
8 | /* Time base configuration */
|
9 | |
10 | TIM_TimeBaseStructure.TIM_Prescaler = 256; |
11 | TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; |
12 | TIM_TimeBaseStructure.TIM_Period = 0x00FF; |
13 | TIM_TimeBaseStructure.TIM_ClockDivision = 0; |
14 | TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; |
15 | |
16 | TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); |
17 | TIM_UpdateRequestConfig(TIM1, TIM_UpdateSource_Global); |
18 | TIM_UpdateDisableConfig(TIM1,DISABLE); |
19 | |
20 | /* Channel 1, 2 and 3 Configuration in PWM mode */
|
21 | TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; |
22 | TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; |
23 | TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; |
24 | TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; |
25 | TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; |
26 | TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; |
27 | TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; |
28 | |
29 | TIM_OCInitStructure.TIM_Pulse = 0x0000; |
30 | TIM_OC1Init(TIM1, &TIM_OCInitStructure); |
31 | TIM_OCInitStructure.TIM_Pulse = 0x0000; |
32 | TIM_OC2Init(TIM1, &TIM_OCInitStructure); |
33 | TIM_OCInitStructure.TIM_Pulse = 0x0000; |
34 | TIM_OC3Init(TIM1, &TIM_OCInitStructure); |
35 | }
|
36 | /* Update the BDTR register with deadtime setting, break features and output options
|
37 | */
|
38 | void UpdateDTI(u8 deadTime){ |
39 | |
40 | TIM_BDTRStructInit(&TIM_BDTRInitStructure); |
41 | /* Automatic Output enable, Break, dead time and lock configuration*/
|
42 | TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; |
43 | TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; |
44 | TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; |
45 | TIM_BDTRInitStructure.TIM_DeadTime = deadTime; |
46 | TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; |
47 | TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; |
48 | TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; |
49 | TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); |
50 | }
|
Danke für deine schnelle Antwort :). Also das PWM Signal wird bei mir korrekt Angezeigt nur die Channel 1-3 sind nicht Phasenverschoben, ich benötige die Phasenverschiebung,da ich die Signale für eine Motor Control Steuerung benutzen möchte. __|--|_____|--|__ _____|--|______|--|__ --|______|--|______|--|__ Damit die Signale 120° Phasenverschoben sind. Deine BDTR Funtkion, die du gepostet hast, Updatest du mit Werten. Nun meine Frage benutzt du für die Werte noch einen anderen Timer oder eine einfache schleife?
Fabian L. schrieb: > Nun > meine Frage benutzt du für die Werte noch einen anderen Timer oder eine > einfache schleife? Wofür jetzt? Die Totzeit wird beim Programmstart aus einem EEPROM gelesen und dann einmal gesetzt. Für Blockkommutierung benutze ich enable/disable der OC Outputs, das geht am schnellsten (mittels des CCER Registers). Umschalten tue ich in der Interrupt Routine für die Hallsensoren, da ich hier nur Motoren mit Sensoren steuere. Die Werte in der PWM werden im Timerüberlauf Interupt aufgefrischt und kommen von der Drehlzahlregelung. Bei Blockkommutierung stehen in allen drei CC Registern die gleichen Werte, sobald ich auf Sinus umstelle, natürlich nicht mehr. Die Phasenverschiebung für Sinusmodulation kommt in bewährter Weise aus einer Tabelle (siehe AVR447, die ich auf den STM32 angepasst habe).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.