Styra pinnar individuellt på en port (AVR) ?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Fagge
Inlägg: 3930
Blev medlem: 27 maj 2003, 13:59:51
Ort: Blekinge

Styra pinnar individuellt på en port (AVR) ?

Inlägg av Fagge »

Att sätta eller nolla en enstaka pinne på en port är ju enkelt via kommandona SBI & CBI.
Men hur gör jag för att sätta t.e.x 4 pinnar samtidigt på en port, men dom andra 4a får inte röras då dessa är kopplade till en helt annan funktion?.

Måste man ORa värderna, eller finns det något enklare sätt?.
t.e.x
Ldi r16, 0bxx1111xx
Out Portd

Där då (x) lämnas orört.
Exemplet är ju bara ett önsketänkande, vilket givetvis inte fungerar…

Anledningen till detta, är att jag har skrivit ett program till en Mega16, men nu vill köra koden på en Attiny2313 då den har exakt antal i/o pinnar som jag behöver, vilket gör Mega16 överflödig till projektet. Men det förutsätter då att man kan på ett enkelt sätt kan dela portarna till flera funktioner.
Användarvisningsbild
Stinrew
Inlägg: 954
Blev medlem: 20 augusti 2006, 03:14:41
Ort: Motala
Kontakt:

Inlägg av Stinrew »

Då du programmerar i asm vet jag inte svaret, men i C skulle du gjort så här:

PORTD = PORTD | 0b00111100; //Sätter pinnarna 2,3,4,5

PORTD = PORTD & 0b11000011; //Släcker pinnarna 2,3,4,5

| är en 'bitvis-OR-operand', och
& är en 'bitvis-AND-operand'.
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg av thepirateboy »

Tror man måste ORa

PORTD = PORTD | 0b00111100;

genererar

Kod: Markera allt

in	r24, 0x12	
ori	r24, 0x3C	
out	0x12, r24	
där 0x12 är adressen till PORTD
Användarvisningsbild
Fagge
Inlägg: 3930
Blev medlem: 27 maj 2003, 13:59:51
Ort: Blekinge

Inlägg av Fagge »

Okidoki.
Dock så funkar inte OR funktionen riktigt i alla lägen.
Om en bit redan är satt till 1 men ska bli 0, då kommer biten att fortsatt vara1. Det löstes dock med att rotera 1snäpp fram & tillbaka för att nolla den biten innan OR funktionen kördes. I detta fallet funkade det fint då just den biten låg i ytterkant på porten.
eqlazer
Inlägg: 923
Blev medlem: 22 september 2007, 13:53:45
Ort: Göteborg

Inlägg av eqlazer »

För att nollställa en bit:
PORTD &= ~(1<<PD0);

Alltså invertera motsvarande värde som används vid ett-ställning, sedan kör bitvis and. Ungefär som Stinrew skrev tidigare.
Hur detta blir i asm fixas lätt av den händige.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Inlägg av Swech »

man kör and+or

Kod: Markera allt

.def  b8_pin1 = 0b00000001
.def  b8_pin2 = 0b00000100
.def  b8_pin3 = 0b00100000
.def  b8_pin4 = 0b00001000


ldi     R17,b8_pin2+b8_pin3   ;activate  pin2+pin3
In      R16,porta                    ;read old Port A
andi    R16,255-(b8_pin1+b8_pin2+b8_pin3+b8_pin4)  ;clear pin1..4
or     R16,r17                       ;set pins in R17 (Pin2+pin3)
out   porta,r16                     ;write porta 

Observera att i exemplet är pinnarna inte i ordningsföljd.
men skriver man så här behöver man endast ändra .def raden då
man byter fysisk pinne på processorn....

Swech
Skriv svar