3. IIC-Schnittstelle auf LPC 2138

Gast #582522
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren