www.mikrocontroller.net

Forum: Projekte & Code 3. IIC-Schnittstelle auf LPC 2138


Autor: heinvonnewerft (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

LPC 2138 hat standardmäßif 2 IIC-Schnittstellen, für ein Projekt 
brauchte ich jedoch 3 solche Schnittstellen.
Nach einiger Überlegung und einigen Tipps hier aus dem Forum, habe ich 
mir überlegt, also eine eigene IIC-Schnittstelle auf 2 GPIO-Port zu 
programmieren.
Es gibt zwar im I-Net einige Beispiele für eine solche Programmierung, 
jedoch keine, die direkt auf den LPC 2138 passt, deshalb möchte ich sie 
hier einmal posten:
#include <target.h>  //Header-Datei des LPC2138 einbinden

//Eine Delay-Fkt (Einfacher Aufruf und Rueckgabe):
void delay(void){
  //Tue nichts  
}


//zwei Unterfunktionen, um die SDA- und SCK-Leitungen zu setzen(zurueckzusetzen)
//  mit Beruecksichtigung der Funktion der GPIO Ports

void setze_sda(unsigned char state){
  if (state == 0){
    Intern_io0dir |= 0x20000000;  //P0.29 ist Ausgang
    Intern_io0clr |= 0x20000000;  //P0.29 auf '0'
  }else{
    Intern_io0dir &= 0xDFFFFFFF;  //P0.29 ist Eingang -> Pull-up Widerstand zieht die Leitung hoch
    usleep(1);
  }
}

void setze_sck(unsigned char state){
  if (state == 0){
    Intern_io0dir |= 0x10000000;  //P0.28 ist Ausgang
    Intern_io0clr |= 0x10000000;  //P0.28 auf '0'
  }else{
    Intern_io0dir &= 0xEFFFFFFF;  //P0.28 ist Eingang -> Pull-up Widerstand zieht die Leitung hoch
    usleep(1);

  }
}
//zwei Unterfunktionen um den Status von P0.28 und P0.29 zu lesen!

unsigned char lese_sda(void){
  unsigned char wert;
  
  Intern_io0dir &= 0xDFFFFFFF;  //P0.29 ist Eingang
  wert = (Intern_io0pin & 0x20000000) ? 1:0;
  return wert;
}

unsigned char lese_sck(void){
  unsigned char wert;
  
  Intern_io0dir &= 0xEFFFFFFF;  //P0.28 ist Eingang
  wert = (Intern_io0pin & 0x10000000) ? 1:0;
  return wert;
} 

//-------------------------------------------------------------------------------

//Low-Level-IIC-Funktionen (Bus-Protokoll):

void s_iic_init(void)
{ 
  int n;
  
  setze_sda(1);
  delay();
  setze_sck(0);
  for (n=0;n<4;n++){
    s_iic_stop();
    delay();
  }
}

void s_iic_start(void){
  setze_sda(1); delay();
  setze_sck(1); delay();
  setze_sda(0); delay();
  setze_sck(0); delay();
}

void s_iic_stop(void){
  setze_sda(0); delay();
  setze_sck(1); delay();
  setze_sda(1); delay();
}  

void s_iic_putbyte(unsigned char buffer){
  int n;
  unsigned char ack; //Ack sent?
  for (n=7;n>=0;n--){
    setze_sda((buffer & 0x80)? 1:0);
    setze_sck(1);
    buffer <<= 1;
    setze_sck(0);
  }
  setze_sda(1);
  setze_sck(1);delay();
  ack = lese_sda();
  setze_sck(0);
}

unsigned char s_iic_getbyte(unsigned char ack){
  int n;
  unsigned char buffer = 0;
  
  setze_sda(1);
  for (n=0;n<8;n++){
    buffer <<= 1;
    do {
      setze_sck(1);
    } while (lese_sck == 0);  //auf Clock stretching warten
    delay();
    if (lese_sda() > 0) buffer |= 1;  //Wert vom Bus lesen
    setze_sck(0);
  }
  if (ack) setze_sda(0);  //ACK senden
  else setze_sda(1);   //ACK nicht senden
  setze_sck(1);
  delay();
  setze_sck(0);
  setze_sda(1);

  return buffer; 
}
//-------------------------------------------------------------------------

//High-Level-IIC-Funktionen (Read'n'Write):
void s_iic_read(unsigned char addr, int anzahl, unsigned char *buffer){
  int n;
  
  addr |= 0x01;  //READ-FLAG setzen
  s_iic_start();
  s_iic_putbyte(addr);
  
  for (n=0; n < anzahl; n++){
    if (n <anzahl-1) buffer[n] = s_iic_getbyte(1);
    else buffer[n] = s_iic_getbyte(0);  //last Byte -> kein ACK senden
  }
  s_iic_stop();
}

void s_iic_write(unsigned char addr, int anzahl, unsigned char *buffer){
  int n;
  
  addr &= 0xFE;  //READ-FLAG loeschen
  s_iic_start();
  s_iic_putbyte(addr);
  
  
  for (n=0;n<anzahl;n++){
    s_iic_putbyte(buffer[n]);
  }
  s_iic_stop();
}

Gruß,

Hein vonne Werft

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.