Forum: Mikrocontroller und Digitale Elektronik AT89C51ED2 PWM-Duty per Taste verändern


von Mathias Z. (matziz198)


Lesenswert?

Hallo Gemeinde,

kleines Problem: ich möchte den Tastgrad einer Hard-PWM an Pin 1.3 
verändern.
Der erste Programmentwurf funktioniert erstmal auch grundsätzlich. Taste 
"tief" macht dunkel und Taste "hoch" macht hell. Wenn ich am Ende des 
Arrays angekommen bin z.b. ganz dunkel (bei mir wert 255) springt wird 
die LED bei einem weiteren Tastendruck auf "tief" wieder auf einen sehr 
hellen Wert obwohl die LED bei weiteren Tastendrücken auf "tief" dunkel 
bleiben soll. Beim hellsten Wert das gleiche Verhalten. Springt bei 
weiteren Tastendrücken zw. hell und dunkel.
Tastenentprellen habe ich erstmal nicht implementiert und spielt in dem 
Fall auch keine Rolle.

Eine Weitere Frage betrifft die PWM selbst. Kann ich die Frequenz 
veringern ohne einen Timer oder ext. Signal zu verwenden? Habe jetzt 
PCA-Clock/6. Sollten ca. 2 MHz sein. Ich möchte ca. 200 bis 600 Hz 
haben.


MfG Matze
1
#include <at89c51xd2.h>
2
3
4
sbit pulsweite_tief=P2^2; // Drucktasten für Pulsweiten
5
sbit pulsweite_hoch=P2^5;
6
7
sbit Pin10=P1^0;    // kann raus beim richtigen programm
8
sbit Pin11=P1^1;
9
sbit Pin12=P1^2;
10
sbit Pin14=P1^4;
11
sbit Pin15=P1^5;
12
sbit Pin16=P1^6;
13
sbit Pin17=P1^7;
14
/*--------------------------------------------------------------------
15
Globale Variablen
16
----------------------------------------------------------------------*/
17
unsigned char pwm_array[32] = {255, 215, 181, 152, 128, 108, 91, 76, 64,
18
                               54, 45, 38, 32, 27, 23, 19, 16, 13, 11,
19
                               10, 8, 7, 6, 5, 4, 3, 3, 2, 2, 2, 1, 0};
20
/* invertierte PWM-Tabelle da LED bei 255 = dunkel und bei 0 = hell */
21
22
/*-----------------------------------------------------------------------
23
Zusatzfunktionen
24
------------------------------------------------------------------------*/
25
26
/*void wait(void)
27
{
28
unsigned int x;
29
for(x=1;x<=20000;x++); //Delay
30
}*/
31
32
void PWM_INI(void)
33
{ CMOD=0x00; // Interner Clock fpca/6 -- kein Interruptbetrieb
34
  CCON=0x00; // PCA steht still
35
  CCAPM0=0x42; // ECOM0-Bit und PWM0-Bit werden gesetzt
36
}
37
38
/*--------------------------------------------------------------------
39
Hauptprogramm
40
----------------------------------------------------------------------*/
41
void main(void)
42
43
{  
44
  static char old_level_t1=0;
45
  char new_level_t1;
46
  static char old_level_t2=0;
47
  char new_level_t2;
48
  
49
  char i=0;  // Arrayzaehler
50
51
  Pin10=0;   // andere Ports aus; kann raus beim richtigen programm
52
  Pin11=0;
53
  Pin12=0;
54
  Pin14=0;
55
  Pin15=0;
56
  Pin16=0;
57
  Pin17=0;
58
  
59
  PWM_INI();  // PWM-Initialisierung
60
  CR=1;    // PWM starten
61
  CCAP0H=255;  // Startwert der PWM
62
  
63
  while(1)        // Endlosschleife
64
  {   
65
    new_level_t1 = (pulsweite_hoch != 0);    //Taste 1 Flankenerkennung
66
    if(!old_level_t1 && new_level_t1)
67
      {
68
        if(i <= 31)    // steigende flanke erkannt 
69
        {i++;}        // gehe ein Feld weiter
70
        else
71
        {i=31;}
72
        CCAP0H=pwm_array[i];  // schreibe aktuelle stelle in Register Tastgrad      
73
      }
74
      old_level_t1 = new_level_t1;
75
76
    new_level_t2 = (pulsweite_tief != 0);  //Taste 2 Flankenerkennung
77
    if(!old_level_t2 && new_level_t2)
78
      {
79
        if(i >= 0)  // steigende flanke erkannt 
80
        {i--;}  // gehe ein Feld zurueck
81
        else
82
        {i=0;}
83
        CCAP0H=pwm_array[i];  // schreibe aktuelle stelle in Register Tastgrad
84
      }
85
      old_level_t2 = new_level_t2;
86
  }
87
}

von holger (Gast)


Lesenswert?

>        if(i <= 31)    // steigende flanke erkannt
>        {i++;}        // gehe ein Feld weiter

Dein Array hat nur die Indizes 0..31.
Das letzte i++ kann aber auf 32 kommen.
Peng Arrayindex falsch.

Hier das selbe in umgekehrter Richtung:

>        if(i >= 0)  // steigende flanke erkannt
>        {i--;}  // gehe ein Feld zurueck

i kann kleiner Null werden. Peng;)

Mach die beiden = weg.
Also

  if(i < 31)    // steigende flanke erkannt
  if(i > 0)  // steigende flanke erkannt

von Thomas E. (thomase)


Lesenswert?

Mathias Z. schrieb:
> if(i <= 31)    // steigende flanke erkannt
>
>         {i++;}        // gehe ein Feld weiter
>
>         else
>
>         {i=31;}
>
>         CCAP0H=pwm_array[i];  // schreibe aktuelle stelle in Register Tastgrad

Dein Fehler ist die if-Bedingung. Wenn i == 31 erhöhst du auf 32 und 
gibst den 1. Wert nach dem Array aus.
mit if (i < 31)... wird i auch nicht größer als 31.

mfg.

von Mathias Z. (matziz198)


Lesenswert?

Ja, kleiner Verständnissfehler.
Danke für die Hilfe!!

von Mathias Z. (matziz198)


Lesenswert?

Nochmal zur PWM Frequenz. Kennt einer von Euch eine Möglichkeit diese zu 
verringern ohne dabei einen Timer zu benutzen ? (bezugnehmend zum 1. 
Post)

//Matze

von Peter D. (peda)


Lesenswert?

Its clock input can be programmed to count any one of the following
signals:
• Peripheral clock frequency (FCLK PERIPH) ÷ 6
• Peripheral clock frequency (FCLK PERIPH) ÷ 2
• Timer 0 overflow
• External input on ECI (P1.2)


Peter

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.