Hallo uC-Fans,
kurz zu mir, da dies mein erster Beitrag ist. Ich bin 24 und studiere
Automatisierungssysteme in Berlin. Ich habe im kommenden Semester ein
großes Projekt vor mir und bin bereits in der Vorbereitung, weshalb ich
mich mit der Programmierung von uCs beschäftige.
Ich nutze eine AVR XMEGA-A1 X-PLAINED Board mit atxmega128a1. Dort gibt
es 8 Taster (PD0...PD5+PR0+PR1) und 8 LEDs (PE0...PE7).
In einem ersten kleien Programm will ich einfach nur erledigen, dass
jeder Taster eine entsprechende LED einschaltet, solange dieser gedrückt
wird. PD6 und PD7 sind laut Schaltplan nicht angeschlossen. Wie
interpretiert dies der uC?
Und wie kann ich die gelesenen Werte von PD0...PD5 mit denen von PR0+PR1
zu einem Ausgabewert für PE vereinen?
Mein bisheriger Ansatz funktioniert nur für PE0...PE6, PE7 ist
dauer-High.
wert = PORTD.IN; // Lese Port D, Bit 0...5 = Taster 0...5, sind "0",
wenn Taster gedrückt
if(!(PORTR.IN & 0x01)) // Wenn PR0 = 0 (SW6 gedrückt)
wert -= 0x40;
if(!(PORTR.IN & 0x02)) // Wenn PR1 = 0 (SW7 gedrück)
wert -= 0x80;
PORTE.OUT = wert; // Port E schreiben
Ich danke euch und hoffe auf eine schöne Zeit bei euch, werde wohl öfter
hier sein :)
Grüße
Philipp
Philipp Seckel schrieb:> Und wie kann ich die gelesenen Werte von PD0...PD5 mit denen von PR0+PR1> zu einem Ausgabewert für PE vereinen?
Mit Bitmanipulationen bist du schon auf einem guten Weg. Nur:
>> Mein bisheriger Ansatz funktioniert nur für PE0...PE6, PE7 ist> dauer-High.>> wert = PORTD.IN; // Lese Port D, Bit 0...5 = Taster 0...5, sind "0",> wenn Taster gedrückt>> if(!(PORTR.IN & 0x01)) // Wenn PR0 = 0 (SW6 gedrückt)> wert -= 0x40;
WEnn du ein Bit löschen willst
wert &= ~( 1 << bitnummer );
Wenn du ein Bit gezielt setzen willst
wert |= ( 1 << bitnummer );
Grundlage sind immer die Verknüpfungen eines kompletten Bytes mit
irgendwelchen 'Masken', die das gewünschte erledigen.
Und dann kann man natürlich noch ein Byte als ganzes ein paar Bits nach
links oder rechts schieben. Das sind die Operatoren << und >>
wert = wert << 1;
// schiebt alle Bits von 'wert' um 1 Stelle nach links
wert = wert >> 1;
// schiebt alle Bits von 'wert' um 1 Stelle nach rechts
du könntest zb PORTR als ganzes einlesen, danach mit Bitoperationen alle
anderen, dich nicht interessierenden Bits gezielt auf 0 setzen, das
Ergebnis davon dann so zurechtschieben, dass du es zum Ergebnis von
PORTD dazuodern kannst.
Hallo Philipp,
ich habe beim Umstieg auf den XMEGA und AVR32 vieles durch dieses
Tutorial gelernt.
http://kampis-elektroecke.de/?page_id=876
In Verbindung mit dem AVR-GCC-Tutorial hier, ist das eigentlich alles
was man ausser dem Datenblatt noch braucht.
Gruß
Philipp
Hallo,
erstmal Verzeihung, dass ich mich so lange nicht gemeldet habe. Beruf
und Studium verlangen derzeit viel Zeit.
Ich habe es jetzt über den folgenden Ansatz versucht (dabei hat mir auch
das Tutorial von Kampi ganz gut geholfen):
1
wert=PORTD.IN;// Lese Port D, Bit 0...5 = Taster 0...5, sind "0", wenn Taster gedrückt
2
3
wert|=(1<<6);// Bit6 in wert auf 1 setzen
4
wert|=(1<<7);// Bit7 in wert auf 1 setzen
5
6
if(!(PORTR.IN&0x01))// Wenn PR0 = 0 (SW6 gedrückt)
7
{wert&=~(1<<6);}// Setze Bit6 in wert = 0 (LED6 an)
8
9
if(!(PORTR.IN&0x02))// Wenn PR1 = 0 (SW7 gedrück)
10
{wert&=~(1<<7);}// Setze Bit7 in wert = 0 (LED7 an)
11
12
PORTE.OUT=wert;// Port E schreiben
E6 und E7 sind nun aber Dauer-Low, d.h. die LEDs leuchten immer. Das
Problem scheint in den if-Abfragen zu liegen. Denn wenn ich diese
auskommentiere, sind alle LEDs aus. Wenn ich auch noch die ersten
Zuweisungen für Bit6 und Bit7 lösche, sind LED6 und LED7 wiederum immer
an.
Hab ich da noch einen Knoten in meinen Gedanken?
Danke und viele Grüße
Philipp
Hallo Philipp,
bei LOW aktiven Tastern, die Entprellung nicht vergessen, würde ich
deinen Code abändern:
Philipp Seckel schrieb:> if(!(PORTR.IN & 0x01))
Wird dann, ich setzte noch mal Klammern, dass Du sichst was zusammen
gehört:
1
if((~PORTR.IN)&0x01){...}
Hier eine Entwicklung von Innen nach Außen, was so passiert:
Sei PORTR.IN gleich 0b11111110
~PORTR.IN ist 0b00000001
(~PORTR.IN & 0x01) die verUNDung mit 0x01 liefert 0b00000001, das ist
Wahr (true) !
Hallo Uwe,
deine Darlegung kann ich zwar nachvollziehen, aber das Ergebnis ist das
gleiche. Es müsste nur bei gedrücktem Taster die Bedingung erfüllt
werden. Scheinbar ist dem aber nicht so.
Uwe S. schrieb:> bei LOW aktiven Tastern, die Entprellung nicht vergessen
Unabhängig davon. Und hier unnötig. Das Flackern der LEDs wird er
verkraften ;-)
Philipp Seckel schrieb:> habe sie mit PORTR.PIN0CTRL = 0x18; eingeschaltet, hat aber keine Änderung
ergeben.
Ich kenne den Controller nicht. Mich wundert allerdings, daß die beiden
Ports 0 und 1 auf Bit 3 und 4 liegen - ist das korrekt?
Gruß
Jobst
Hallo Jobst,
nein, sie sollten auf Bit 0 und 1 liegen. Wie kommst du auf 3 und 4?
Wegen dem Pullup mit 0x18? (siehe dazu
http://www.atmel.com/Images/doc8077.pdf Seite 142)
Philipp Seckel schrieb:> Wegen dem Pullup mit 0x18?
Ja.
Da fehlen mir weitere Informationen. Wie gesagt, ich kenne das Ding
nicht. Es ist mir nur aufgefallen. Es zu überprüfen, überlasse ich Dir.
:-)
Was passiert, wenn Du PortR mal komplett und direkt auf PortE ausgibst?
Verhält es sich wie gewünscht?
Gruß
Jobst
Hallo,
hab ich mal ausprobiert.
Dann funktionieren mit den besagten Tastern an R0 und R1 die LEDs 0 und
1. Passt also. Bin aber leider immer noch nicht dahinter gestiegen, was
das Problem nun verursacht.