PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : invalid lvalue



Bonestruca
07.07.2005, 22:54
hallo,
immer wenn ich folgenden code compilieren will:



#include <io.h>
#include "..\lib\mydefs.h"
#include "..\lib\lcd.h"
#include "..\lib\stepper.h"
#include "..\lib\rc5.h"
#include "..\lib\uart.h"
#include "..\lib\sensor.h"

int main(void)
{

// ports auf empfang setzen

PB0 = 0x1F;
PB1 = 0x1F;
PB2 = 0x1F;
PB3 = 0x1F;
PB4 = 0x1F;


return 0;
}

komm die fehlermeldung:

"invalid lvalue in assignment" bei jeder port-zeile. wo liegt der
fehler ?

vielen dank für eure hilfe :)

linux_80
08.07.2005, 00:58
Wenn ich mich recht erinnere ist mit PB1 nur ein Bit gemeint, dann ist der
Wert von 0x1F ein bisserl zu gross dafür.
Also entweder nur einmal PORTB verwenden oder nur 0 und 1 für jedes Bit.

Bonestruca
08.07.2005, 08:14
habs auch schon mit 0xFF versucht und auch mal "PORTB" ausgeschrieben. hilft alles nix. :(

SprinterSB
08.07.2005, 09:12
Das mit PORTB sollte funktionieren.

Aus (zB)

PORTB |= _BV(3); // PORT B.3 setzen

sollte so was oder ähnliches entstehen entstehen, nachdem der Präprozessor drübergerauscht ist:

(*(volatile uint8_t *)((0x18) + 0x20)) |= (1 << (3));

Falls nicht, stimmt was mit deiner Umgebung oder den includes nicht.
Verbutlich wird das PORTB erst gar nicht aufgelöst.
avr-gcc sollte das #include <io.h> anmeckern, stattdessen:
#include <avr/io.h>

Johann

Bonestruca
08.07.2005, 09:20
gcc meckert nich bei den includes, findet sie anscheinend alle aber lvalue bekomme ich immer zurückgeschmettert :(

SprinterSB
08.07.2005, 09:32
Wie siegt's denn aus, wenn du zusätzlich mit Option -v übersetzt?

Bonestruca
08.07.2005, 09:45
hö ? da kommen dann die ganzen infos von den entwicklern wann und in welchem jahr und wer genau und so blabla.

SprinterSB
08.07.2005, 09:52
U.a. solltest du auch sehen, welche Suchpfade für die Includes verwendet werden, deine gcc-Version, und wie er configured wurde, etc. Derin Problem ist je kein eigentliches C-Problem, sondern mit deiner Umbegung finzt was nicht.

#include <avr/io.h>

void main()
{
PORTB = 0;
}

Wird bei mir problemlos übersetzt (avr-gcc 3.4.1 unter mingw)

>avr-gcc -v -mmcu=atmega8 -Wall -Os -ffreestanding main.c -c -o main.o -save-temps

...#include <io.h>...
Hingegen gibt eine deprecated (veraltet)-Warnung.
Das die bei dir nicht erscheint, gibt zu denken...

Bonestruca
08.07.2005, 09:59
gnu make version 3.78.1

pfade werden keine angzeigt :(

SprinterSB
08.07.2005, 10:05
Das -v als gcc-Schalter, nicht für make...

So wie in meinem letzten Posting. Verwende auch mal -save-temps, damit du ein dump vom Präprozessor erhälst (als *.i).
Das gibt bei solchen Problemen manchmal Hinweise wo der Wurm steckt. Weil du dann siehst, was der Compiler tatsächlich als Eingabe erhält, und nicht irgendwelche nichtssagenden Makros wie PORTB, hinter denen alles mögliche stecken kann.

linux_80
08.07.2005, 10:06
Ich glaub ihr sucht in die falsche Richtung,
normalerseise setzt/löscht man ein Bit doch u.a. so:


// löschen
PORTB &= ~(1 << PB3);
// setzen
PORTB |= (1 << PB3);

Felix G
08.07.2005, 10:20
stimmt...

in der io***.h steht nämlich das:

/* PORTB */
#define PB7 7
#define PB6 6
#define PB5 5
#define PB4 4
#define PB3 3
#define PB2 2
#define PB1 1
#define PB0 0

das heisst, daß der Präprozessor aus deinem "PB0 = 0x1F" das macht:

0 = 0x1F;

Du versuchst also einer Zahl einen anderen Wert zuzuweisen, was natürlich nicht funktionieren kann.
(und genau das besagt auch die Fehlermeldung... frei übersetzt: "dem Ding links vom = kann man nix zuweisen")


nimm die Variante von linux_80, so macht mans richtig.

SprinterSB
08.07.2005, 10:20
Klaro, aber daß bei
PORTB = / &= / |=
ein 'illegal lvalue in assignment' kommt, ist recht ungewöhnlich.

Bei PB3 = ... ist das klar, weil PB3 eine Konstante ist und auflöst zu
3 = ..., was ja auch Käse ist.

Richtig ist zB

PORTB |= _BV(PB3);

Übrigens empfiehlt es sich, die Port-Definitionen an einer _einzigen_ Stelle in der Quelle zu halten, damit man beim Ändern eines Ports (zB von PortB.0 auf PortD.2) wirklich nur 1(!) Stelle im Code ändern muss, was erforderlich ist, wenn man das Design ändet und man ein anderes Layout der I/O-Pins verwendet.

Tückisch wird es sonst, weil mindestens 3 Register zu einem Port(pin) gehören, typischer weise

- PORTx (Ausgang, Pullups)
- PINx (Eingang)
- DDRx (Richtung)

Felix G
08.07.2005, 10:24
PORTB = .... funktioniert natürlich...

er meinte aber nur daß er "PORTB auch mal ausgeschrieben" hat, was natürlich bedeuten könnte daß dann sowas wie

PORTB0 = 0xFF;
PORTB1 = 0xFF;
etc.

dabei rausgekommen ist.

lekro
08.07.2005, 13:46
Immer diese Crosspostings (http://www.mikrocontroller.net/forum/read-2-203662.html). :/

Auf solche simplen Fragen wirst du bestimmt in *einem* Forum mehr als genügend Antworten bekommen, es besteht also keine Notwendigkeit, in das Fettnäpfchen "Crossposting" zu treten.

Bonestruca
08.07.2005, 17:35
ich will bits weder löschen noch setzen. ich will den port b als eingang haben, also seine datenrichtung festlegen. wie um himmels willen mach ich das denn nun ?

Kjion
08.07.2005, 17:59
#include <avr/io.h>

...
DDRB = 0x00;
...

Das muss funktionieren, ansonsten ist irgendwas sehr grundlegendes falsch!

Vielleicht mal die neuste Version installieren/neuinstallieren ??

MfG Kjion

Bonestruca
09.07.2005, 14:51
ich hab jetzt komplett alles neu installiert und auf den neuesten stand gebracht. und siehe da: es funktioniert :) danke euch allen.