Forum: Compiler & IDEs sda = (d >> 7); für GCC


von Gast (Gast)


Lesenswert?

Hallo,

ich versuche grade einen Beispielcode aus einem Datenblatt für meinen 
Mega8  umzuschreiben.
wie kann ich folgenden Codeschnipsel in eine GCC verständliche Form 
bringen?

sda = (d >> 7);

mfg und danke

Gast

von Benedikt K. (benedikt)


Lesenswert?

Dies sollte beim gcc so funktionieren.

von Gast (Gast)


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;
}

von Thomas (Gast)


Lesenswert?

sda ist keine Variable. Du kannst somit keinen Wert zuweisen.

von Peter D. (peda)


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.

von Volker (Gast)


Lesenswert?

Peter hats zwar schon vorweggenommen, aber schau auch mal hier:

Beitrag "sbit macro für avr-gcc"


Gruß Volker

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.