Forum: Mikrocontroller und Digitale Elektronik Bits beim Port setzen/löschen


von Michael H. (Gast)


Lesenswert?

Moin

Ich möchte auf meinem STK500 auf Port-C alle Bits auf einen bestimmten 
Status setzen, also entweder high oder low.

Bei dem Beispiel soll zuerst
PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7
 1   0   0   1   1   0   0   1

und nach einer Sekunde:
PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7
 1   0   1   0   1   0   1   0

und so weiter. Irgendwie haut das aber nicht hin so wie ich es versucht 
habe:

     PORTC |= (1<<0);
     PORTC &= ~(2<<0);
     PORTC &= ~(4<<0);
     PORTC |= (8<<0);
     PORTC |= (16<<0);
     PORTC &= ~(32<<0);
     PORTC &= ~(64<<0);
     PORTC |= (128<<0);
     _delay_ms(1000);
     PORTC |= (1<<0);
     PORTC &= ~(2<<0);
     PORTC |= (4<<0);
     PORTC &= ~(8<<0);
     PORTC |= (16<<0);
     PORTC &= ~(32<<0);
     PORTC |= (64<<0);
     PORTC &= ~(128<<0);
     _delay_ms(1000);

Wie kann ich das umsetzen, so daß bestimmt Ports gesetzt sind und andere 
gelöscht, ohne unsichere Zustände zu haben?

Gruß
Michael

von Johannes M. (johnny-m)


Lesenswert?


von M.Heuer (Gast)


Lesenswert?

Würde das so funktionieren? (Ich habe mein STK500 im Moment nicht am 
Mann)

>Bei dem Beispiel soll zuerst
>PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7
> 1   0   0   1   1   0   0   1
>
>und nach einer Sekunde:
>PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7
> 1   0   1   0   1   0   1   0


PORTC |= ((1 << PC0) | (1 << PC3) | (1 << PC4) | (1 << PC7));
PORTC &= ~((1 << PC1) | (1 << PC2) | (1 << PC5) | (1 << PC6));
_delay_ms(1000);

PORTC |= ((1 << PC0) | (1 << PC2) | (1 << PC4) | (1 << PC6));
PORTC &= ~((1 << PC1) | (1 << PC3) | (1 << PC5) | (1 << PC7));
_delay_ms(1000);



gruß
Michael

von Johannes M. (johnny-m)


Lesenswert?

Wenn Du eh jeweils alle Bits im Register manipulieren willst, dann 
kannste Dir den Kram mit den UND und ODER sparen und einfach das 
Bitmuster reinschreiben!
1
PORTC |= ((1 << PC0) | (1 << PC3) | (1 << PC4) | (1 << PC7));
2
PORTC &= ~((1 << PC1) | (1 << PC2) | (1 << PC5) | (1 << PC6));
3
//...ist identisch mit
4
PORTC = 0x99;
5
6
//und
7
PORTC |= ((1 << PC0) | (1 << PC2) | (1 << PC4) | (1 << PC6));
8
PORTC &= ~((1 << PC1) | (1 << PC3) | (1 << PC5) | (1 << PC7));
9
//...mit
10
PORTC = 0x77;
Die bitweisen logischen Verknüpfungen werden nur benötigt, wenn nicht 
alle Bits verändert werden sollen.

Übrigens schreibt man Zahlen i.d.R. mit der höchstwertigen Stelle links 
und der niedrigstwertigen rechts. Oder schreibst Du 
tausendzweihundertvierunddreißig als 4321?

von Stefan E. (sternst)


Lesenswert?

Johannes M. wrote:

> PORTC = 0x77;

Ähm, doch wohl eher 0x55.

von Johannes M. (johnny-m)


Lesenswert?

Stefan Ernst wrote:
> Johannes M. wrote:
>
>> PORTC = 0x77;
>
> Ähm, doch wohl eher 0x55.
Jüpp, hast recht. Seine "arabische Schreibweise" hat mich doch ein 
bisschen verwirrt...

von Michael H. (Gast)


Lesenswert?

Danke und Salamaleikum :)

Gruß
Michael

von M.Heuer (Gast)


Lesenswert?

Irgendwie will er nicht wie er soll. Ich dachte ich hätte die Sache mit 
der Zuweisung als Hexzahl verstanden, aber die LEDs am STK500 richten 
sich nicht danach:

"soll" ist der als Hex übergebene Wert, "ist" ist der wie ihn die LEDs 
anzeigen:

                PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0  HEX
1.Schritt soll   1   0   0   1   1   0   0   1   0x99
          ist    0   1   0   0   0   0   1   0   0x42

2.Schritt soll   0   1   0   1   0   1   0   1   0x55
          ist    1   0   0   0   0   0   1   0   0x82

3.Schritt soll   0   1   1   0   0   1   1   0   0x66
          ist    1   0   0   0   0   0   0   1   0x81

4.Schritt soll   1   0   1   0   1   0   1   0   0xaa
          ist    0   1   0   0   0   0   0   1   0x41

Ich habe das Programm mal auf das wesentliche eingedampft:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#define F_CPU 3686400
4
5
int main(void){
6
 DDRC  = 0xff;  //alle auf Ausgang stellen
7
8
 while(1){            //        PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
9
     PORTC = 0x99;    //  soll   1   0   0   1   1   0   0   1
10
                      //  ist    0   1   0   0   0   0   1   0
11
     _delay_ms(1000);
12
     PORTC = 0x55;    //  soll   0   1   0   1   0   1   0   1
13
                      //  ist    1   0   0   0   0   0   1   0
14
     _delay_ms(1000);
15
     PORTC = 0x66;    //  soll   0   1   1   0   0   1   1   0
16
                      //  ist    1   0   0   0   0   0   0   1
17
     _delay_ms(1000);
18
     PORTC = 0xaa;    //  soll   1   0   1   0   1   0   1   0
19
                      //  ist    0   1   0   0   0   0   0   1
20
     _delay_ms(1000);
21
 }
22
}

Ich sehe einfach nicht wo da der Wurm drin ist.

von STK500-Besitzer (Gast)


Lesenswert?

1. Welchen Controller benutzt du? (hat der vielleicht ein 
JTAG-Interface?)
2. Die LEDs am STK500 funktionieren invertiert, was soviel heisst, dass 
sie leuchten, wenn man eine 0 an den Port schreibt.

von Stefan E. (sternst)


Lesenswert?

M.Heuer wrote:
> (soll/ist Tabelle)

PC2-5 sind immer 0
-> JTAG ist aktiviert

Rest ist invertiert
-> die LEDs sind gegen VCC angeschlossen und werden daher von dir falsch 
interpretiert (leuchten bei 0)

von M.Heuer (Gast)


Lesenswert?

Hallo STK500-Besitzer und Stefan

Das wars wohl gewesen.
Ich habe das JTAG mit den Zeilen aus dem Tutorial deaktiviert...
1
   MCUCSR |= (1<<JTD);
2
   MCUCSR |= (1<<JTD);
...allerdings weis ich nicht so recht was ich da eigentlich gemacht 
habe. Ich werde mir das noch mal genauer im Tutorial zu Gemüte führen 
müssen.

Danke und Gruß
Michael

von Di P. (drpepper) Benutzerseite


Lesenswert?

1
PORTC = 0x99;    //  soll   1   0   0   1   1   0   0   1
kann man auch als
1
PORTC = 0b10011001;    //  soll   1   0   0   1   1   0   0   1
schreiben. Das ist für Bitmuster vielleicht eingängiger.

von Timmo H. (masterfx)


Lesenswert?

>PORTC = 0b10011001;    //  soll   1   0   0   1   1   0   0   1
>schreiben. Das ist für Bitmuster vielleicht eingängiger.
aber nicht standardconform

von Teplotaxl X. (t3plot4x1)


Lesenswert?

>>  _delay_ms(1000);

Das ist so nicht machbar; guck mal im AVR-GCC-Tutorial unter delays 
nach.

von Stefan E. (sternst)


Lesenswert?

Sir alan Teplotaxl wrote:
>>>  _delay_ms(1000);
>
> Das ist so nicht machbar; guck mal im AVR-GCC-Tutorial unter delays
> nach.

Hängt davon ab, welche Version der avr-libc er benutzt.

von M.Heuer (Gast)


Lesenswert?

@Sir alan Teplotaxl
>>>  _delay_ms(1000);
>Das ist so nicht machbar; guck mal im AVR-GCC-Tutorial unter delays
>nach.
Ist nur dafür das ich sehen kann was an den LED's passiert. Wird jetzt, 
wo tatsächlich passiert was passieren soll, runtergesetzt :-)


@Stefan Ernst
>>>>  _delay_ms(1000);
>>
>> Das ist so nicht machbar; guck mal im AVR-GCC-Tutorial unter delays
>> nach.
>
>Hängt davon ab, welche Version der avr-libc er benutzt.

Laut Synaptic ist es Version 1.4.7-1 (Ich benutzer hier Ubuntu (Hardy), 
avrdude 5.5.1, gcc-avr 4.2.2-1)

Gruß
Michael

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
Noch kein Account? Hier anmelden.