Hallo Leute, hätte mal eine Frage zur flexiblen Portzuweisung. Ich benutze das AtmelStudio 6 (C++) und einen AVR. Ich habe ein Programm, das über USART ein paar Benutzereingaben empfangen kann. Nun möchte ich je nach Benutzereingabe unterschiedliche Ports in meinem Programm nutzen. z.B.: if (Benutzereingabe == 1) { USED_PORT = PORTB; USED_PIN = PINB; iPIN = 1; } else { USED_PORT = PORTD; USED_PIN = PIND; iPIN = 0; } //etwas Code.... if(USED_PIN & (1 << iPIN)) { USED_PORT |= (1 << iPIN); } /*******************************/ Mit den Präprozessoranweisungen wie #define komme ich da leider nicht weiter, da ich ja die Benutzereingabe verwenden möchte, um mich auf einen Port festzulegen. Ich weiß, ist ne Anfängerfrage aber ich bin für jede Hilfe dankbar und lese auch gerne selber nach, wenn Ihr einen Link kennt, der mein Problem erklärt. Viele Grüße, Steve-o
Naja, man kann auch die Ports direkt zuweisen, ohne ueber variablen zu gehen. DDRB=0x00; usw.
Hey, switch -- case würde ich benutzen aber ich möchte die Ports auch in Interrupt-Routinen über die Variable USED_PORT aufrufen Hat noch jemand ne Idee? Danke für die Hilfe.
portb usw. ist doch eigendlich auch nur ne adresse irgendwohin, thema pointer
1 | volatile uint8_t * PortToUse; |
2 | volatile uint8_t * PinToUse; |
3 | uint8_t iPin; |
4 | |
5 | |
6 | ...
|
7 | |
8 | if (Benutzereingabe == 1) |
9 | {
|
10 | PortToUse = &PORTB; |
11 | PinToUse = &PINB; |
12 | iPin= 1; |
13 | }
|
14 | else
|
15 | {
|
16 | PortToUse = &PORTD; |
17 | PinToUse = &PIND; |
18 | iPin= 0; |
19 | }
|
20 | |
21 | //etwas Code....
|
22 | |
23 | |
24 | if( *PinToUse & (1 << iPin)) |
25 | {
|
26 | *PortToUse |= (1 << iPin); |
27 | }
|
28 | |
29 | ...
|
Und Variablen-Namen in Grossbuchstaben gewöhnst du dir gleich wieder ab. Bezeichner, die ausschliesslich in Grossbuchstaben geschrieben sind, reservierst du einzig und alleine ausschliesslich für Makros.
>Und Variablen-Namen in Grossbuchstaben gewöhnst du dir gleich wieder ab.
Und variable Shifts am besten auch. Die kosten richtig Zeit;)
holger schrieb: >>Und Variablen-Namen in Grossbuchstaben gewöhnst du dir gleich wieder ab. > > Und variable Shifts am besten auch. Die kosten richtig Zeit;) Genau. Wobei: Wenn man so indirekt auf die Ports zugreift, wird das wahrscheinlich auch schon egal sein. :-) Denn genau genommen muss man da jetzt noch eventuell eine Interrupt-Sicherung einbauen Fazit: Es geht zwar, aber eigentlich will man das so nicht machen.
Hey Leute, erstmal vielen Dank für eure Hilfe! Wenn wir schon dabei sind, könntet ihr mir vielleicht erklären was ihr mit Variable Shifts meint? Kann nichts gebrauchen, was viel Zeit kostet! @kbuchegg: Was meinst du mit Interrupt-Sicherung? Ich mache die Zuweisung der Ports nur 1x am Anfang des Programms. Erst danach aktiviere ich die Interrupts und springe in die Endlosschleife. Fazit: Es geht zwar, aber eigentlich will man das so nicht machen... Ich kann mein Problem natürlich auch mit einem Flag und ner IF-Abfrage lösen. Wenn mein Weg unsicher ist und später zu Problemen im Programmablauf führt, gehe ich gerne einen anderen. Was genau ist der Grund, warum man das nicht so machen will? Viele Grüße, Steve-o
Steve-o Bane schrieb: > Hey Leute, > > erstmal vielen Dank für eure Hilfe! > > Wenn wir schon dabei sind, könntet ihr mir vielleicht erklären was ihr > mit Variable Shifts meint? Kann nichts gebrauchen, was viel Zeit kostet! 1 << variable das ist eine Operation, die man auf einem AVR nicht haben will, weil sie vom Compiler in Form einer Schleife umgesetzt werden muss (teuer) > @kbuchegg: > > Was meinst du mit Interrupt-Sicherung? Die Absicherung, dass während der Operation *PortToUse |= (1 << iPin); kein Interrupt auftreten darf, in dessen ISR selbst wieder am gleichen Port etwas geändert wird. > Ich mache die Zuweisung der Ports nur 1x am Anfang des Programms. > Erst danach aktiviere ich die Interrupts und springe in die > Endlosschleife. Darum gehts nicht. Es geht darum, dass diese Operation *PortToUse |= (1 << iPin); vom Compiler nicht in einem Zug (in einer einzigen Assembler Operation) umgesetzt werden kann, sondern in mehrere Instruktionen aufgelöst werden muss. Und dann kann dir das passieren: Du beginnst einen Satz in einem Buch zu schreiben Noch ehe du mit dem Satz fertig bist, wirst du unterbrochen. Während du dich um dieses andere kümmerst, kommt jemand und tauscht das Buch aus. Du kommst von der UNterbrechung zurück und schreibst den Satz (im jetzt anderen Buch) weiter, so als ob nichts gewesen wäre. Das da nur Unsinn dabei herauskommt, dürfte klar sein. > Was genau ist der Grund, warum man das nicht so machen will? Weil * die Shift-Operation teuer ist * man zusätzlichen Aufwand braucht um sich gegen Eventualitäten abzusichern, du nur deswegen entstehen, weil man möglichst allgemein sein möchte. Beschränkt man sich auf die Fälle, die man wirklich braucht, verschwinden diese Probleme ganz von alleine.
@kbuchegg: Vielen Dank für deine schnelle und genaue Antwort! Du hast mir sehr geholfen! Ich werde versuchen mein Problem anders zu lösen, ohne dabei Variable-Shifts & Co. zu verwenden! Grüße, Steve-o
Steve-o Bane schrieb: > Ich mache die Zuweisung der Ports nur 1x am Anfang des Programms. Dann brauchst Du keinen Portpin, sondern kannst die Leitung direkt auf VCC oder GND legen. Einen Portpin will man immer wieder in der Mainloop neu setzen und da sind die Interrupts ja aktiv. Der Zugriff muß also atomar erfolgen. Nur wenn der Pin zur Compilezeit feststeht, kann der Compiler die atomaren Befehle SBI/CBI nehmen. Peter
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.