Forum: Mikrocontroller und Digitale Elektronik AT89C51ED2 + CA3081 Port immer High?


von Mathias Z. (matziz198)


Angehängte Dateien:

Lesenswert?

Hallo,

ich lese ab und zu in diesem Forum um mir Ideen und Anregungen zu holen.
Nun habe ich mir eine Schaltung aufgebaut um diverse Sachen (vor allem 
Hard PWM) zu testen.

Wie Ihr sehen könnt habe ich an einem AT89C51ED2 Port 1 ein 
Transistorarray CA3081 (hatte ich noch rumliegen) angeschlossen. 
Programieren lässt sich der µC problemlos bzw. gibt keine Fehler. Zum 
Testen der Schaltung lasse ich den gesamten Port 1 an und aus machen. 
Allerdings leuchten die LEDs ständig.
Das bedeutet doch das an dem Port ständig High anliegt und der 
Transistor durchsteuert. Oder habe ich den Basiswiderstand falsch 
gewählt?

Könnt Ihr bitte mal drüberschauen ob ich irgendeinen Fehler drin habe?
Ich komme gerade nicht weiter.

MfG
Matze

von Matthias K. (matthiask)


Lesenswert?

6.8k passt so. LED RV könnten etwas größer sein, falls es normale 20mA 
LEDs sind.

Hast Du mal direkt am Port gemessen, ob er wirklich getoggelt wird? 
Vielleicht geht der Wechsel auch zu schnell, so dass Du das EIN/AUS gar 
nicht mehr optisch wahrnehmen kannst.

von Ralf (Gast)


Lesenswert?

In Ergänzung zu Matthias' Kommentar, poste mal den Code, falls es das 
nicht war.

Und mach einen Widerstand in die PSEN-Leitung. PSEN ist nur beim Reset 
ein Eingang, danach ein Ausgang, und über den Taster machst du einen 
Schlurzkuss.

Ralf

von Mathias Z. (matziz198)


Lesenswert?

Ganz einfaches Programm zum testen (X2 aus):

1
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
2
#include <stdio.h>
3
4
sbit ausgang=P1; // Portpin P1 als Signalausgang
5
void zeit(void); // Prototypen-Anmeldung
6
7
void main(void)
8
{
9
  while(1) // Endlos-Schleife
10
  {   zeit(); // Delay
11
    ausgang=~ausgang; // Bit komplementieren
12
  }
13
}
14
void zeit(void) // Wartezeit-Erzeugung
15
{ unsigned int x;
16
  for(x=0;x<=8000;x++);
17
}

Der Strom durch die LEDs beträgt 18mA, also noch im Rahmen.

Danke für die schnellen Antworten!! Hoffe mir kann geholfen werden. Zu 
Weihnachten muss das Projekt fertig werden.

MfG
Matze

von Matthias K. (matthiask)


Lesenswert?

1
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
2
#include <stdio.h>
3
4
void zeit(void); // Prototypen-Anmeldung
5
6
void main(void)
7
{
8
  while(1) // Endlos-Schleife
9
  {
10
    P1 = 0;
11
    zeit(); // Delay
12
    P1 = 0xFF;
13
    zeit(); // Delay
14
  }
15
}
16
17
void zeit(void) // Wartezeit-Erzeugung
18
{ unsigned int x;
19
  for(x=0;x<=8000;x++);
20
}

P1 ist doch schon definiert. Probiers mal so. Die 8000 hast Du schon mal 
vergrößert?

von Mathias Z. (matziz198)


Lesenswert?

Habe deine Version mit 65535 getestet. Keine Veränderung.
Muss ich bei der "Startup.A51" etwas verändern? Oder bei den 
Projekteinstellungen (Keil) ein Häckchen vergessen?

von Ralf (Gast)


Lesenswert?

> Oder bei den Projekteinstellungen (Keil) ein Häckchen vergessen?
Nur so ne Vermutung: Was hast du bei den Speicher-Modellen eingestellt?
Bitte nichts anderes als SMALL beim Datenspeicher...

Ralf

PS: Was sagt der Simulator zu deinem Programm?

von Pieter (Gast)


Lesenswert?

moin moin,

Gleichspannungmessung an P1, welcher Wert?
Was macht Keil aus "Zeit" in Assembler?

Bin kein C'ler, aber sollte main nicht "das letze" in einem Prog sein?

Pieter

von ddddd (Gast)


Lesenswert?

Matthias K. schrieb:
> void zeit(void) // Wartezeit-Erzeugung
> { unsigned int x;
>   for(x=0;x<=8000;x++);
> }

der Compiler dürfte wohl die forschleife wegoptimieren.....
also entweder optimierung ausschalten oder x als volatile definieren
oder irgendwas anderes tun.....

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mathias Z. schrieb:
> Allerdings leuchten die LEDs ständig. Das bedeutet doch das an dem Port
> ständig High anliegt und der Transistor durchsteuert.
Das kann auch sein, dass die LEDs blitzschnell ein- und ausgeschaltet 
werden.

Zum Test, ob dein Port funtkioniert:
Kannst du die LEDs dauernd aus- und dauernd einschalten?
1
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
2
#include <stdio.h>
3
4
void main(void)
5
{
6
  P1 = 0;
7
  while(1); // Endlos-Schleife
8
}

Und:
1
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
2
#include <stdio.h>
3
4
void main(void)
5
{
6
  P1 = 0xff;
7
  while(1); // Endlos-Schleife
8
}

Und wenn das geht, dann klemmts bei der Wartezeiterzeugung.
Dann kannst du mal sowas probieren:
1
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
2
#include <stdio.h>
3
4
volatile unsigned int x;
5
  
6
void zeit(void)
7
{ 
8
   for(x=0;x<=0xffff;x++);
9
}
10
11
void main(void)
12
{
13
  P1 = 0;
14
  while(1) {
15
     P1 = ~P1;
16
     zeit();
17
  }
18
}

Pieter schrieb:
> Bin kein C'ler, aber sollte main nicht "das letze" in einem Prog sein?
Unwichtig, wenn die Funktionen woanders (z.B. hinter main() oder in 
einer anderen Datei) stehen, müssen nur die Funktionsprototypen vor der 
Verwendung bekannt gemacht werden.

von Mathias Z. (matziz198)


Lesenswert?

Also der 1. und 2. Code funktionieren. Beim 3. leuchten wieder alle.

Ich gehe mal davon aus das der µC im Standartmodus 12 Takte/Zyklus 
benötigt. Bei 22.118MHz Taktfrequenz muss ich bis 460792 zählen um alle 
250ms zu toggeln oder?

(22118000/12)/4

Matze

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mathias Z. schrieb:
> Beim 3. leuchten wieder alle.
Aber nur halb so hell?
Sieh mal die LEDs und schüttel den Kopf. Siehst du da was flackern?

> Bei 22.118MHz Taktfrequenz muss ich bis 460792 zählen um alle
> 250ms zu toggeln oder?   (22118000/12)/4
Das gilt nur, wenn du tatsächlich in jedem Takt um 1 hochzählen und 
vergleichen könntest. Aber schon das x++ braucht einige Prozessortakte. 
Dazu der Vergleich, dazu der Rücksprung...
In der Summe wirst du mit einem wesentlich kleineren Wert auskommen.

Aber wenn dir der Compiler die nutzlose Zeile
   for(x=0;x<=0xffff;x++);
einfach rausoptimiert, dann ist er natürlich blitzschnell fertig und 
schaltet mit Vollgas nur die LED ein und aus.

Probier mal das aus:
1
volatile unsigned long x;
2
  
3
void zeit(void)
4
{ 
5
   for(x=0;x<=200000;x++);
6
}

von Mathias Z. (matziz198)


Lesenswert?

Habe gerade viel um die Ohren.
Außerdem hatte ich die RS232 noch auf ner Extraplatine und baue gerade 
Alles auf eine drauf. Wenn ich fertig bin teste ich weiter.

Vielen Dank für Eure Hilfe!!
Matze


PS: Habe beim Keil noch nach dem Speichermodell nachgeschaut. Steht auf 
small

von Mathias Z. (matziz198)


Lesenswert?

Irgendwie wollen die Sachen die wir hier versucht haben nicht laufen. 
Habe dann nochmal n gaaanz primitives Programm geschrieben um zu sehen 
ob die Hardware Funktioniert. Und sie tut es :) Werde jetzt weitere 
Sachen testen.

Kleines Lauflicht:
1
#include <reg51xd2.h>
2
3
sbit LED1 = P1^1;
4
sbit LED2 = P1^2;
5
sbit LED3 = P1^3;
6
sbit LED4 = P1^4;
7
sbit LED5 = P1^5;
8
sbit LED6 = P1^6;
9
sbit LED7 = P1^7;
10
11
void Pause (void)
12
{
13
  unsigned int i;
14
  for (i=1; i < 30000; i++);
15
}
16
17
void main(void)
18
{  
19
  while (1)
20
  {
21
    LED1 = 1;
22
    Pause ();
23
    LED1 = 0;
24
    LED2 = 1;
25
    Pause ();
26
    LED2 = 0;
27
    LED3 = 1;
28
    Pause ();
29
    LED3 = 0;
30
    LED4 = 1;
31
    Pause ();
32
    LED4 = 0;
33
    LED5 = 1;
34
    Pause ();
35
    LED5 = 0;
36
    LED6 = 1;
37
    Pause ();
38
    LED6 = 0;
39
    LED7 = 1;
40
    Pause ();
41
    LED7 = 0;
42
  }
43
}

//Matze

von Bernhard S. (b_spitzer)


Lesenswert?

Die 8051 haben für den '1'-Pegel am Ausgang nur einen relativ schwachen 
Pull-Up mit etwa 20kOhm. Der 1-Pegel wird zwar für einen Takt (nicht 
Maschinenzyklus) stärker getrieben, aber das reicht hier evtl. nicht 
aus. Für das Transistorarray sieht es daher nach einem 27kOhm 
Basiswiderstand aus. Damit fließt in die Basis ein Strom von höchstens 
4.3V/27kOhm = 0,16mA. Bei dem Strom ist die Stromverstärkung nur knapp 
über 50. Damit wäre ein Ic von 8mA das höchste der Gefühle. Die 100 Ohm 
Vorwiderstand vor den LEDs dürfte Standard-LED mit 20mA bedeuten.
In diesem Fall könnte man die Basis-Widerstände vermutlich komplett 
weglassen. Vorsichtige Naturen schließen 330 Ohm an, damit die Pins bei 
5 V nie 20mA abbekommen können.

tschuessle
Bernhard

von Mathias Z. (matziz198)


Lesenswert?

Also der µC scheint keine Probleme mit dem Basisstrom zu haben. Ein 
Lauflicht Programm funktioniert problemlos. Den Basisvorwiderstand habe 
ich so gewählt das der Transistor gerade so in die Sättigung kommen 
müsste.


Ich habe noch ein Progrämmchen geschrieben dessen Verhalten ich mir 
nicht so richtig erklären kann. Ich möchte mit 2 Tastern 2 LEDs 
schalten. Wenn der Taster gedrückt wird soll die LED an gehen ansonsten 
aus bleiben. Anschalten geht. Aber die LED geht nicht mehr aus beim 
loslassen. Ist das Verhalten ein Denkfehler in meinem Programm?
1
#include <reg51xd2.h>
2
3
sbit LED1 = P1^1;
4
sbit LED2 = P1^2;
5
sbit taster1 = P2^2;
6
sbit taster2 = P2^5;
7
8
void main(void)
9
{  
10
  
11
    if(taster1==0)
12
    {LED1=0;}
13
    else if(taster1==1)
14
    {LED1=1;}
15
    if(taster2==0)
16
    {LED2=0;}
17
    else if(taster2==1)
18
    {LED2=1;}
19
  
20
}

von Matthias K. (matthiask)


Lesenswert?

1
if(!taster1) LED1=0; else LED1=1;

Das if nach dem else kannst Du dir sparen, weil die Bedingung schon 
erfüllt ist.

von Mathias Z. (matziz198)


Lesenswert?

Das gleiche Problem. Die LEDs gehen nicht aus.
Programmtechnisch sehe ich keinen Grund warum das nicht funktionieren 
sollte. Muss dann doch was mit der Hardware nicht in Ordnung sein.

von Matthias K. (matthiask)


Lesenswert?

Wie haste die Taster denn genau angeschlossen?

Programm muss natürlich noch in eine Endlosschleife!
1
while (1) {
2
  if(!taster1) LED1=0; else LED1=1;
3
}

von Mathias Z. (matziz198)


Lesenswert?

Die Schaltung ist im 1. Post zu sehen. Die while schleife ist 
selbstverständlich drinn. Keine Veränderung.

von Mathias Z. (matziz198)


Lesenswert?

Ich habe die Schaltung ohne Basivorwiderstände kurz getestet. Ergebniss: 
läuft sehr instabil bzw. gar nicht.
Weiteres habe ich die Vorwiderstände der LEDs auf 220 Ohm erhöht.
Iled nun 8,18mA

Hat einer von Euch irgendein Lauflichtprogramm oder ähnliches für den 
ED2 welches 100%ig funktioniert? Könnte damit herausfinden ob es an der 
Hardware liegt oder ein Softwareproblem vorliegt.

//Matze

von Bernhard S. (b_spitzer)


Lesenswert?

Deine Einfach-Programme sollten eigentlich laufen.
Beim Lauflicht könnte der Compiler die for-Schleife wegoptimieren, weil 
die ja sonst nix macht. Evtl. mal den Optimierungslevel verändern oder 
gleich den erzeugten ASM-Code anschauen (im Debugger). Wenn bei der 
FOR-Schleife (mit INT-Variable) nicht 8-10 Zeilen ASM stehen, hat der 
Compiler viel wegoptimiert. Dann hilft evtl. ein _nop_(); in der 
Schleife, welches in der Intrins.h zu finden ist.

Kürzeres Testprogramm:

void main(void){
  while(1){
    P1++;
    Pause();
  }
}

Du verwendest einen 22,11MHz-Quarz. Damit ist (ohne X2-Mode) ein 
Maschinenzyklus 0,54us. Beim RIDE-Compiler braucht eine for-Schleife mit 
INT etwa 8MZ (mit LONG gschickte 10MZ...). Keine Ahnung, was der Keil 
daraus macht, das musst Du mal im Debugger ausstoppen.
Mit einer INT-Schleife kommt man so auf eine maximale Wartezeit von 
65535*8MZ*0.54us/MZ = 284ms. Da sollte man Zählen und auch Blinken sehr 
gut sehen.

AAAARGH - das sehe ich jetzt erst!
Vorsicht mit
    for(x=0;x<=0xffff;x++);
Das ist bei INT immer erfüllt und wird damit zur ungewollten 
Endlosschleife. Besser nur
    for(x=0;x<0xffff;x++);
schreiben oder Controllerfreundlich runterzählen:
   for(x=0xffff;x!=0;x--);

Spendiere dem /PSEN-Pin lieber noch einen Pull-Up an 5V...

tschuessle
Bernhard

von Mathias Z. (matziz198)


Lesenswert?

Ich habe nun das Problem des merkwürdigen Verhaltens ausfindig machen 
können.
Ich hatte die Taster aktiv high beschaltet. Obwohl ich das in diversen 
Testprogrammen berücksichtigt habe zeigten sich unerklärliche 
Verhaltensweisen welche ich weiter oben beschrieben hatte.
Jetzt habe ich die Taster aktiv low angeschlossen und alles funktioniert 
so wie es soll.

Danke für Eure Bemühungen und Ideen.

Gruß
Matze

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.