Hallo zusammen,
ich habe einen ATMega16 und an PORTA 8 LEDs angeklemmt,
die ich jetzt einzeln ein/aus schalten möchte. Dafür haeb ich mir eine
Funktion geschrieben, welche ich wie folgt aufrufe:
unique(LEDNr, Status);
also z.B. so:
unique(3,1); //Schaltet LED3 (PORTA2) ein
aber irgendwie funktioniert das noch nicht richtig, habe die funktion
erstmal soweit bis zum EINSCHALTEN programmiert, um das Ausschalten
kümmere ich mich danach.
hier die Funktion:
1
unique(intLEDNr,intStatus)
2
{
3
intLED=LEDNr-1;
4
charpraefix[3];
5
6
praefix[0]='P';
7
8
if((LED>=0)&&(LED<=7))
9
{
10
praefix[1]='A';
11
praefix[2]=LED;
12
}
13
14
if(Status==1)
15
{
16
PORTA|=(1<<praefix);// hier wird Fehler angezeigt (siehe unten)
17
}
18
}
Der Fehler: main.c:1265: error: invalid operands to binary <<
ich hoffe mir kann jemand weiterhelfen, ich denke ich weiß auch woran
das liegt, nämlich an der char variable, oder ??
vielen dank
:)
ja genauso hatte ich das vor, das funktioniert super und ist viel
kompakter als meine Idee....
vielen dank simon !!
Jetzt muss ich bloß noch hingehen nund was programmieren, das ich auch
PORTC und PORTD damit ansprechen kann...
Habe eine LED-Leiste mit 24 LEDs und Treiberbaustein, die ich gerne
einzeln ansteuern würde....
Also dirty geht es, halt nur einzenl über Funktionsaufruf war noch ein
Featue, was ich brauchte :)
VIELEN DANK !! echt super geil !!
Dominique wrote:
> :)> ja genauso hatte ich das vor, das funktioniert super und ist viel> kompakter als meine Idee....> vielen dank simon !!>> Jetzt muss ich bloß noch hingehen nund was programmieren, das ich auch> PORTC und PORTD damit ansprechen kann...> Habe eine LED-Leiste mit 24 LEDs und Treiberbaustein, die ich gerne> einzeln ansteuern würde....> Also dirty geht es, halt nur einzenl über Funktionsaufruf war noch ein> Featue, was ich brauchte :)>>> VIELEN DANK !! echt super geil !!
Übrigens: Das Ausschalten funktioniert mit obiger Funktion nicht. Nur
das einmalige Anschalten. Wenn du die LED auch ausschalten möchtest
(über den Status Parameter) dann musst du die Funktion etwas erweitern:
Alo gut, für PORTA und PORTC habe ich es am laufen, leider jedoch
funktioniert die funktion nicht bei PORTD :(
hier mal die beiden Auszüge für A und D aus der Funktion unique();
=============================
if((LED >= 0) && (LED <= 7))
{
if(Status == 1)
{
PORTA |= (1 << (LEDNr-1));
}
else if(Status == 0)
{
PORTA &= (0 << (LEDNr-1));
}
}
=============================
if((LED >= 16) && (LED <= 23))
{
if(Status == 1)
{
PORTD |= (1 << (LEDNr-1));
}
else if(Status == 0)
{
PORTD &= (0 << (LEDNr-1));
}
}
=============================
Ich verstehe nicht ganz, wiedo das mit PORTD nicht geht :(
kann das an irgendwelchen Fuses liegen ??
Das Ausschalten funktioniert in keiner der Varianten korrekt:
PORTA &= (0 << (LEDNr-1));
Woran liegt das Problem?
0 << 1 ist 0, genauso wie 0 << 7 immernoch 0 ist.
PORTA &= 0 setzt den GESAMTEN PortA auf 0, schaltet also alle LEDs aus.
Simon hat bereits den richtigen Weg vorgeschlagen:
PORTA &= ~(1 << (LEDNr-1));
Doch doch, Ausschalten geht auch mit meiner Variante, zumindest bei
PortA und PORTC
bei PORTD geht garnichts mit dieser Variante, nichtmal einschalten :(
Dominique wrote:
> Doch doch, Ausschalten geht auch mit meiner Variante, zumindest bei> PortA und PORTC
Klar, wenn man das ganze Portregister Null schreibt, dann geht alles
aus. Nur ist das, was Rufus schreibt, spätestens dann relevant, wenn an
dem Port auch noch Sachen dranhängen, die nicht mit ausgehen sollen.
> bei PORTD geht garnichts mit dieser Variante, nichtmal einschalten :(
Das Problem mit Port D kann eigentlich nur in Deiner Initialisierung
liegen, die Du geheimhältst... oder ein Hardware-Fehler.
Ja, aber wie Rufus bereits gesagt hatte: Du schaltet DEN GANZEN Port
damit ab, und nicht einzelne LEDS.
Wenn natürlich nur eine an war, merkst du das nicht.
Wenn der PortD nicht geht, dann solltest du mal nach dem DDRD Register
sehen, oder alternative Funktionen verwendet?
An Fuses liegt sowas nicht...
Dominique wrote:
> if((LED >= 16) && (LED <= 23))> {> if(Status == 1)> {> PORTD |= (1 << (LEDNr-1));> }> else if(Status == 0)> {> PORTD &= (0 << (LEDNr-1));> }> }> =============================>>> Ich verstehe nicht ganz, wiedo das mit PORTD nicht geht :(> kann das an irgendwelchen Fuses liegen ??
Überlag mal wie gross den LEDNr ist, wenn dieser if Zweig
betreten wird.
Und dann denk mal drüber nach, was mit einer 1 passiert, wenn
man sie derartig oft nach links schiebt.
ja stimmt schon, das ich den ganzen port ausschalte, habe das jetzt
alles geändert, aber es geht immer noch nicht:
Aber PORTD ist alles richtig initialisier, denn über meine anderen
Funktionen kann ich den prima ansprechen, auch direkt aus der while
schleife, alles kein problem, nur halt der aufruf aus dieser funktion
heraus will nicht
=============================
if((LED >= 0) && (LED <= 7))
{
if(Status == 1)
{
PORTA |= (1 << (LEDNr-1));
}
else if(Status == 0)
{
PORTA &= ~(1 << (LEDNr-1));
}
}
=============================
if((LED >= 16) && (LED <= 23))
{
if(Status == 1)
{
PORTD |= (1 << (LEDNr-1));
}
else if(Status == 0)
{
PORTD &= ~(1 << (LEDNr-1));
}
}
=============================
@Dominique
Du bist im Moment drauf und drann, dich regelmässig mit
übermässig kompliziertem Code selbst auszutricksen.
zb. Entweder du benutzt eine Variable LED, die grundsätzlich
um 1 kleiner ist als das übergebene Argument LedNr. Dann
benutzte aber bitte diese Variable quer durch deine Funktion.
Oder aber du schriebst überall in deiner Funktion LedNr-1.
Aber bitte dann auch konsequent
Oder aber du gehst den besten Weg von allen und akzeptierst
ganz einfach dass in C nun mal bei 0 angefangen wird zu
zählen. Gewöhn dich daran, das spart dir im Laufe der Zeit
viel Kopfzerbrechen: Das erste Element (egal wovon) ist
das mit der Ordnungszahl 0
@Dominique
Ach ja, hab ich vergessen:
Ein konsistentes Einrückschema ist kein Luxus, sondern ein
Instrument um Fehler leichter sehen zu können. Also benutz
das auch.
Ich weiss: Neulinge sagen immer "Das mach ich später".
Nur: Ich hab schon erlebt, dass Neulinge stundenlang nach
Fehlern gesucht und nicht gefunden haben. Dann hab ich
als erstes mal den Code korrekt eingerückt und in 30 Sekunden
haben sie dann selbst das Problem gesehen.
PS: Hast du meine Anmerkung weiter oben gesehen?
Wenn nicht, hier ist sie nochmal:
> if((LED >= 16) && (LED <= 23))> {> if(Status == 1)> {> PORTD |= (1 << (LEDNr-1));> }> else if(Status == 0)> {> PORTD &= (0 << (LEDNr-1));> }> }> =============================>>> Ich verstehe nicht ganz, wiedo das mit PORTD nicht geht :(> kann das an irgendwelchen Fuses liegen ??
Überlag mal wie gross den LEDNr ist, wenn dieser if Zweig
betreten wird.
Und dann denk mal drüber nach, was mit einer 1 passiert, wenn
man sie derartig oft nach links schiebt und nur 8 Bit zur Verfügung
hat.
Schau dir mal folgenden Thread an, hier wird eine Möglichkeit der
direkten Zuweisung von PIN's innerhalb eines Ports erklärt.
Beitrag "sbit macro für avr-gcc"
Bei 8x51 Typen ist das kein Problem und für die AVR's gibts eben den
genannten Workarround. Damit sollte es übersichtlicher und korrekt
werden.