Advertisement
Guest User

Untitled

a guest
Jan 29th, 2020
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.86 KB | None | 0 0
  1. #include <intrins.h>
  2.  
  3. at 0xB4 sbit P3_4;
  4. at 0xB5 sbit P3_5;
  5.  
  6. #define SCL P3_4
  7. #define SDA P3_5
  8.  
  9. void delay(unsigned int);
  10. void I2C_init(void);
  11. void I2C_start(void);
  12. void I2C_stop(void);
  13. bit I2C_schreiben(char);
  14.  
  15. bit ACK;
  16. char Adresse; // Slave-Addressierung (Baustein + Adresspins + Richtungsbit)
  17.  
  18. void main() {
  19.     char wert;
  20.     I2C_init();
  21.  
  22.     // Konfiguration:
  23.     wert = 0x40;
  24.     Adresse = 0b01000000;
  25.  
  26.     while(1) {
  27.         I2C_start();                    // Startbedingung anlegen (SDA = abfallende Flanke, während SCL = H = 1)
  28.         ACK = I2C_schreiben(Adresse);   // Addressierung des Slaves: Baustein (MSB/Bit7 - Bit4) + Adresspins (Bit3 - Bit1) + Richtungsbit (LSB/Bit0)
  29.         ACK = I2C_schreiben(wert);      // Payload übertragen
  30.         I2C_stop();                     // Stopbedingung anlegen (SDA = steigende Flanke, während SCL = H = 1)
  31.     }
  32.  
  33. }
  34.  
  35. // Ruhezustand/definierte Startpegel
  36. void I2C_init(void) {
  37.     SDA = SCL = 1;
  38.     delay(1);       // Mindesttimiung: 4 Mikrosekunden
  39. }
  40.  
  41.  
  42. /* Startbedingung auslösen
  43.  * SDA: abfallende Flanke
  44.  * SCL: High-Pegel
  45.  */
  46. void I2C_start(void) {
  47.     I2C_init();     // Ruhezustand herstellen (SCL = SDA = 1)
  48.    
  49.     SDA = 0;        // HIGH -> LOW (abfallende SCL-Flanke als Startbedinung, da SCL = 1 = HIGH)
  50.     delay(1);       // Delay, damit Startbedinung als solche erkannt wird (Mindesttiming: 4 Mikrosekunden)
  51.     SCL = 0;        // nachfolgende Bits für ungültig erklären
  52.     delay(1);       // Mindesttiming: 4.7 Mikrosekunden
  53. }
  54.  
  55.  
  56. /* Stopbedingung auslösen
  57.  * SDA: steigende Flanke
  58.  * SCL: High-Pegel
  59.  */
  60. void I2C_stop(void) {
  61.     SDA = 0;
  62.     SCL = 1;        // notwendig für Stopbedingung
  63.     delay(1);       // Mindesttiming berücksichtigen: mindestens 4 Mikrosekunden
  64.     SDA = 1;        // steigende Flanke (LOW -> HIGH) als Stopbedingung
  65.     delay(1);       // Delay, damit Stopbedingung als solche erkannt wird
  66. }
  67.  
  68.  
  69. // Semantik des Rückgabewertes: 1 = ACK, 0 = NACK (Empfangsbestätigung)
  70. bit I2C_schreiben(char daten) {
  71.     bit datenbit, ACK_Flag;
  72.     unsigned char i;
  73.    
  74.     // Datenbits einzeln auf Datenleitung anlegen (MSB --> LSB)
  75.     for (i = 7; i >= 0; i--) {
  76.         /* entsprechendes Datenbit aus Datenbyte extrahieren:
  77.          * Funktionweise:
  78.          *  - relevantes Bit auf LSB-Position schieben
  79.          *  - LSB gibt Parität an => Parität gibt LSB-Wert an
  80.          *      => wenn gerade, dann LSB = 0, wenn ungerade, dann LSB = 1
  81.          *      (Parität mittels Modulo-Operator prüfen)
  82.          */
  83.         datenbit = (daten >> i) % 2;
  84.        
  85.         SDA = datenbit; // extrahiertes Datenbit anlegen
  86.         SCL = 1;        // angelegtes Datenbit für gültig erklären
  87.         delay(1);       // Delay, damit ausreichend Zeit zum Auswerten bleibt (Mindesttiming: 4 Mikrosekunden)
  88.         SCL = 0;        // nachfolgende Bits für ungültig erklären
  89.         delay(1);       // ausreichend Abstand zwischen Schreibvorgängen der Datenbits (Mindesttiming berücksichtigen: mindestens 4.7 Mikrosekunden)
  90.     }
  91.    
  92.     SDA = 1;            // Freigabe der Datenleitung vom Transmitter (notwendig, da Wired AND)
  93.     SCL = 1;            // Taktvorgabe vom Master für Slave (wartet auf ACK vom Slave)
  94.     delay(1);           // Mindesttiming berücksichtigen (mind. 4 Mikrosekunden): Slave soll Empfangsbestätigung in diesem Zeitraum anlegen
  95.     ACK_Flag = SDA;     // Empfangsbestätigung von Slave auslesen
  96.    
  97.     SCL = 0;            // nachfolgende Bits für ungültig erklären
  98.     delay(1);           // Mindesttiming berücksichtigen (mind. 4.7 Mikrosekunden)
  99.    
  100.     return ACK_Flag;    // Rückgabewert gibt Auskunft über erfolgreichen Empfang der Daten durch Slave (1 = ACK, 0 = NACK)
  101. }
  102.  
  103.  
  104. void delay(unsigned int ms) {
  105.     unsigned int i, k;
  106.     for(i = 0; i < ms; i++)
  107.         for(k = 0; k < 180; k++)
  108.             _nop_();
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement