www.mikrocontroller.net

Forum: Compiler & IDEs IIC nur in C


Autor: carly (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Werner A. (homebrew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wird deine warteschleife vielleicht wegoptimiert? Ich glaube du must die 
variable als volatile deklarieren, damit der compiler meint, sie könnte 
sich auch innerhalb der schleife ändern...

Autor: carly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen Dank für deinen Hinweis "volatile" hats aber leider auch nicht 
gebracht;
 carly

Autor: peter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Carly

Vielleicht kannst Du mit meinen I2C Routinen etwas anfangen..? (Siehe 
Attachement)
Die Funktionen sollte gut überschaubar sein.

MfG  Peter

Autor: TechInfo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Procyon avrlib enthält ebenfalls eine sehr umfangreiche I2C-lib.

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du schon <util/delay.h> include'st, warum benutzt du dann nicht 
auch die entsprechenden Funktionen ??
void i2c_warte(void)
{
 _delay_us(10); // 1µs ist ein Takt bei 1Mhz...
}
//oder auch
#define I2WAIT _delay_us(10);

// und das
sbi(PORTB,SDA);                      // SDA-Leitung ist jetzt Eingang
// .. 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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sbi/cbi ist deprecated (veraltet!).

http://www.nongnu.org/avr-libc/user-manual/deprecated.html

PS: Zumindest in der AVR-libc..

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
void i2c_start(void)
{
  SDA_HIGH; i2c_warte();
  SCL_HIGH; i2c_warte();
  SDA_LOW;  i2c_warte();
  SCL_LOW;  i2c_warte();
}

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.

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  if (Daten >= 128)
    sbi(PORTB,SDA);
              
    else
    cbi(PORTB,SDA);  
    
    i2c_warte();
         
    sbi(PORTB,SCL);
      Daten <<= 1; 

    i2c_warte();
    cbi(PORTB,SCL); i2c_warte();
  }                              

Ich finde das >= 128 gefährlich. Je nach Datentyp kann das zu Problemen 
führen nach dem Shift. Besser & 128 verwenden.

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
if (Daten & (1<<7))
    ...
nehmen (funktioniert eben auch mit signed-Typen)

hth. Jörg

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.