IIC nur in C

Gast #582428
Lesenswert?
• ▲
▼
Hallo Zusammen,

ich bin auf der Suche nach einer reinen einfachen IIC Routine ohne 
Assembler für einen 8591(AD Wandler). Bisher habe ich die Routinen von 
Peter Fleury verwendet, die auch gut funktionieren.

Zum besseren Verständnis für meine Schüler hätte ich aber gerne eine 
reine C-Routine ohne Assembler. Ich hab mir da zwar was gebastelt (vgl. 
Dateianhang) - funktioniert aber nicht.

Vielen Dank carly
Angehängte Dateien:
Gast #582687
Lesenswert?
• ▲
▼
wenn du schon <util/delay.h> include'st, warum benutzt du dann nicht 
auch die entsprechenden Funktionen ??
1
void i2c_warte(void)
2
{
3
 _delay_us(10); // 1µs ist ein Takt bei 1Mhz...
4
}
5
//oder auch
6
#define I2WAIT _delay_us(10);
7

8
// und das
9
sbi(PORTB,SDA);                      // SDA-Leitung ist jetzt Eingang
10
// .. stimmt irgendwie nicht ;)

(Außerdem mag ich weder sbi()/cbi(), noch mehrere Anweisungen pro 
zeile!!, aber das ist meine Meinung ;) )

hth. jörg

ps.: Hast du mal in der Codesammlung nach twi* oder i2c* gesucht, da 
gibts doch bestimmt C-Routinen
Moderator Persönliche Seite #583245
Lesenswert?
• ▲
▼
> sbi/cbi ist deprecated

Er hat ja seine eigene Implementierung drübergeschrieben.

Ich finde die Wahl trotzdem nicht glücklich, gerade auch für Lernende.
Wenn's schon unbedingt in Makros verwurschtelt werden muss, dann
wären SETBIT und CLEARBIT allemal aussagekräftiger.  Eigentlich ist
es aber sinnvoller, gleich noch einen Schritt weiter zu gehen und eine
Art HAL daraus zu machen (hardware abstraction layer), sodass z. B.
die Startbedingung dann aussieht wie:
1
void i2c_start(void)
2
{
3
  SDA_HIGH; i2c_warte();
4
  SCL_HIGH; i2c_warte();
5
  SDA_LOW;  i2c_warte();
6
  SCL_LOW;  i2c_warte();
7
}

Ansonsten Zustimmung dazu, dass man delays nicht ,,nach Gutdünken''
zimmern sollte, entweder einen Timer oder die Funktionen aus
<util/delay.h> bzw. auch <util/delay_basic.h> nehmen.  Das ist zwar
wieder inline asm, aber in diesem Falle vom Hersteller des Systems,
damit transparent für den Nutzer.  Man kann sogar so weit gehen,
den Lernenden an Hand des aus der ,,privaten'' Zählschleife generierten
(oder besser: nicht generierten) Codes zu zeigen, warum man genau
sowas nicht machen darf und an welchen Stellen der C-Standard dem
Compiler Freiraum für seine Optimierungen gegeben hat.
Gast #583314
Lesenswert?
• ▲
▼
1
  if (Daten >= 128)
2
    sbi(PORTB,SDA);
3
              
4
    else
5
    cbi(PORTB,SDA);  
6
    
7
    i2c_warte();
8
         
9
    sbi(PORTB,SCL);
10
      Daten <<= 1; 
11

12
    i2c_warte();
13
    cbi(PORTB,SCL); i2c_warte();
14
  }

Ich finde das >= 128 gefährlich. Je nach Datentyp kann das zu Problemen 
führen nach dem Shift. Besser & 128 verwenden.
Gast #583324
Lesenswert?
• ▲
▼
> Ich finde das >= 128 gefährlich.
> Je nach Datentyp kann das zu Problemen führen nach dem Shift.

Stimmt, der Typ von Daten (die ganz Zeile glaskugelanwerf 
"i2c_schreibe(unsigned char Daten)") fehlt
Es sieht außerdem unlogisch aus und Lernende müssen jedes Mal zwischen 
Bit- und Dezimaldarstellung hin- und herdenken
Ich würde da:
1
if (Daten & (1<<7))
2
    ...
nehmen (funktioniert eben auch mit signed-Typen)

hth. Jörg

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren