Forum: Mikrocontroller und Digitale Elektronik ueberlagerte? Funktion in Bibliothek???


von Thorsten (Gast)


Lesenswert?

Hei Leute,
ich habe in C ein Problem mit einer Bibliothek/Funktion. Ich will mit 
meinem uC mit dem I2C-Bus kommunizieren. Ich verwende dafuer aus der 
Bibliothek vom Hersteller die Standart Funktion i2c_init(), um die pins 
zu waehlen usw. Dabei funktioniert diese Initalisierungfunktion aber 
nicht. In die Register wird nicht das geschrieben was in der Bibliothek 
steht.

Die Funktion i2c_init() taucht komischerweise in der Bib aber 2x auf!!? 
Mit verschiedenem Inhalt(siehe //??????????????? im Codeauszug unten). 
Habe sowas noch nie gesehn. Werden wenn ich nun in der Hauptroutine 
i2c_init() aufrufe nun beide Funktionsteile ausgefuehrt oder muss ich da 
was beachten. Bei der "zweiten" Funktion steht noch als Erlaeuterung was 
mit SYNTAX: int i2c_init(); was mich ziemlich verwirrt, da die 
dazugehoerige Fkt. void ist.

Kann vielleicht jemand Licht ins Dunkel bringen.
Vielen Dank.

Gruss Thorsten


/*** BeginHeader
i2c_init,i2c_SCL_H,i2c_SCL_L,i2c_SDA_H,i2c_SDA_L,i2c_SDA,i2c_SCL */

void i2c_init(); 
//????????????????????????????????????????????????????????
int i2c_clocks_per_us;  //need declaration to prevent error in asm 
definition
                //below

#define WAIT_5_us asm ld a,(i2c_clocks_per_us) $\
             sub 2 $\
             ld b,a $\
             db 0x10, -2

//*** define C macro ***
// a machine code version of above
#define cWAIT_5_us asm ld a,(i2c_clocks_per_us) $\
             sub 3 $\
             ld b,a $\
             db 0x10,-2


//  db 
3ah,i2c_clocks_per_us&0ffh,(i2c_clocks_per_us>>8)&0ffh,0d6h,3,47h,10h,-2


// Define these to change basic bit handling
#ifndef i2c_SCL_H()
#define i2c_SCL_H() BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSCLBit)
#define i2c_SCL_L() BitWrPortI(PDDDR,&PDDDRShadow,1,I2CSCLBit)
#define i2c_SDA_H() BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSDABit)
#define i2c_SDA_L() BitWrPortI(PDDDR,&PDDDRShadow,1,I2CSDABit)
#define i2c_SCL()   BitRdPortI(PDDR,I2CSCLBit)

#define i2c_SDA()   BitRdPortI(PDDR,I2CSDABit)
#endif

/*** EndHeader */


/* START FUNCTION DESCRIPTION 
********************************************
i2c_init             <I2C.LIB>

SYNTAX: int i2c_init(); //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx

DESCRIPTION: Sets up the SCL and SDA port pins for open-drain output
         Also initializes delay constant
         Acknowledgement:
           This library is programmed for Rabbit Semiconductor by
               KENT JOHANSEN
               ANAKRON / ANAKRON CANADA INC
               www.anakron.com
               kent@anakron.com



END DESCRIPTION 
**********************************************************/
nodebug
void i2c_init() 
//?????????????????????????????????????????????????????????
{
   // Set the bits to tristate and the output to 0. Toggle using
   //tristate reg.
  // This function affects the port D transfer transfer clock
  // Transfer clock on port D is PCLK/2
  WrPortI(PDCR,&PDCRShadow,0);
  BitWrPortI(PDFR ,&PDFRShadow ,0,I2CSCLBit);
  // Set the bits to normal function
  BitWrPortI(PDFR ,&PDFRShadow ,0,I2CSDABit);
  BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSCLBit);
  // Set the bits to input (=0)
  BitWrPortI(PDDDR,&PDDDRShadow,0,I2CSDABit);
  BitWrPortI(PDDCR,&PDDCRShadow,1,I2CSCLBit);
  // Set the bits to Open Drain
  BitWrPortI(PDDCR,&PDDCRShadow,1,I2CSDABit);
  BitWrPortI(PDDR ,&PDDRShadow ,0,I2CSCLBit);
  // Set the outputs to 0, when outputs
  BitWrPortI(PDDR ,&PDDRShadow ,0,I2CSDABit);
  i2c_clocks_per_us = (int)(19200L*32*freq_divider/1000000L);
  if(i2c_clocks_per_us < 3)
  {
    i2c_clocks_per_us = 3;
  }
}

von Karl H. (kbuchegg)


Lesenswert?

> Die Funktion i2c_init() taucht komischerweise in der Bib aber 2x auf!!?
> Mit verschiedenem Inhalt(siehe //??????????????? im Codeauszug unten).

Weis nicht was du hast. Die Funktion ist nur einmal definiert.

Das hier:
1
void i2c_init();

ist ein ganz normaler Funktionsprototyp. Also die Information an
den Compiler, dass es irgendwo eine Funktion namens i2c_init
gibt. Ihre Argumente sind nicht näher spezifiziert, aber zumindest
steht fest, dass i2c_init() nichts zurückliefert.
1
void i2c_init( void );

wäre besser gewesen. Ist aber auch kein Beinbruch.

Das hier
1
/* START FUNCTION DESCRIPTION
2
********************************************
3
i2c_init             <I2C.LIB>
4
5
SYNTAX: int i2c_init(); //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
6
7
DESCRIPTION: Sets up the SCL and SDA port pins for open-drain output
8
         Also initializes delay constant
9
         Acknowledgement:
10
           This library is programmed for Rabbit Semiconductor by
11
               KENT JOHANSEN
12
               ANAKRON / ANAKRON CANADA INC
13
               www.anakron.com
14
               kent@anakron.com
15
16
17
18
END DESCRIPTION
19
**********************************************************/

ist ein ganz gewöhnlicher Kommentar. Vom öffnenden /* bis zum
schliessenden */. Was da drinnen steht, ist für den Compiler
uninteressant.

Und hier:
1
nodebug
2
void i2c_init()
3
//?????????????????????????????????????????????????????????
4
{
5
   // Set the bits to tristate and the output to 0. Toggle using
6
   //tristate reg.
7
  // This function affects the port D transfer transfer clock
8
  // Transfer clock on port D is PCLK/2
9
  WrPortI(PDCR,&PDCRShadow,0);
10
  BitWrPortI(PDFR ,&PDFRShadow ,0,I2CSCLBit);
11
  // Set the bits to normal function
12
  ...

kommt dann die Funktion.
Der Prototyp lautete auf  void i2c_init()  und die Implementierung
lautet auf   void i2c_init().
Passt also alles zusammen. Der einzige gerechtfertigte Kritikpunkt
besteht darin, dass der Funktionskommentar (und damit die Doku)
nicht zur Funktion passt. Darüber kann man erbost sein, das kommt
aber öfter vor als man denkt. Nichts was einen Profi beunruhigen
würde.

Das nodebug dürfte eine Attributierung der Funktion sein, die
dem Debugger verbietet in die Funktion hineinzusteppen.



von Thorsten (Gast)


Lesenswert?

Danke Karl Heinz Buchegger,

ja stimmt natuerlich. War nur verwirrt wegen falschem Kommentar.

Ist vielleicht weit hergeholt jetzt, aber woran koennte es noch liegen, 
dass nicht in die Register geschrieben wird. Auch wenn das der einzige 
Befehl in meinem Programm ist fuehrt ihn der Prozessor nicht aus. Die 
Register aendern Ihre Werte nicht!!!???
Thorsten

von Karl H. (kbuchegg)


Lesenswert?

Thorsten wrote:

> Auch wenn das der einzige
> Befehl in meinem Programm ist fuehrt ihn der Prozessor nicht aus. Die
> Register aendern Ihre Werte nicht!!!???

Tut mir leid. Da kann ich dir nicht weiterhelfen.
Hast du keine Möglichkeit das mal mit einem Debugger
durchzusteppen?
Spontan würde ich mal auf irgendeinen Konfigurationsfehler
tippen.


von Thorsten (Gast)


Lesenswert?

Ich habe die Bibliothek schon ins Main-Programm rauskopiert und dort 
schrittweise ausgefuehrt, es laeuft auch alles durch aber wie gesagt 
ohne Veraenderung der Register.
Was meinst du mit Konfigurationsfehler genau?
Thorsten

von Karl H. (kbuchegg)


Lesenswert?

> Was meinst du mit Konfigurationsfehler genau?

Na ja. Irgendeine Konfiguration die Vorasusseztung
für das korrekte funktionieren ist.

Ist aber nur so eine Idee. Ich hab sowieso schon das Gefühl
mich zuweit aus dem Fenster zu lehnen.

von Peter D. (peda)


Lesenswert?

Sieht aus wie Software-I2C, geht also nur als Single-Master.

Irgendwie scheint diese CPU keinen direkten Zugriff auf die Port zu 
haben und muß daher immer eine extra Schreibfunktion benutzen.

Auch sind die Portregister nicht rücklesbar und müssen daher zusätzlich 
noch in ein Schattenregister dubliziert werden, damit man vorherige 
Konfigurationen nicht zunichte macht.

Wirklich ne sehr umständliche CPU.

Wie einfach ists doch beim 8051.


Peter

von Thosten (Gast)


Lesenswert?

Hast verdammt Recht Peter, aber ich MUSS diesen tollen uC jetzt nehmen, 
da mein Chef schon dutzenden davon bestellt hat weil diese sooo toll und 
soooo EMV arm sind.

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.