sda = (d >> 7); für GCC

Gast #627282
Lesenswert?

Hallo,

ich schreib mal noch ein bischen mehr von meinem Code.

#define sda PC4
#define scl PC5


void i2c_write(unsigned char d)
{
  unsigned char i;

  PORTC &= ~(1<<PC5);
  for ( i=1; i<=8; i++)
    {
      sda = (d >> 7);
      PORTC |= (1<<scl);
      d = d << 1;
      PORTC &= ~(1<<scl);
    }
  PORTC |= (1<<sda);
  PORTC &= ~(1<<scl);
  PORTC |= (1<<scl);
}

als Fehelermeldung bekomme ich "error: invalid lvalue in assignment" für 
die Zeile mit "sda = (d >> 7);"
Alles andere scheint zumindest beim Comilieren Fehlerfrei zu sein.
Der Beispielcode aus dem Datenblatt ist Folgender:

void I2C_write(uchar d)
{
uchar i;
scl = 0;
for (i = 1; i <= 8; i++)
{
sda = (d >> 7);
scl = 1;
d = d << 1; /* increase scl high time */
scl = 0;
}
sda = 1; /* Release the sda line */
scl = 0;
scl = 1;
if(sda) printf("Ack bit missing %02X
",(unsigned int)d);
scl = 0;
}
#627299
Lesenswert?

Beim AVR mußt Du für Eingänge und Ausgänge verschiedene Register nehmen 
(PINx, PORTx).
Open Drain Ausgänge realisiert man mit dem DDRx-Register

Um Bitvariablen zu definieren, muß man unter GCC Bitfelder benutzen, 
dann gehts ganz einfach wie unter Keil C51:
1
#include <avr\io.h>
2
#include <inttypes.h>
3
#include <stdio.h>
4

5

6
struct bits {
7
  uint8_t b0:1;
8
  uint8_t b1:1;
9
  uint8_t b2:1;
10
  uint8_t b3:1;
11
  uint8_t b4:1;
12
  uint8_t b5:1;
13
  uint8_t b6:1;
14
  uint8_t b7:1;
15
} __attribute__((__packed__));
16

17

18
#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
19

20

21
#define scl     SBIT(PORTC, 5)
22
#define sda     SBIT(DDRC, 4)
23
#define sdain   SBIT(PINC, 4)
24
#define sdalevel SBIT(PORTC, 4)
25

26
#define uchar unsigned char
27

28

29
void I2C_write(uchar d)
30
{
31
uchar i;
32
sdalevel = 0;
33
scl = 0;
34
for (i = 1; i <= 8; i++)
35
{
36
sda = !(d >> 7);
37
scl = 1;
38
d = d << 1; /* increase scl high time */
39
scl = 0;
40
}
41
sda = 0; /* Release the sda line */
42
scl = 0;
43
scl = 1;
44
if(sdain) printf("Ack bit missing %02X",(unsigned int)d);
45
scl = 0;
46
}


Peter


P.S.:
1
d = d << 1; /* increase scl high time */
Dürfte beim AVR nicht reichen.
Außerdem verschiebt der AVR-GCC solche Intruktionen, da sie seiner 
Meinung nach keinen Einfluß auf die Ausführung haben.
IO-Zugriffe stellen leider keine Barrieren für Reordering dar.

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