eeprom.c


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
      }