Hi, Ich bin an der Entwicklung eines BLDC Controllers und habe zumindest schon mal erfolgreich das Central Aligned PWM mit getriggerter Strommessung implementiert. Nun habe ich festgestellt, dass ab einem bestimmten Duty Cycle (ab so 85%) die Strommessung nicht mehr richtig funktioniert. Angehängt ist einmal eine Messung mit maximal 80% Duty Cycle und einmal mit maximal 95% Duty Cycle wobei die Phasenströme in RGB sind. Wie man sieht, hat es nichts mit dem maximalen Strom zu tun, also der ADC geht nicht in die Sättigung, da bei 95% Duty Cycle weniger Phasenstrom fließt (Da die Spannung für Messung runtergedreht wurde). Die Ströme werden über 3 Shunts an den Low-Sides gemessen mit jeweils einem Differenzverstärker. Das Bild im Anhang PA_PB zeigt die beiden Phasenströme A und B für 95% Duty Cycle. Jemand eine Idee, warum hier die Strommessung bei Duty Cycles über 85% nicht mehr funktioniert?
:
Bearbeitet durch User
Bert S. schrieb: > Ich bin an der Entwicklung eines BLDC Controllers und habe zumindest > schon mal erfolgreich das Central Aligned PWM mit getriggerter > Strommessung implementiert. Wie genau hast du das getan. Wie genau hast du die korrekte Funktion verifiziert? > Nun habe ich festgestellt, dass ab einem > bestimmten Duty Cycle (ab so 85%) die Strommessung nicht mehr richtig > funktioniert. Mir scheint, dass da das Attribut "erfolgreich" da etwas den Ereignissen im RL vorausgreift...
c-hater schrieb: > Wie genau hast du das getan. Wie genau hast du die korrekte Funktion > verifiziert? Nun ja, der Strom-ripple wurde minimal für konstante PWM Signale an den 3 Phasen, daher müsste eigentlich die Messung korrekt klappen. Ich denke aber ich sollte das mit dem Oszi prüfen, es kann natürlich durchaus sein, dass die Timings trotzdem noch nicht stimmen. Hier ist noch der Code für das Center Aligned PWM + Timer für ADC Trigger: (Auslesen tue ich den Phasenstrom mit HAL_ADCEx_InjectedGetValue(adc_manager.adc1,ADC_CURRA);, das sollte eigentlich ja den letzten getriggerten Wert zurückgeben, oder sollte ich das besser mit dem Interrupt (HAL_ADCEx_InjectedGetValue_IT) lösen?
1 | static void MX_ADC1_Init(void) |
2 | {
|
3 | |
4 | ADC_ChannelConfTypeDef sConfig; |
5 | ADC_InjectionConfTypeDef sConfigInjected; |
6 | |
7 | /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
|
8 | */
|
9 | hadc1.Instance = ADC1; |
10 | hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; |
11 | hadc1.Init.Resolution = ADC_RESOLUTION_12B; |
12 | hadc1.Init.ScanConvMode = ENABLE; |
13 | hadc1.Init.ContinuousConvMode = DISABLE; |
14 | hadc1.Init.DiscontinuousConvMode = DISABLE; |
15 | hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; |
16 | hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; |
17 | hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; |
18 | hadc1.Init.NbrOfConversion = 4; |
19 | hadc1.Init.DMAContinuousRequests = DISABLE; |
20 | hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; |
21 | if (HAL_ADC_Init(&hadc1) != HAL_OK) |
22 | {
|
23 | _Error_Handler(__FILE__, __LINE__); |
24 | }
|
25 | |
26 | /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
27 | */
|
28 | sConfig.Channel = ADC_CHANNEL_3; |
29 | sConfig.Rank = 1; |
30 | sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; |
31 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
32 | {
|
33 | _Error_Handler(__FILE__, __LINE__); |
34 | }
|
35 | |
36 | /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
37 | */
|
38 | sConfig.Channel = ADC_CHANNEL_4; |
39 | sConfig.Rank = 2; |
40 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
41 | {
|
42 | _Error_Handler(__FILE__, __LINE__); |
43 | }
|
44 | |
45 | /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
46 | */
|
47 | sConfig.Channel = ADC_CHANNEL_5; |
48 | sConfig.Rank = 3; |
49 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
50 | {
|
51 | _Error_Handler(__FILE__, __LINE__); |
52 | }
|
53 | |
54 | /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
|
55 | */
|
56 | sConfig.Channel = ADC_CHANNEL_6; |
57 | sConfig.Rank = 4; |
58 | if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) |
59 | {
|
60 | _Error_Handler(__FILE__, __LINE__); |
61 | }
|
62 | |
63 | /**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
|
64 | */
|
65 | sConfigInjected.InjectedChannel = ADC_CHANNEL_3; |
66 | sConfigInjected.InjectedRank = 1; |
67 | sConfigInjected.InjectedNbrOfConversion = 4; |
68 | sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_480CYCLES; |
69 | sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_RISING; |
70 | sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T5_TRGO; |
71 | sConfigInjected.AutoInjectedConv = DISABLE; |
72 | sConfigInjected.InjectedDiscontinuousConvMode = DISABLE; |
73 | sConfigInjected.InjectedOffset = 0; |
74 | if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) |
75 | {
|
76 | _Error_Handler(__FILE__, __LINE__); |
77 | }
|
78 | |
79 | /**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
|
80 | */
|
81 | sConfigInjected.InjectedChannel = ADC_CHANNEL_4; |
82 | sConfigInjected.InjectedRank = 2; |
83 | if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) |
84 | {
|
85 | _Error_Handler(__FILE__, __LINE__); |
86 | }
|
87 | |
88 | /**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
|
89 | */
|
90 | sConfigInjected.InjectedChannel = ADC_CHANNEL_5; |
91 | sConfigInjected.InjectedRank = 3; |
92 | if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) |
93 | {
|
94 | _Error_Handler(__FILE__, __LINE__); |
95 | }
|
96 | |
97 | /**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
|
98 | */
|
99 | sConfigInjected.InjectedChannel = ADC_CHANNEL_6; |
100 | sConfigInjected.InjectedRank = 4; |
101 | if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) |
102 | {
|
103 | _Error_Handler(__FILE__, __LINE__); |
104 | }
|
105 | |
106 | }
|
107 | |
108 | /* TIM5 init function */
|
109 | static void MX_TIM5_Init(void) |
110 | {
|
111 | |
112 | TIM_MasterConfigTypeDef sMasterConfig; |
113 | TIM_OC_InitTypeDef sConfigOC; |
114 | |
115 | htim5.Instance = TIM5; |
116 | htim5.Init.Prescaler = 0; |
117 | htim5.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED2; |
118 | htim5.Init.Period = 1000; |
119 | htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; |
120 | if (HAL_TIM_PWM_Init(&htim5) != HAL_OK) |
121 | {
|
122 | _Error_Handler(__FILE__, __LINE__); |
123 | }
|
124 | |
125 | sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; |
126 | sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; |
127 | if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) |
128 | {
|
129 | _Error_Handler(__FILE__, __LINE__); |
130 | }
|
131 | |
132 | sConfigOC.OCMode = TIM_OCMODE_PWM1; |
133 | sConfigOC.Pulse = 0; |
134 | sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; |
135 | sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; |
136 | if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) |
137 | {
|
138 | _Error_Handler(__FILE__, __LINE__); |
139 | }
|
140 | |
141 | if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) |
142 | {
|
143 | _Error_Handler(__FILE__, __LINE__); |
144 | }
|
145 | |
146 | if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) |
147 | {
|
148 | _Error_Handler(__FILE__, __LINE__); |
149 | }
|
150 | |
151 | HAL_TIM_MspPostInit(&htim5); |
152 | |
153 | }
|
Ok, ich sehe das die Messung wirklich noch nicht synchron ist, aber zumindest immer im gleichen Zeitintervall kommt. Mal sehen warum das so daneben ist.
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.