Forum: Compiler & IDEs mb90540 I/O Pins zu schalten. Hilfeeee


von Tobias H. (Firma: keine) (tobiasth)


Angehängte Dateien:

Lesenswert?

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
   }
}

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

ADD: 3/ habe ich falsch gemacht, sorry. Du hast in deinem Code das 
DB_WRITE vorm Beschreiben des DATABUS drin. Das ist richtig!

von Tobias H. (Firma: keine) (tobiasth)


Angehängte Dateien:

Lesenswert?

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);
}

von Tobias H. (Firma: keine) (tobiasth)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.