Sida 1 av 1

Styra pinnar individuellt på en port (AVR) ?

Postat: 15 mars 2008, 11:28:25
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.

Postat: 15 mars 2008, 11:40:49
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'.

Postat: 15 mars 2008, 12:03:32
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

Postat: 15 mars 2008, 14:32:59
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.

Postat: 15 mars 2008, 14:54:57
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.

Postat: 15 mars 2008, 18:40:13
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