Maskinvare XOR for utgangspinner på AVR-mikrokontrollere
Visste du at mange AVR-sjetonger har en type maskinvare eksklusiv eller (XOR) -alternativ når det gjelder logikknivået på utgangspinnene? Hvis du ser i databladet (bildet ovenfor er et skjermbilde fra et ATTINY13-datablad) finner du en del ved å bytte PIN-koden. Det viser seg at hvis du angir en port som en utgang, vil skrive logikk en til det tilhørende PIN-registeret bytte logikknivåene til det ut. Dette er veldig enkelt å forsømme hvis du skriver i C, men jeg har jobbet med å lære litt assemblers språk og fant dette å være veldig nyttig. Fortsett å lese etter pause, og jeg vil fortelle deg hvordan jeg skjedde på denne informasjonen og hva det er bra for.
Så først, la oss snakke om hvorfor dette ikke betyr noe veldig mye om du skriver i C-kode. Vanligvis hvis du vil bytte noen utgangspinner, skriver du bare en en-liner som xor er med en bitmask:
1
Portb ^ = 0xff;
Dette er litt av C Shorthand (Lær mye mer om det fra min opplæringsserie) som utfører XOR på de nåværende utgangsnivåene og skriver resultatet tilbake til porten. Men det samme kan gjøres i maskinvare ved å skrive bitmasken til PINB-registeret:
1
Pinb = 0xff;
Du bryr deg ikke, fordi det bare er en linje med kode. Faktisk er det sannsynligvis enklere å xor portben fordi det gir mye mer mening konseptuelt. Men kompilatoren kan ende opp med å bruke mye flere sykluser enn hvis du hadde skrevet til PIN-registeret.
Jeg skjedde over denne funksjonen fordi jeg blinket noen lysdioder som en måte å lære assembler på. Jeg hadde denne jumben av kode i en avbruddsservice rutine:
1
2.
3.
4.
ldi myreg, 0xff
i Intreg, Portb
Eor Intreg, Myreg
ut portb, intreg
Den laster en bitmask i ett register, laster i den nåværende logikken fra Portb til et annet register, utfører en XOR av de to, og skriver resultatet tilbake til Portb. Dette tar fire sykluser og krever to registre. Toggling biter er en slik rudimentær operasjon jeg ble overrasket at det ikke var en kommando til xor biter direkte så jeg begynte å søke rundt. Jeg kom over denne korte artikkelen over på AVR Freaks som kledde meg inn i bitbryteren. Nå var jeg i stand til å redusere montørkoden min som følger:
1
2.
LDI Intreg2, 0xFF; Temporarity Bruk Intreg2 som litt maske
ut pinb, intreg2; skriving til pinb effektivley gjør en eksklusiv eller på portb
Dette resulterer i samme byttende effekt, men tar bare to sykluser og krever bruk av bare ett register.
Det jeg fant mange interessante er at uansett hvor mye jeg bruker AVR-chips, det er aldri en mangel på overraskelser som venter på å bli funnet i databladet.