Forum: Mikrocontroller und Digitale Elektronik Center Aligned PWM Maximaler Duty Cycle


von Bert S. (kautschuck)



Lesenswert?

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
von c-hater (Gast)


Lesenswert?

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

von Bert S. (kautschuck)


Lesenswert?

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
}

von Bert S. (kautschuck)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.