5.10. C-Kielen Perusteet Maskaus

5
1 5.10. C-kielen perusteet. Maskaus. 8.1.2008, pva ”En ole täydellinen idiootti. Joitakin osia vielä puuttuu”. - Mr Benny Mable Yleistä Sulautetuissa järjestelmissä on varsin tavallista se, että ohjelmalla halutaan käsitellä vain yhtä yksittäistä bittiä. Vain tietty bitti pitää asettaa ykköseksi tai resetoida nollaksi, mutta muihin rekisterin/portin bitteihin ei saa samalla kertaa koskea. Tai kun olemme kiinnostuneet vain portin yhden bitin tilasta, onko se ykkönen, vai nolla. Silloin tarvitaan bittioperaatioita, jonka erityistoiminne on maskaus, maskin käyttö. Käytännön esimerkkejä milloin tarvitaan maskausta Lähtöporttiin on kytketty FET, jolla ohjataan vesipumpun sähkömoottoria. Luetaan tuloportista, onko tietty ovikytkin asennossa ON tai EI. Kerrotaan AD-muuntimelle, että nyt on aika aloittaa muunnosprosessi. Kun pitää asettaa sarjaportin lähetyskeskeytys päälle tai pois päältä. Asetetaan ajastimen ohjausrekisterin jokin tietty bitti ’päälle’ tutkitaan onko lippurekisterin bitti asetettu - jne Tämän dokumentin sisardokumentti on Bittioperaatiot. Tutki samalla sitä. Bittioperaatiot ovat tehokkaita, koske ne eivät käytä matemaattisia laskutoimituksia, vaan operoivat bittikuvioita suoraan. Maskaus Maski on bittikuvio, johon on asetettu ne bitit, joita halutaan käsitellä. Maskin avulla yksittäisten bittien käsittely on mahdollista muuttamatta rekisterin muiden bittien tilaa. Kun maskin ja rekisterin bittien välillä tehdään sopiva looginen operaatio, saadaan maskiin merkityt bitit nollatuiksi tai asetetuiksi Maski voidaan ajatella olevan ikäänkuin sihti (siivilä, verkko) joka päästää vain tietyt rekisterin (portin) bitit käsittelyyn. Tuo käsittely voi olla: Bitin tilan tutkiminen Bitin asetus ykköseksi Bitin nollaus Bitin tilan vaihto

Transcript of 5.10. C-Kielen Perusteet Maskaus

Page 1: 5.10. C-Kielen Perusteet Maskaus

1

5.10. C-kielen perusteet. Maskaus. 8.1.2008, pva ”En ole täydellinen idiootti. Joitakin osia vielä puuttuu”. - Mr Benny Mable Yleistä Sulautetuissa järjestelmissä on varsin tavallista se, että ohjelmalla halutaan käsitellä vain yhtä yksittäistä bittiä. Vain tietty bitti pitää asettaa ykköseksi tai resetoida nollaksi, mutta muihin rekisterin/portin bitteihin ei saa samalla kertaa koskea. Tai kun olemme kiinnostuneet vain portin yhden bitin tilasta, onko se ykkönen, vai nolla. Silloin tarvitaan bittioperaatioita, jonka erityistoiminne on maskaus, maskin käyttö. Käytännön esimerkkejä milloin tarvitaan maskausta

• Lähtöporttiin on kytketty FET, jolla ohjataan vesipumpun sähkömoottoria. • Luetaan tuloportista, onko tietty ovikytkin asennossa ON tai EI. • Kerrotaan AD-muuntimelle, että nyt on aika aloittaa muunnosprosessi. • Kun pitää asettaa sarjaportin lähetyskeskeytys päälle tai pois päältä. • Asetetaan ajastimen ohjausrekisterin jokin tietty bitti ’päälle’ • tutkitaan onko lippurekisterin bitti asetettu - jne

Tämän dokumentin sisardokumentti on Bittioperaatiot. Tutki samalla sitä. Bittioperaatiot ovat tehokkaita, koske ne eivät käytä matemaattisia laskutoimituksia, vaan operoivat bittikuvioita suoraan. Maskaus Maski on bittikuvio, johon on asetettu ne bitit, joita halutaan käsitellä. Maskin avulla yksittäisten bittien käsittely on mahdollista muuttamatta rekisterin muiden bittien tilaa. Kun maskin ja rekisterin bittien välillä tehdään sopiva looginen operaatio, saadaan maskiin merkityt bitit nollatuiksi tai asetetuiksi Maski voidaan ajatella olevan ikäänkuin sihti (siivilä, verkko) joka päästää vain tietyt rekisterin (portin) bitit käsittelyyn. Tuo käsittely voi olla: Bitin tilan tutkiminen Bitin asetus ykköseksi Bitin nollaus Bitin tilan vaihto

Page 2: 5.10. C-Kielen Perusteet Maskaus

2

Maski on vakio tai muuttuja, jolla erotetaan halutut bitit toisesta muuttujasta.

Bitin tilan tutkiminen Tutkitaan onko jokin rekisterin (muuttujan tietty bitti asetettu vai ei). Muodostetaan maski jossa tutkittavassa bittipaikassa on ykkönen ja muissa nolla. Sitten käytetään AND-operaatiota ja yhdistetään maski ja tutkittava tavu. Jos tutkittava bitti on asetettu, niin tulos on nollasta poikkeava, siis tosi-true. Jos tutkittava bitti ei ole asetettu (siis se on nolla), niin tulos on nolla, epätosi-false. Esim. Tutkitaan onko portin 2-bitti asetettu ykköseksi. /************************************************** ******** Project : maski_1.c Hardware: PV-M32-MOOkit + PV-EMO + PV-LEDIT B-porti ssa Software: WinAVR-20071221 Date : 07.01.2008 Author : pva Comments: PB2-LED loistaa, kun PD2 on ykkönen paina S2=D-portin 2-bitti nollaksi, LED sammuu *************************************************** *******/ #include <avr/io.h> #define MASKI 1<<2 // 0000 0100 int main(void) { DDRB = 0xFF; // suunta ulos DDRD = 0x00; // suunta sisään PORTD = 0xFF; // pinnit ylös uint8_t tutki = 0; while(1) { tutki = MASKI & PIND; // AND-operaatio PORTB = tutki; } }

Analyysi PIND 1111 1111 MASKI 0000 0100 ----------------------------- & AND tutki 0000 0100 tosi-true

Page 3: 5.10. C-Kielen Perusteet Maskaus

3

Bitin asetus ykköseksi Perusperiaate Bitin asetus ykköseksi tulee tapahtua niin, että muiden rekisterissä olevien bittien tila ei muutu. Niihin ei kosketa. Bitti asetetaan ykköseksi siitä riippumatta onko sen tila ennestään ykkönen tai nolla. Bitti asetetaan OR-operaatiolla. Maski on tällöin luku, jossa asetettava bitti on ykkönen ja muut nollia.

Esim. Asetetaan portin 7-bitti ykköseksi, muihin ei kosketa. /************************************************** ******** Project : maski_2.c Hardware: PV-M32-MOOkit + PV-EMO + PV-LEDIT B-porti ssa Software: WinAVR-20071221 Date : 07.01.2008 Author : pva Comments: halutaan asettaa B-portin 7-bitti muihin ei kosketa *************************************************** *******/ #include <avr/io.h> #define MASKI 1<<7 // 1000 0000 int main(void) { DDRB = 0xFF; // suunta ulos PORTB = 0x0F; // 0000 1111 while(1) { PORTB = MASKI | PORTB; // OR-operaatio } }

Analyysi PORTB 0000 1111 MASKI 1000 0000 ----------------------------- | OR PORTB 1000 1111 tosi-true

Bitin nollaus Perusperiaate Bitin nollaus tulee tapahtua niin, että muiden rekisterissä olevien bittien tila ei muutu. Niihin ei kosketa. Bitti nollataan siitä riippumatta onko sen tila ennestään ykkönen tai nolla. Bitti nollataan AND-operaatiolla. Maski on tällöin luku, jossa nollattava bitti on nolla ja muut bitit ovat ykkösiä.

Page 4: 5.10. C-Kielen Perusteet Maskaus

4

Esim. Nollataan portin 6-bitti, muihin ei kosketa. /************************************************** ******** Project : maski_3.c Hardware: PV-M32-MOOkit + PV-EMO + PV-LEDIT B-porti ssa Software: WinAVR-20071221 Date : 07.01.2008 Author : pva Comments: nollataan B-portin 6-bitti muihin ei kosketa *************************************************** *******/ #include <avr/io.h> #define MASKI ~(1<<6) // 1011 1111 int main(void) { DDRB = 0xFF; // suunta ulos PORTB = 0xFF; // 1111 1111 while(1) { PORTB = MASKI & PORTB; // AND-operaatio } }

Analyysi PORTB 1111 1111 MASKI 1011 1111 ----------------------------- & AND PORTB 1011 1111 tosi-true Tässä on käytetty ns. käänteistä maskia (muutettava bitti on nolla, muut ykkösiä). Toisinkin voi tehdä. Käännetään maski komplementtioperaattori tildellä (~). esim. näin: define MASKI 1<<6 // 0100 0000 PORTB = ~MASKI & PORTB; // AND-operaatio

MASKI 0100 0000 ~MASKI 1011 1111

Tämän jälkeen toiminta on sama kuin edellä. On makuasia kumpaa tapaa käytät. Selkeyskin on kiinni tottumuksista.

Page 5: 5.10. C-Kielen Perusteet Maskaus

5

Bitin tilan vaihto Perusperiaate Bitin tilan invertoiminen (kääntäminen) tulee tapahtua niin, että muiden rekisterissä olevien bittien tila ei muutu. Niihin ei kosketa. Bitti invertoidaan siitä riippumatta onko sen tila ennestään ykkönen tai nolla. Bitti invertoidaan XOR-operaatiolla. Maski on tällöin luku, jossa käännettävä bitti on ykkönen ja muut bitit ovat nollia

Esim. Invertoidaan portin 0-bitti, muihin ei kosketa. /************************************************** ******** Project : maski_4.c Hardware: PV-M32-MOOkit + PV-EMO + PV-LEDIT B-porti ssa Software: WinAVR-20071221 Date : 07.01.2008 Author : pva Comments: invertoidaan B-portin 0-bitti muihin ei k osketa *************************************************** *******/ #include <avr/io.h> #include <util/delay.h> #define MASKI 1<<0 // 0000 0001 // *** Primitive wait() *** void wait(uint16_t time) { volatile uint16_t i; for(i=0;i<2000;i++) _delay_loop_2(time); } int main(void) { DDRB = 0xFF; // suunta ulos PORTB = 0xF0; // 1111 0000 while(1) { PORTB = MASKI ^ PORTB; // XOR-operaatio wait(200); } } Analyysi Eka kierros PORTB 1111 0000 MASKI 0000 0001 ----------------------------- ^ XOR PORTB 1111 0001 tosi-true

Toka kierros PORTB 1111 0001 MASKI 0000 0001 ----------------------------- ^ XOR PORTB 1111 0000 tosi-true