AT89C51ED2 + CA3081 Port immer High?

OP #1950924
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
Angehängte Dateien:
Gast #1951022
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
OP #1951076
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
#1951108
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?
Gast #1951452
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?
Moderator (Firma: Titel) Persönliche Seite #1951619
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.
Moderator (Firma: Titel) Persönliche Seite #1951917
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
}
OP #1957511
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
#1958779
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
OP #1959362
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
}
OP #1960988
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
#1961337
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
OP #1962691
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren