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
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;
}
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.