www.mikrocontroller.net

Forum: GCC bit_is_set Abfrage in Software i2c auf Atmega8

Autor: Matthias (Gast)
Datum: 04.07.2008 15:06

hi

ich bin grade mit dem Versuch beschäftigt, für einen Atmega8 mit
Winavr/GCC eine Software i2c-routine zu schreiben. Dummerweise treibt
mich dabei aber eine kleine if-Abfrage so langsam aber sicher in den
Wahnsinn. Das Ding wehrt sich schon seit tagen:
#define SCL_PORT PORTC
#define SCL_DDR  DDRC
#define SCL_PINREG PINC
#define SCL_PIN PC5
#define SDA_PORT PORTC
#define SDA_DDR DDRC
#define SDA_PINREG PINC
#define SDA_PIN PC4

unsigned char i2c_readNak(void)
{
    unsigned char data;
    unsigned char i = 1;
    // sicherstellen dass alle zustände auf richtigem ausgangspunkt sind
    SDA_DDR &= ~(1<<SDA_PIN);  // SDA: Datenrichtung: in
    SDA_PORT &= ~(1<<SDA_PIN);   // SDA: low
    SCL_DDR |= (1<<SCL_PIN);  // SCL: Datenrichtung: out
    SCL_PORT &= ~(1<<SCL_PIN);  // SCL: low
    // empfangen einleiten 
    data = 0;
    i = 1;
    while( i <= 8)    
    {
       i2c_wait_quaterpuls();
       SCL_DDR &= ~(1<<SCL_PIN);  // SCL: Datenrichtung: in (clockstreching)
       SCL_PORT |= (1<<SCL_PIN);   // SCL: high
       while( bit_is_clear(SCL_PINREG,SCL_PIN) )
       {
         asm volatile ("nop");
       }
       SCL_DDR |= (1<<SCL_PIN);  // SCL: Datenrichtung: out
       i2c_wait_quaterpuls();
       if( bit_is_set(SDA_PINREG,SDA_PIN) )
       {
          data = ( (data<<1) | 0x01);    // neue information einschreiben
       }
       else
       {
          data = ( (data<<1) | 0x00);
       }
       i2c_wait_quaterpuls();
       SCL_PORT &= ~(1<<SCL_PIN);  // SCL: low
       i2c_wait_quaterpuls();    // lowpuls abwarten  
       i = i + 1;
    }
    SDA_DDR |= (1<<SDA_PIN);  // SDA: Datenrichtung: out
    SDA_PORT |= (1<<SDA_PIN);   // SDA: high = NO ACK
    i2c_wait_quaterpuls();    // lowpuls fertig warten
    SCL_DDR &= ~(1<<SCL_PIN);  // SCL: Datenrichtung: in (clockstreching)
    SCL_PORT |= (1<<SCL_PIN);   // SCL: high
    while( bit_is_clear(SCL_PINREG,SCL_PIN) )
    {
      asm volatile ("nop");
    }
    SCL_DDR |= (1<<SCL_PIN);  // SCL: Datenrichtung: out
    i2c_wait_quaterpuls();    // highpuls abwarten
    i2c_wait_quaterpuls();
    SCL_PORT &= ~(1<<SCL_PIN);  // zurück auf "warten auf Aufgabe"

    return data;        // Daten ausgeben    
}/* i2c_readNak */
die dabei spinnende Abfrage ist die Zeile:
if(bit_is_set(SDA_PINREG,SDA_PIN) )
die spricht immer an, egal ob der Pin gesetzt ist oder nicht, was zur
Folge hat, dass der Code immer 0xff als Ergebniss zurückgibt.

hat mir da irgendjemand eine idee, woran es liegen könnte?

gruß und Danke
Matthias

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net