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
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.
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
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
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?
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?
> 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?
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
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.....
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.
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
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 | }
|
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
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
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
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 | }
|
1 | if(!taster1) LED1=0; else LED1=1; |
Das if nach dem else kannst Du dir sparen, weil die Bedingung schon erfüllt ist.
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.
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 | }
|
Die Schaltung ist im 1. Post zu sehen. Die while schleife ist selbstverständlich drinn. Keine Veränderung.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.