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


von heinvonnewerft (Gast)


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:
1
#include <target.h>  //Header-Datei des LPC2138 einbinden
2
3
//Eine Delay-Fkt (Einfacher Aufruf und Rueckgabe):
4
void delay(void){
5
  //Tue nichts  
6
}
7
8
9
//zwei Unterfunktionen, um die SDA- und SCK-Leitungen zu setzen(zurueckzusetzen)
10
//  mit Beruecksichtigung der Funktion der GPIO Ports
11
12
void setze_sda(unsigned char state){
13
  if (state == 0){
14
    Intern_io0dir |= 0x20000000;  //P0.29 ist Ausgang
15
    Intern_io0clr |= 0x20000000;  //P0.29 auf '0'
16
  }else{
17
    Intern_io0dir &= 0xDFFFFFFF;  //P0.29 ist Eingang -> Pull-up Widerstand zieht die Leitung hoch
18
    usleep(1);
19
  }
20
}
21
22
void setze_sck(unsigned char state){
23
  if (state == 0){
24
    Intern_io0dir |= 0x10000000;  //P0.28 ist Ausgang
25
    Intern_io0clr |= 0x10000000;  //P0.28 auf '0'
26
  }else{
27
    Intern_io0dir &= 0xEFFFFFFF;  //P0.28 ist Eingang -> Pull-up Widerstand zieht die Leitung hoch
28
    usleep(1);
29
30
  }
31
}
32
//zwei Unterfunktionen um den Status von P0.28 und P0.29 zu lesen!
33
34
unsigned char lese_sda(void){
35
  unsigned char wert;
36
  
37
  Intern_io0dir &= 0xDFFFFFFF;  //P0.29 ist Eingang
38
  wert = (Intern_io0pin & 0x20000000) ? 1:0;
39
  return wert;
40
}
41
42
unsigned char lese_sck(void){
43
  unsigned char wert;
44
  
45
  Intern_io0dir &= 0xEFFFFFFF;  //P0.28 ist Eingang
46
  wert = (Intern_io0pin & 0x10000000) ? 1:0;
47
  return wert;
48
} 
49
50
//-------------------------------------------------------------------------------
51
52
//Low-Level-IIC-Funktionen (Bus-Protokoll):
53
54
void s_iic_init(void)
55
{ 
56
  int n;
57
  
58
  setze_sda(1);
59
  delay();
60
  setze_sck(0);
61
  for (n=0;n<4;n++){
62
    s_iic_stop();
63
    delay();
64
  }
65
}
66
67
void s_iic_start(void){
68
  setze_sda(1); delay();
69
  setze_sck(1); delay();
70
  setze_sda(0); delay();
71
  setze_sck(0); delay();
72
}
73
74
void s_iic_stop(void){
75
  setze_sda(0); delay();
76
  setze_sck(1); delay();
77
  setze_sda(1); delay();
78
}  
79
80
void s_iic_putbyte(unsigned char buffer){
81
  int n;
82
  unsigned char ack; //Ack sent?
83
  for (n=7;n>=0;n--){
84
    setze_sda((buffer & 0x80)? 1:0);
85
    setze_sck(1);
86
    buffer <<= 1;
87
    setze_sck(0);
88
  }
89
  setze_sda(1);
90
  setze_sck(1);delay();
91
  ack = lese_sda();
92
  setze_sck(0);
93
}
94
95
unsigned char s_iic_getbyte(unsigned char ack){
96
  int n;
97
  unsigned char buffer = 0;
98
  
99
  setze_sda(1);
100
  for (n=0;n<8;n++){
101
    buffer <<= 1;
102
    do {
103
      setze_sck(1);
104
    } while (lese_sck == 0);  //auf Clock stretching warten
105
    delay();
106
    if (lese_sda() > 0) buffer |= 1;  //Wert vom Bus lesen
107
    setze_sck(0);
108
  }
109
  if (ack) setze_sda(0);  //ACK senden
110
  else setze_sda(1);   //ACK nicht senden
111
  setze_sck(1);
112
  delay();
113
  setze_sck(0);
114
  setze_sda(1);
115
116
  return buffer; 
117
}
118
//-------------------------------------------------------------------------
119
120
//High-Level-IIC-Funktionen (Read'n'Write):
121
void s_iic_read(unsigned char addr, int anzahl, unsigned char *buffer){
122
  int n;
123
  
124
  addr |= 0x01;  //READ-FLAG setzen
125
  s_iic_start();
126
  s_iic_putbyte(addr);
127
  
128
  for (n=0; n < anzahl; n++){
129
    if (n <anzahl-1) buffer[n] = s_iic_getbyte(1);
130
    else buffer[n] = s_iic_getbyte(0);  //last Byte -> kein ACK senden
131
  }
132
  s_iic_stop();
133
}
134
135
void s_iic_write(unsigned char addr, int anzahl, unsigned char *buffer){
136
  int n;
137
  
138
  addr &= 0xFE;  //READ-FLAG loeschen
139
  s_iic_start();
140
  s_iic_putbyte(addr);
141
  
142
  
143
  for (n=0;n<anzahl;n++){
144
    s_iic_putbyte(buffer[n]);
145
  }
146
  s_iic_stop();
147
}

Gruß,

Hein vonne Werft

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.