Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <intrins.h>
- at 0xB4 sbit P3_4;
- at 0xB5 sbit P3_5;
- #define SCL P3_4
- #define SDA P3_5
- void delay(unsigned int);
- void I2C_init(void);
- void I2C_start(void);
- void I2C_stop(void);
- bit I2C_schreiben(char);
- bit ACK;
- char Adresse; // Slave-Addressierung (Baustein + Adresspins + Richtungsbit)
- void main() {
- char wert;
- I2C_init();
- // Konfiguration:
- wert = 0x40;
- Adresse = 0b01000000;
- while(1) {
- I2C_start(); // Startbedingung anlegen (SDA = abfallende Flanke, während SCL = H = 1)
- ACK = I2C_schreiben(Adresse); // Addressierung des Slaves: Baustein (MSB/Bit7 - Bit4) + Adresspins (Bit3 - Bit1) + Richtungsbit (LSB/Bit0)
- ACK = I2C_schreiben(wert); // Payload übertragen
- I2C_stop(); // Stopbedingung anlegen (SDA = steigende Flanke, während SCL = H = 1)
- }
- }
- // Ruhezustand/definierte Startpegel
- void I2C_init(void) {
- SDA = SCL = 1;
- delay(1); // Mindesttimiung: 4 Mikrosekunden
- }
- /* Startbedingung auslösen
- * SDA: abfallende Flanke
- * SCL: High-Pegel
- */
- void I2C_start(void) {
- I2C_init(); // Ruhezustand herstellen (SCL = SDA = 1)
- SDA = 0; // HIGH -> LOW (abfallende SCL-Flanke als Startbedinung, da SCL = 1 = HIGH)
- delay(1); // Delay, damit Startbedinung als solche erkannt wird (Mindesttiming: 4 Mikrosekunden)
- SCL = 0; // nachfolgende Bits für ungültig erklären
- delay(1); // Mindesttiming: 4.7 Mikrosekunden
- }
- /* Stopbedingung auslösen
- * SDA: steigende Flanke
- * SCL: High-Pegel
- */
- void I2C_stop(void) {
- SDA = 0;
- SCL = 1; // notwendig für Stopbedingung
- delay(1); // Mindesttiming berücksichtigen: mindestens 4 Mikrosekunden
- SDA = 1; // steigende Flanke (LOW -> HIGH) als Stopbedingung
- delay(1); // Delay, damit Stopbedingung als solche erkannt wird
- }
- // Semantik des Rückgabewertes: 1 = ACK, 0 = NACK (Empfangsbestätigung)
- bit I2C_schreiben(char daten) {
- bit datenbit, ACK_Flag;
- unsigned char i;
- // Datenbits einzeln auf Datenleitung anlegen (MSB --> LSB)
- for (i = 7; i >= 0; i--) {
- /* entsprechendes Datenbit aus Datenbyte extrahieren:
- * Funktionweise:
- * - relevantes Bit auf LSB-Position schieben
- * - LSB gibt Parität an => Parität gibt LSB-Wert an
- * => wenn gerade, dann LSB = 0, wenn ungerade, dann LSB = 1
- * (Parität mittels Modulo-Operator prüfen)
- */
- datenbit = (daten >> i) % 2;
- SDA = datenbit; // extrahiertes Datenbit anlegen
- SCL = 1; // angelegtes Datenbit für gültig erklären
- delay(1); // Delay, damit ausreichend Zeit zum Auswerten bleibt (Mindesttiming: 4 Mikrosekunden)
- SCL = 0; // nachfolgende Bits für ungültig erklären
- delay(1); // ausreichend Abstand zwischen Schreibvorgängen der Datenbits (Mindesttiming berücksichtigen: mindestens 4.7 Mikrosekunden)
- }
- SDA = 1; // Freigabe der Datenleitung vom Transmitter (notwendig, da Wired AND)
- SCL = 1; // Taktvorgabe vom Master für Slave (wartet auf ACK vom Slave)
- delay(1); // Mindesttiming berücksichtigen (mind. 4 Mikrosekunden): Slave soll Empfangsbestätigung in diesem Zeitraum anlegen
- ACK_Flag = SDA; // Empfangsbestätigung von Slave auslesen
- SCL = 0; // nachfolgende Bits für ungültig erklären
- delay(1); // Mindesttiming berücksichtigen (mind. 4.7 Mikrosekunden)
- return ACK_Flag; // Rückgabewert gibt Auskunft über erfolgreichen Empfang der Daten durch Slave (1 = ACK, 0 = NACK)
- }
- void delay(unsigned int ms) {
- unsigned int i, k;
- for(i = 0; i < ms; i++)
- for(k = 0; k < 180; k++)
- _nop_();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement