mikrocontroller.net

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


Autor: Mathias Z. (matziz198)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz einfaches Programm zum testen (X2 aus):

#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
#include <stdio.h>

sbit ausgang=P1; // Portpin P1 als Signalausgang
void zeit(void); // Prototypen-Anmeldung

void main(void)
{
  while(1) // Endlos-Schleife
  {   zeit(); // Delay
    ausgang=~ausgang; // Bit komplementieren
  }
}
void zeit(void) // Wartezeit-Erzeugung
{ unsigned int x;
  for(x=0;x<=8000;x++);
}

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

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
#include <stdio.h>

void zeit(void); // Prototypen-Anmeldung

void main(void)
{
  while(1) // Endlos-Schleife
  {
    P1 = 0;
    zeit(); // Delay
    P1 = 0xFF;
    zeit(); // Delay
  }
}

void zeit(void) // Wartezeit-Erzeugung
{ unsigned int x;
  for(x=0;x<=8000;x++);
}

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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Pieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: ddddd (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.....

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
#include <stdio.h>

void main(void)
{
  P1 = 0;
  while(1); // Endlos-Schleife
}

Und:
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
#include <stdio.h>

void main(void)
{
  P1 = 0xff;
  while(1); // Endlos-Schleife
}

Und wenn das geht, dann klemmts bei der Wartezeiterzeugung.
Dann kannst du mal sowas probieren:
#include <at89c51xd2.h> // Header für Controller "AT89C51ED2"
#include <stdio.h>

volatile unsigned int x;
  
void zeit(void)
{ 
   for(x=0;x<=0xffff;x++);
}

void main(void)
{
  P1 = 0;
  while(1) {
     P1 = ~P1;
     zeit();
  }
}

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.

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
volatile unsigned long x;
  
void zeit(void)
{ 
   for(x=0;x<=200000;x++);
}

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <reg51xd2.h>

sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit LED3 = P1^3;
sbit LED4 = P1^4;
sbit LED5 = P1^5;
sbit LED6 = P1^6;
sbit LED7 = P1^7;

void Pause (void)
{
  unsigned int i;
  for (i=1; i < 30000; i++);
}

void main(void)
{  
  while (1)
  {
    LED1 = 1;
    Pause ();
    LED1 = 0;
    LED2 = 1;
    Pause ();
    LED2 = 0;
    LED3 = 1;
    Pause ();
    LED3 = 0;
    LED4 = 1;
    Pause ();
    LED4 = 0;
    LED5 = 1;
    Pause ();
    LED5 = 0;
    LED6 = 1;
    Pause ();
    LED6 = 0;
    LED7 = 1;
    Pause ();
    LED7 = 0;
  }
}

//Matze

Autor: Bernhard Spitzer (b_spitzer)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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?
#include <reg51xd2.h>

sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit taster1 = P2^2;
sbit taster2 = P2^5;

void main(void)
{  
  
    if(taster1==0)
    {LED1=0;}
    else if(taster1==1)
    {LED1=1;}
    if(taster2==0)
    {LED2=0;}
    else if(taster2==1)
    {LED2=1;}
  
}

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if(!taster1) LED1=0; else LED1=1;

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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie haste die Taster denn genau angeschlossen?

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

Autor: Mathias Z. (matziz198)
Datum:

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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bernhard Spitzer (b_spitzer)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mathias Z. (matziz198)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.