eeprom.c


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