mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI und I²C zeitgleich benutzen


Autor: Andre K. (round_one)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!
Ich arbeite gerade an einem Projekt, bei dem ich eine RTC (über I²C) und 
eine SD Karte (SPI) zeitgleich an einem 18F458 betreiben muss.
Die RTC soll dabei in bestimmten Intervallen angesprochen werden und 
einen Timestamp auf die MMC schreiben.
I²C und SPI werden bei diesem PIC von den gleichen PINs angeboten. Daher 
hab ich jetzt drei Möglichkeiten:
- RTC über I²C und MMC über Soft-SPI
- RTC über Soft-I²C und MMC über SPI
- RTC über I²C und MMC über I²C-SPI Bridge

Hat jemand von euch schon Erfahrungen damit gesammelt oder einen Tipp, 
welches die einfachste bzw. logischste Lösung ist?

Vielen Dank schon mal im Voraus!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SD-Karten wuseln ja ordentlich Daten umher (FAT usw.), da würde ich das 
harte SPI nehmen.

Für die paar Byte des RTC reicht weiches I2C völlig.
Oder viele MCs erlauben direkt den Anschluß eines Uhrenquarzes im 
Stromsparmodus, dann ohne extra RTC-Chip.


Peter

Autor: Andre K. (round_one)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem Quarz geht leider nicht, da der µC schon auf einer 
Embeddedplatine sitzt.
Das mit dem Software-I²C lese ich mir jetzt schon die ganze Zeit durch. 
Aber da ich (noch) nicht soo viel Routine im C Programmieren hab, weiß 
ich nicht wirklich, wie ich da rangehen soll. Ein Beispiel in C auf PIC 
bezogen hab ich noch nicht gefunden..
Kenn vielleicht jemand einen guten Link oder hat selbst schon mal eine 
SW-I²C-Routine für PICs geschrieben?

Autor: stephan_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Andre K. (round_one)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Sprutseiten hab ich auch schon alles durch. Ich würde halt nur gerne 
in C bleiben, da ich mich da etwas "wohler" fühle :)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist fürn AVR, sollte aber leicht anzupassen sein.
Beim PIC sind wohl die Directionbits anders rum.

#define i2c_delay()     _delay_us( 2.5 / 2 )    // 2.5us = 400kHz


#define ssda_lo()       SSDA_DDR = 1
#define ssda_hi()       SSDA_DDR = 0
#define sscl_lo()       SSCL = 0
#define sscl_hi()       SSCL = 1


void si2c_start( void )                         // input: SDA = 1, SCL = x
{
  SSCL_DDR = 1;                                 // SCL = output
  SSDA = 0;
  SSDA_DDR = 0;                                 // SDA = high (input)
  sscl_hi();
  i2c_delay();
  ssda_lo();
  i2c_delay();
  sscl_lo();
}


void si2c_stop( void )                          // input: SDA = 1, SCL = 0
{
  ssda_lo();
  i2c_delay();
  sscl_hi();
  i2c_delay();
  ssda_hi();
}


static uint16_t si2c_rw( uint16_t val )         // input: SDA = x, SCL = 0
{
  for( uint8_t i = 9; i; i-- ){                         // data + ACK
    if( val & 0x8000 )
      ssda_hi();
    else
      ssda_lo();
    i2c_delay();
    sscl_hi();
    i2c_delay();
    val <<= 1;
    if( SSDA_PIN )
      val |= 0x80;
    sscl_lo();
  }
  return val;
}


uint8_t si2c_r( uint8_t nack )                          // input NACK
{
  if( nack )
    nack = 0x80;                                        // set only bit 7 !
  return si2c_rw( 0xFF00 | nack ) >> 8;                 // return data
}


uint8_t si2c_w( uint8_t val )                           // input data
{
  return si2c_rw( 0x00FF | (val<<8)) & 0xFF;            // return NACK
}


Peter

Autor: Andre K. (round_one)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für den Code, Peter! Ich werd's direkt mal testen.

Autor: kruemeltee (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch ein 8051-C-Code für Software I2C, dort sieht man sehr genau 
und auf den ersten Blick, wann welcher Pin welchen Zustand hat.
//-----------------------------------------------------------------
void delay(unsigned char warte_wert)
{
  do
  {
    warte_wert--;
  }
  while(warte_wert != 0);
}
//-----------------------------------------------------------------
void i2c_bus_start()
{
  SCL = 0;
  delay(1);
  SDA = 1;
  delay(1);
  SCL = 1;
  while(SCL==0);
  delay(1);
  SDA = 0;
  delay(1);
  SCL = 0;
  delay(1);
  SDA = 1;
  delay(1);
}
//-----------------------------------------------------------------

void i2c_bus_stop()
{
  SCL = 0;
  delay(1);
  SDA = 0;
  delay(1);
  SCL = 1;
  while(SCL==0);
  delay(1);
  SDA = 1;
  delay(1);
  SCL = 0;
  delay(1);
}

//-----------------------------------------------------------------
void i2c_bit_write(bit bit_wert)
{
  SDA = bit_wert;
  delay(1);
  SCL = 1;
  while(SCL==0);
  delay(1);
  SCL = 0;
  delay(1);
}
//-----------------------------------------------------------------
/*
bit i2c_bit_read()
{
  bit bit_wert;
  SCL = 0;
  delay(1);
  SDA = 1;
  delay(1);
  SCL = 1;
  while(SCL==0);
  delay(1);
  bit_wert = SDA;
  SCL = 0;
  delay(1);
  SDA = 0;
  delay(1);
  return(bit_wert);
}
*/
//-----------------------------------------------------------------
void i2c_ack_slave()
{
  SCL = 0;
  delay(1);
  SDA = 1;
  delay(1);
  SCL = 1;
  while(SCL==0);
  while(SDA==1);
  delay(1);
  SCL = 0;
  delay(1);
}
//-----------------------------------------------------------------
/*
void i2c_ack_master()
{
  SCL = 0;
  delay(1);
  SDA = 0;
  delay(1);
  SCL = 1;
  while(SCL==0);
  delay(2);
  SCL = 0;
  delay(1);
  SDA = 1;
  delay(1);
}
*/
//-----------------------------------------------------------------
void i2c_byte_write(unsigned char byte_wert)
{
  unsigned char i;
  bit bit_wert;
  for(i=0;i<=7;i++)
  {
    bit_wert = (byte_wert&0x80)/128;
    i2c_bit_write(bit_wert);
    byte_wert=byte_wert<<1;
  }
}
//-----------------------------------------------------------------
/*
unsigned char i2c_byte_read()
{
  unsigned char i;
  unsigned char byte_wert=0;
  for(i=0;i<=7;i++)
  {
    byte_wert=(i2c_bit_read()<<(7-i))+byte_wert;
  }
  return(byte_wert);
}
*/

Autor: stephan_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andre K. schrieb:
> Die Sprutseiten hab ich auch schon alles durch. Ich würde halt nur gerne
> in C bleiben, da ich mich da etwas "wohler" fühle :)

Inline ASM ???

Autor: ado (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Microchip hat auch noch Funktions-Bibliotheken in denen Software und 
Hardware-Schnittstellen angesprochen werden können.

Keine Ahnung ob die was taugen.


http://ww1.microchip.com/downloads/en/devicedoc/MP...

Autor: Bernd Rüter (Firma: Promaxx.net) (bigwumpus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eine Steuerung gebaut, die I2C- und SPI-Slaves anspricht (und 
das mit 5V und 3,3V!).
Mit einem Analog-Umschalter (4053?) schalte ich die SDA/SCL-Signale auf 
jeweils einen Bus (Pull-Ups bzw -downs intelligent gewählt).
Läuft prima.
Die Software aktiviert immer das benötigte Hardware-Modul und den 
Umschalter und spricht die Geräte an.

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.