Hallo, ich könnte von Euch einwenig Hilfe gebrauchen , da ich selbst schon an verzweifeln bin. http://www.roboterwelt.de/auktion/fujit/index.htm (Um dieses Board geht es) <-- Ich möchte gerne die 12 Ausgänge auf Eins setzen, was aber mit den undenstehenden Quelltext nicht klappt. Ich habe die I/O Adressen aus der Mitgliferten Software. Eine dierekte Adressen beschreibung konnte ich nicht finden. Könnte es sein, das ich einen ouput befehl aufrufen muss? Ich würde mich freunen wenn mir jemand ein Tip geben könnte. Gruß Tobias #include "mb90540.h" int main() { while(1) { PDR2=0x08; //ADDRESSBUS=CS_OUT_1_8; //Auswahl des Adressbuses PDR8_P83=0; // OUT_EN; //Einschalten des A DDR0=0xFF; // DB_WRITE;//Auf Datenbuss Schreiben PDR0=0x7f;// // DATABUS=0x7f;// Wert auf Datenbuss schreiben } }
Zunächst mal Lob! Nämlich dass du die Frage mit ausreichend Material gefüttert hast, so dass man eine Antwort wagen kann. Ich muss aber dazusagen, dass ich von dem erwähnten µC Null,Null Ahnung habe und nur formal (mit gesundem Programmiererverstand) an die Sache rangehen kann. Interessant ist an der Stelle, wie die Funktion setoutput das in der Beispielsoftware macht:
1 | void setoutput (unsigned char uc_port,unsigned char uc_wert) |
2 | {
|
3 | |
4 | OUT_EN; // Output enable aktiv// |
5 | |
6 | switch(uc_port) |
7 | {
|
8 | case 0: |
9 | DB_WRITE; |
10 | DATABUS = ~uc_wert; // Bus Ausgabe aktiv 1..8 |
11 | ADDRESSBUS = CS_OUT_1_8 // durch Anlegen der Adresse Ausgabebyte Taktimpuls |
12 | wait(1); // für das Latch erzeugen |
13 | ADDRESSBUS = CS_DEFAULT_IN; |
14 | break; |
15 | case 1: |
16 | DB_WRITE; |
17 | DATABUS = ~uc_wert; // Bus Ausgabe aktiv 9..12 |
18 | ADDRESSBUS = CS_OUT_9_12 // durch Anlegen der Adresse Ausgabebyte Taktimpuls |
19 | wait(1); // für das Latch erzeugen |
20 | ADDRESSBUS = CS_DEFAULT_IN; |
21 | break; |
22 | /*
|
23 | // im Moment unwichtig
|
24 | case 2:
|
25 | if ((uc_wert&0x01)!=0) OUT3_0=1; else OUT3_0=0;
|
26 | break;
|
27 | */
|
28 | }
|
29 | }
|
Anm.: Der Code (aus src.rar) enthält an der Stelle
> ADDRESSBUS = CS_OUT_1_8 // durch Anlegen der Adresse Ausgabebyte Taktimpuls
^
einen Syntaxfehler, was das Zutrauen in einen sorgfältigen Test und die
Dokumentation der Firmware etwas erschüttert.
Die wesentlichen #defines für ADDRESSBUS, DATABUS, OUT_EN und DB_WRITE
sehen so aus:
1 | #define OUT_EN PDR8_P83 = 0 // OUTput_ENable für UWR-Outputs
|
2 | #define DB_WRITE DDR0 = 0xFF // Schreibender Zugriff auf den Datenbus
|
3 | #define DATABUS PDR0
|
4 | #define ADDRESSBUS PDR2
|
5 | #define CS_DEFAULT_IN 0x07;
|
6 | #define CS_OUT_1_8 0x08;
|
7 | #define CS_OUT_9_12 0x09;
|
Desweiteren ist in der init der Adressbus auf Ausgabe geschaltet worden
1 | DDR2 = 0xFF; // ADDRESSBUS als Output |
Die Aufrufe im Code sehen so aus:
1 | setoutput(0, 0xFF); /* Output1 1-8 */ |
2 | setoutput(1, 0x0F); /* Output2 9-12 (4 Bit Power)*/ |
Was mir nicht klar ist, ob eine "1" einen Output anschaltet oder ausschaltet. In setoutput wird jedenfalls mit einen ~ negiert. Bei deinem Code ist formal 1/ ADDRESSBUS nicht auf Ausgabe gestellt (DDR2 = 0xFF; fehlt). Deine Schreibzugriffe auf ADDRESSBUS landen vielleicht im Nirvana (hängt von der Defaulteinstellung beim Reset des µC ab). 2/ Das OUT_EN out-of-sequence, d.h. nicht die erste Aktion. Ob das Relevant ist weiss ich nicht. Es könnte nur eine LED sein, die was anzeigt (unkritisch) oder ein Schaltungsteil, der Output 9-12 Power zuteilt (kritisch). 3/ In der Beispielsource wird bevor Daten auf den Bus kommen, ein Schreiben erst ermöglicht (DB_WRITE). Das ist bei dir nicht der Fall und deine Schreibversuche auf DATABUS landen vielleicht im Nirvana (hängt von der Defaulteinstellung beim Reset des µC ab). 4/ Die Zuweisung an DATABUS und ADDRESSBUS auch out-of-sequence. Das kann auch ein wichtiger Punkt sein. Zuerst die Daten auf den Bus und dann die Adresse. Genaueres müsste die Doku zum CPLD hergeben. 5/ Der Adressbus wird mit zwei Zuständen beschrieben, zwischen denen eine Wartezeit einzuhalten ist. Das ist üblich, wenn ein nachgeschaltetes IC Daten übernehmen soll. Das fehlt bei deinem Code. Genaueres müsste die Doku zum CPLD hergeben. 6/ Die Output von 1-8 und 9-12 sind getrennt zu behandeln, Es sind unterschiedliche Übernahmeanweisungen für ADDRESSBUS notwendig. Dein Code benutzt nur eine Übernahmeanweisung (die für 1-8, wobei du mit 0x1F nur 1-7 übergibst). Genaueres müsste die Doku zum CPLD hergeben. 7/ Der Datenwert ist anscheinend invertiert (~ im Original). Möglicherweise setzt du die Output statt auf AN aus AUS und beobachtest "Nix". Mangels Doku (bis nicht so tief eingestiegen, ob das irgendwo erklärt wird) hilft hier Experimentieren mit/ohne ~. Genaueres müsste die Doku zum CPLD hergeben. Insgesamt 7 formal fischige Stellen in deinem Code, die jede für sich für ein Nichtfunktionieren verantwortlich sein kann. Aber ich sehe einen Lichtblick, dass du mit der Hardware vor Ort die Aufgabe meistern kannst.
ADD: 3/ habe ich falsch gemacht, sorry. Du hast in deinem Code das DB_WRITE vorm Beschreiben des DATABUS drin. Das ist richtig!
Hallo Steffan, ich finde es super das du mir geantwotest hast. 1/ Shit, wieso habe ich so eine einfache Sache übersehen? Danke :-) 2/ Das OUT_EN--> Ich hänge den Schaltplan mit dran, der muss sein . 4/ OK, habe ich angepasst. 5/ OK , ich habe die Funkion von Orginal übernommen 6/ ich weis , ich wäre glücklich wenn wenigsten die led's leuchten. 7/ ich habs mi 0x10(10000) versuch, da müsste doch irgen was leuchten. Wenn ich darf, dann würde ich dir das gsamte Projekt zukommen lassen. Gruß Tobis #include "mb90540.h" // Timer-Variablen static unsigned char guc_Tim; /* Flag Timer aktiv */ static unsigned char guc_Tim1ms; /* Flag 1ms Tic */ static unsigned char guc_TimC; /* Counter für 1ms Timer-Tic */ static unsigned int gus_Timer; /* Counter allgemeiner Timer */ static unsigned int gus_Tiled; /* Counter Timer fuer LED */ static unsigned int gus_Toser; /* Counter */ void wait (us_Time) unsigned int us_Time; { unsigned int us_pau; // for (delay=0; delay<DELAY; delay++) // asm("\tNOP"); guc_Tim = 0; // Flag Timer loeschen for (us_pau = 0; us_pau != us_Time; us_pau++) { do ; while (guc_Tim == 0); // 250us warten // MAX_WDI; // Watchdog toggeln guc_Tim = 0; // Flag Timer loeschen } } int main() { while(1) { __EI(); DDR0 = 0xFF; // Schreibender Zugriff auf den Datenbu PDR8_P83=0; // OUT_EN; // Output enable aktiv// DDR2 = 0xFF; // ADDRESSBUS als Output wait(1); PDR0=0x10; // DATABUS=0x40;// Wert auf Datenbuss schreiben PDR2=0x08; //ADDRESSBUS=CS_OUT_1_8; //Auswahl des Adressbuses wait(1); //ADDRESSBUS = CS_DEFAULT_IN; PDR0=0x07; } //return (1); }
Hallo Stefan, Mit dem Code aufruf , das verstehe ich nicht gans, ich dachte das wird über die Adressen #define CS_OUT_1_8 0x08; #define CS_OUT_9_12 0x09; geregelt. Der reiner aufruf löst einen Fehler aus --------------------Configuration: IO_TSE.prj - Debug-------------------- MAIN.C *** d:\daten\iso\fujisu_board\software\test1\src\main.c(47) E4001C: invalid operands: type of function designator must be function type: operator `()' *** d:\daten\iso\fujisu_board\software\test1\src\main.c(48) E4001C: invalid operands: type of function designator must be function type: operator `()' ------------------------------ Error detected. Gruß Tobias
Tobias Himpenmacher wrote: > MAIN.C > *** d:\daten\iso\fujisu_board\software\test1\src\main.c(47) E4001C: > invalid operands: type of function designator must be function type: > operator `()' > *** d:\daten\iso\fujisu_board\software\test1\src\main.c(48) E4001C: > invalid operands: type of function designator must be function type: > operator `()' > ------------------------------ > Error detected. Die Source aus Posting 'Datum: 01.03.2008 23:46' hat nur 47 Zeilen. Ich kann die Fehlermeldungen in Zeile 47 und 48 keinem Sourcecodeabschnitt zuordnen. > Mit dem Code aufruf , das verstehe ich nicht gans, ich dachte das wird > über die Adressen > > #define CS_OUT_1_8 0x08; > #define CS_OUT_9_12 0x09; > > geregelt. Ich verstehe nicht, was du nicht verstehst. Du solltest schreiben, wie du was verstehst/denkst, damit ich das verstehe ;-) Die Datenübergabe vom µC an das CPLD verläuft so: 1. ADDRESSBUS als Output konfigurieren (DDR2 = 0xFF) 2. OUTput_ENable für UWR-Outputs (OUT_EN bzw. PDR8_P83 = 0). 3. DATABUS als Output konfigurieren (DB_WRITE bzw. DDR0 = 0xFF) 4. Wert an DATABUS zuweisen 5. ADDRESSBUS auf CS_OUT_1_8 (0x08) setzen 6. min. ??? µs Warten (wait(1)) 7. ADDRESSBUS auf CS_DEFAULT_IN (0x07) setzen Ich sehe nicht, ob deine Wartefunktion aus Posting 'Datum: 01.03.2008 23:46' die erforderliche Wartezeit einhält. In der Originalsource wird das Warten mit einem Timerinterrupt gemacht. In deiner Source wird das:
1 | guc_Tim = 0; // Flag Timer loeschen |
2 | for (us_pau = 0; us_pau != us_Time /* us_time ist hier 1 */; us_pau++) |
3 | {
|
4 | do ; |
5 | while (guc_Tim == 0); // 250us warten |
im Bereich do/while eine sehr unerwünschte Endlosschleife geben, weil kein Timer läuft und folglich kein TimerInterrupthandler guc_Tim ungleich 0 setzen kann. Im folgenden dein Code mit Kommentaren von mir. BTW. Für mich ist der Code besser lesbar, wenn die Schreibweise aus dem Original mit den Makros verwendet wird (ADDRESSBUS=CS_OUT_1_8), statt die Makros aufzulösen (PDR2=0x08).
1 | int main() |
2 | {
|
3 | // #0: Ich würde main anders machen - alles aus der while Schleife
|
4 | // vorziehen, d.h. einmalig ausführen und dann zum Abschluss eine
|
5 | // leere Endlosschleife, damit main() nicht verlassen wird.
|
6 | while(1) |
7 | {
|
8 | // #1: Was macht diese Zeile? Sieht verdächtig nach einem
|
9 | // Enable Interrupts aus aber du hast keine Interrupthandlerfunktionen
|
10 | // und keine Voreinstelungen der Interrupts.
|
11 | __EI(); |
12 | |
13 | DDR0 = 0xFF; // Schreibender Zugriff auf den Datenbus |
14 | |
15 | // #2: DDR8 ist ebenfalls irgendwo auf Output zu stellen,
|
16 | // damit das funktioniert
|
17 | PDR8_P83=0; // OUT_EN; // Output enable aktiv// |
18 | |
19 | DDR2 = 0xFF; // ADDRESSBUS als Output |
20 | |
21 | // #3: Wie oben geschrieben ist das Zeitverhalten im Moment unklar.
|
22 | // Schau in der Doku der Compilerlibrary, ob du Funktionen findest,
|
23 | // mit denen du warten kannst. Irgendwas mit delay... oder sleep...
|
24 | // oder wait...
|
25 | wait(1); |
26 | |
27 | PDR0=0x10; // DATABUS=0x40;// Wert auf Datenbuss schreiben |
28 | |
29 | PDR2=0x08; // ADDRESSBUS=CS_OUT_1_8; //Auswahl des Adressbuses |
30 | |
31 | // Siehe #3
|
32 | wait(1); |
33 | |
34 | PDR0=0x07; // ADDRESSBUS = CS_DEFAULT_IN; |
35 | }
|
36 | // return(1);
|
37 | }
|
An sich sieht das nicht schlecht aus.
Hallo zusammen! Nur, weils grad beim überfliegen aufgefallen ist: >Anm.: Der Code (aus src.rar) enthält an der Stelle >> ADDRESSBUS = CS_OUT_1_8 // durch Anlegen der Adresse Ausgabebyte Taktimpuls > ^ >einen Syntaxfehler, was das Zutrauen in einen sorgfältigen Test und die >Dokumentation der Firmware etwas erschüttert. Und dann:
1 | #define CS_OUT_1_8 0x08;
|
Das Makro enthält das Semikolon bereits, deswegen enthält die Zeile keinen Syntaxfehler. Allerdings sollte man sich das in der Form gar nicht erst angewöhnen, das Semikolon gehört natürlich bewusst eingetippt. Das war's auch schon, zum eigentlichen Problem habe ich leider nichts beizutragen :-\
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.