1 | #define BYTE unsigned char
|
2 | #define WORD unsigned short
|
3 | #define I2C_PORT_SEL P3SEL
|
4 | #define EEPROM_ADDRESS 0x50
|
5 |
|
6 |
|
7 | void I2C_Init(void) // Initialisierung des I²C-Moduls
|
8 | {
|
9 | I2C_PORT_SEL |= 0x0A; // P3.1 und P3.3 --> SDA/SCL des USART0-Moduls
|
10 | UCTL0 |= I2C+SYNC; // USART0 auf I²C-Betrieb stellen
|
11 | UCTL0 &= ~I2CEN; // I²C-Modul vor der Konfiguration deaktivieren
|
12 | I2CTCTL = I2CTRX+I2CSSEL_2; // Transmit Mode und SMCLK als Taktquelle
|
13 | I2CSA = EEPROM_ADDRESS; // Adresse des EEPROM festlegen
|
14 | I2CPSC = 0x00; // Vorteiler für I²C-Takt = SMCLK/1
|
15 | I2CSCLH = 0x03; // (SMCLK ist 4MHz)
|
16 | UCTL0 |= I2CEN; // I²C-Modul aktivieren
|
17 | }
|
18 |
|
19 |
|
20 | void I2C_Write_Init(void) // I²C-Initialisierung für Schreiben
|
21 | {
|
22 | UCTL0 |= MST; // Master Mode einstellen
|
23 | I2CTCTL |= I2CTRX; // Transmit Mode (R/W-Bit ist 0)
|
24 | I2CIFG &= ~TXRDYIFG; // Transmit-Ready-Flag löschen
|
25 | I2CIE = TXRDYIE; // Transmit-Ready-Interrupt aktivieren
|
26 | }
|
27 |
|
28 |
|
29 | void I2C_Read_Init(void) // I²C-Initialisierung für Lesen
|
30 | {
|
31 | I2CTCTL &= ~I2CTRX; // Receive Mode (R/W-Bit ist 1)
|
32 | I2CIE = RXRDYIE; // Receive-Ready-Interrupt aktivieren
|
33 | }
|
34 |
|
35 |
|
36 | void EEPROM_Write(WORD adr, BYTE data) // Schreiben eines Bytes in das EEPROM
|
37 | {
|
38 | BYTE adr_hi;
|
39 | BYTE adr_lo;
|
40 |
|
41 | while(I2CDCTL & I2CBUSY); // warten, solange I²C-Modul noch aktiv ist
|
42 |
|
43 | adr_hi = adr >> 8; // High-Byte der Adresse berechnen
|
44 | adr_lo = adr & 0xFF; // Low-Byte der Adresse berechnen
|
45 |
|
46 | I2C_buffer[2] = adr_hi; // I²C-Buffer mit den zu sendenden Bytes füllen
|
47 | I2C_buffer[1] = adr_lo;
|
48 | I2C_buffer[0] = data;
|
49 | pointer = 2; // Buffer-Pointer setzen
|
50 |
|
51 | I2C_Write_Init();
|
52 | I2CNDAT = 3; // Zähler der zu übertragenden Bytes
|
53 | I2CTCTL |= I2CSTT+I2CSTP; // Start-Zustand senden - I²C-Kommunikation aktiv
|
54 | } // Stop-Zustand wird automatisch gesendet, sobald
|
55 | // alle Bytes übertragen sind
|
56 |
|
57 |
|
58 | BYTE EEPROM_Read(WORD adr) // Lesen eines Bytesatzes aus dem EEPROM
|
59 | {
|
60 | BYTE adr_hi;
|
61 | BYTE adr_lo;
|
62 |
|
63 | while(I2CDCTL & I2CBUSY); // warten, solange I²C-Modul noch aktiv ist
|
64 |
|
65 | adr_hi = adr >> 8; // High-Byte der Adresse berechnen
|
66 | adr_lo = adr & 0xFF; // Low-Byte der Adresse berechnen
|
67 |
|
68 | I2C_buffer[1] = adr_hi; // I²C-Buffer mit den zu sendenden Bytes füllen
|
69 | I2C_buffer[0] = adr_lo;
|
70 | pointer = 1; // Buffer-Pointer setzen
|
71 |
|
72 | I2C_Write_Init();
|
73 | I2CNDAT = 2; // Zähler der zu übertragenden Bytes
|
74 | I2CIFG &= ~ARDYIFG; // Access-Ready-Flag löschen
|
75 | I2CTCTL |= I2CSTT; // Start-Zustand senden - I²C-Kommunikation aktiv
|
76 | // Stop-Zustand wird automatisch gesendet, sobald
|
77 | // alle Bytes übertragen sind
|
78 |
|
79 | while((~I2CIFG) & ARDYIFG); // Ende der Übertragung abwarten
|
80 |
|
81 | I2C_Read_Init();
|
82 | I2CNDAT = 1; // Zähler der zu empfangenden Datenbytes
|
83 |
|
84 | I2CIFG &= ~ARDYIFG; // Access-Ready-Flag löschen
|
85 | I2CTCTL |= I2CSTT+I2CSTP; // Start-Zustand senden - I²C-Kommunikation aktiv
|
86 | // Stop-Zustand wird automatisch gesendet, sobald
|
87 | // alle Bytes übertragen sind
|
88 | while((~I2CIFG) & ARDYIFG); // Ende der Übertragung abwarten
|
89 | return I2C_buffer[0]; // empfangenes Byte übergeben
|
90 | }
|
91 |
|
92 |
|
93 | BYTE EEPROM_Read_Cont(void)
|
94 | {
|
95 | while (I2CDCTL & I2CBUSY); // warten, solange I²C-Modul noch aktiv ist
|
96 | I2C_Read_Init();
|
97 | U0CTL |= MST; // Master Mode einstellen
|
98 | I2CNDAT = 1; // Zähler der zu empfangenden Bytes
|
99 | I2CIFG &= ~ARDYIFG; // Access-Ready-Flag löschen
|
100 | I2CTCTL |= I2CSTT+I2CSTP; // Start-Zustand senden - I²C-Kommunikation aktiv
|
101 | // Stop- und Restart-Zustände werden automatisch
|
102 | // gesendet
|
103 | while ((~I2CIFG) & ARDYIFG); // Ende der Übertragung abwarten
|
104 | return I2C_buffer[0]; // empfangenes Byte übergeben
|
105 | }
|
106 |
|
107 |
|
108 | void EEPROM_Ack_Polling(void) // Testen auf Abschluss des Schreibzyklus
|
109 | {
|
110 | while(I2CDCTL & I2CBUSY); // warten, solange I²C-Modul noch aktiv ist
|
111 | UCTL0 &= ~I2CEN; // I²C-Modul vor der Rekonfiguration deaktivieren
|
112 | I2CTCTL |= I2CRM; // Software kontrolliert Übertragung
|
113 | UCTL0 |= I2CEN; // I²C-Modul aktivieren
|
114 | I2CIFG = NACKIFG; // No-Acknowledge-Flag setzen
|
115 | while (NACKIFG & I2CIFG)
|
116 | {
|
117 | I2CIFG = 0x00; // Interrupt-Flags löschen
|
118 | U0CTL |= MST; // Master Mode einstellen
|
119 | I2CTCTL |= I2CTRX; // Transmit Mode (R/W-Bit ist 0)
|
120 | I2CTCTL |= I2CSTT; // Start-Zustand senden
|
121 |
|
122 | while (I2CTCTL & I2CSTT); // warten, bis I2CSTT-Bit wieder gelöscht ist
|
123 |
|
124 | I2CTCTL |= I2CSTP; // nach Adress-Übertragung Stop-Zustand senden
|
125 | // --> I²C-Kommunikation aktiv
|
126 | while (I2CDCTL & I2CBUSY); // warten, solange I²C-Modul noch aktiv ist
|
127 | }
|
128 | UCTL0 &= ~I2CEN; // I²C-Modul vor der Rekonfiguration deaktivieren
|
129 | I2CTCTL &= ~I2CRM; // I²C-Modul kontrolliert Übertragung
|
130 | UCTL0 |= I2CEN; // I²C-Modul aktivieren
|
131 | return;
|
132 | }
|
133 |
|
134 |
|
135 | #pragma vector = USART0TX_VECTOR // ISR
|
136 | __interrupt void ISR_I2C(void)
|
137 | {
|
138 | switch (I2CIV)
|
139 | {
|
140 | case I2CIV_AL: // Interrupt-Vektor: Arbitrierung verloren (ALIFG)
|
141 | break;
|
142 | case I2CIV_NACK: // Interrupt-Vektor: Kein Acknowledge (NACKIFG)
|
143 | break;
|
144 | case I2CIV_OA: // Interrupt-Vektor: Eigene Adresse (OAIFG)
|
145 | break;
|
146 | case I2CIV_ARDY: // Interrupt-Vektor: Zugriff bereit (ARDYIFG)
|
147 | break;
|
148 | case I2CIV_RXRDY: // Interrupt-Vektor: Empfang bereit (RXRDYIFG)
|
149 | I2C_buffer[0] = I2CDRB; // empfangene Daten in den Buffer speichern
|
150 | break;
|
151 | case I2CIV_TXRDY: // Interrupt-Vektor: Übertragung bereit (TXRDYIFG)
|
152 | I2CDRB = I2C_buffer[pointer];
|
153 | pointer = pointer-1;
|
154 | if (pointer==0)
|
155 | I2CIE &= ~TXRDYIE; // Transmit-Ready-Interrupt deaktivieren
|
156 | break;
|
157 | case I2CIV_GC: // Interrupt-Vektor: Allgemeiner Aufruf (GCIFG)
|
158 | break;
|
159 | case I2CIV_STT: // Interrupt-Vektor: Start-Zustand empfangen (STTIFG)
|
160 | break;
|
161 | }
|
162 | }
|