AT32UC3A0512-UES PWM Update Problem

Gast #1756308
Lesenswert?
• ▲
▼
Moin,

ich nutze zurzeit einen AT32UC3A0512-UES auf einem EVK1100. Ich möchte 
eigentlich nur die Spannung die ich per PWM rausgebe (benutze PWM als 
Analogausgang) im Betrieb verändern. Dazu habe ich mir folgendes 
gebastelt, was auch funktioniert.
1
static float V = 1.5;
2

3
int update_pwm1(void)
4
{
5
  int tmp = (int)((V-3.27)/-0.00308);
6

7

8
  if(tmp < 1)
9
  {
10
    tmp = 1;
11
  }
12
  else if(tmp > 1023)
13
  {
14
    tmp = 1023;
15
  }
16

17

18
  avr32_pwm_channel_t pwm_channel = { .ccnt = 0 };  // One channel config.
19

20
  pwm_channel.CMR.calg = PWM_MODE_LEFT_ALIGNED;       // Channel mode.
21
  pwm_channel.CMR.cpol = PWM_POLARITY_LOW;            // Channel polarity.
22
  pwm_channel.CMR.cpd = PWM_UPDATE_DUTY;              // Not used the first time.
23
  pwm_channel.CMR.cpre = AVR32_PWM_CPRE_MCK;       // Channel prescaler.
24
  pwm_channel.cdty = 1;   // Channel duty cycle, should be < CPRD.
25
  pwm_channel.cprd = 1024;  // Channel period.
26
  pwm_channel.cupd = tmp;
27

28
  return pwm_sync_update_channel(1, &pwm_channel);
29
}
30

31
int main(void)
32
{
33
  // Switch main clock to external oscillator 0 (crystal).
34
  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);
35

36
  init_pwm1();
37

38
  update_pwm1();
39

40
  while(1);
41
}

Was mich jetzt aber extremst verwirrt ist, dass folgende zwei Varianten 
nicht funktionieren und ich absolut keine warum.

Geht nicht:
1
static volatile float V = 1.5;
2

3
int update_pwm1(void)
4
{
5
  int tmp = (int)((V-3.27)/-0.00308);
6

7

8
  if(tmp < 1)
9
  {
10
    tmp = 1;
11
  }
12
  else if(tmp > 1023)
13
  {
14
    tmp = 1023;
15
  }
16

17

18
  avr32_pwm_channel_t pwm_channel = { .ccnt = 0 };  // One channel config.
19

20
  pwm_channel.CMR.calg = PWM_MODE_LEFT_ALIGNED;       // Channel mode.
21
  pwm_channel.CMR.cpol = PWM_POLARITY_LOW;            // Channel polarity.
22
  pwm_channel.CMR.cpd = PWM_UPDATE_DUTY;              // Not used the first time.
23
  pwm_channel.CMR.cpre = AVR32_PWM_CPRE_MCK;       // Channel prescaler.
24
  pwm_channel.cdty = 1;   // Channel duty cycle, should be < CPRD.
25
  pwm_channel.cprd = 1024;  // Channel period.
26
  pwm_channel.cupd = tmp;
27

28
  return pwm_sync_update_channel(1, &pwm_channel);
29
}
30

31
int main(void)
32
{
33
  // Switch main clock to external oscillator 0 (crystal).
34
  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);
35

36
  init_pwm1();
37

38
  update_pwm1();
39

40
  while(1);
41
}

Geht auch nicht:
1
//static float V = 1.5;
2

3
int update_pwm1(float V)
4
{
5
  int tmp = (int)((V-3.27)/-0.00308);
6

7

8
  if(tmp < 1)
9
  {
10
    tmp = 1;
11
  }
12
  else if(tmp > 1023)
13
  {
14
    tmp = 1023;
15
  }
16

17

18
  avr32_pwm_channel_t pwm_channel = { .ccnt = 0 };  // One channel config.
19

20
  pwm_channel.CMR.calg = PWM_MODE_LEFT_ALIGNED;       // Channel mode.
21
  pwm_channel.CMR.cpol = PWM_POLARITY_LOW;            // Channel polarity.
22
  pwm_channel.CMR.cpd = PWM_UPDATE_DUTY;              // Not used the first time.
23
  pwm_channel.CMR.cpre = AVR32_PWM_CPRE_MCK;       // Channel prescaler.
24
  pwm_channel.cdty = 1;   // Channel duty cycle, should be < CPRD.
25
  pwm_channel.cprd = 1024;  // Channel period.
26
  pwm_channel.cupd = tmp;
27

28
  return pwm_sync_update_channel(1, &pwm_channel);
29
}
30

31
int main(void)
32
{
33
  // Switch main clock to external oscillator 0 (crystal).
34
  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);
35

36
  init_pwm1();
37

38
  update_pwm1(1.5);
39

40
  while(1);
41
}

Bei den unteren beiden Varianten bleibt die Spannung auf dem Wert, den 
sie nach init_pwm1() bereits hat und ändert sich nicht auf ~1,5V.
Gast #1756513
Lesenswert?
• ▲
▼
OK nun ist die Verwirrung komplett. Anscheinend ist es dem µC nicht 
möglich, zur Laufzeit berechnete float-Werte in einen Integer zu casten.
1
int update_pwm1(int V)
2
{
3
  char buf[16];
4
  float f_tmp;
5
  int tmp;
6

7
  f_tmp = (((((float)V)/1000)-3.27)/-0.00308);
8

9
  usart_write_line(EXAMPLE_USART, "\n VOR tmp = (int)f_tmp; \n");
10
  tmp = (int)f_tmp;
11
  usart_write_line(EXAMPLE_USART, "\n NACH tmp = (int)f_tmp; \n");
12
  ...
13
}

Die Ausgabe vor dem Cast kommt, die nach_ dem Cast aber _nicht mehr.

Änder ich die Berechnung auf Fixpunkt, also
1
tmp = ((mV*100-327000)/-308);
dann funktioniert es.


Also Problem gelöst, Verwirrung bleibt!

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.