This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| et:examples:digi:switch [2015/03/03 21:58] – raivo.sell | et:examples:digi:switch [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | < | ||
| + | ====== Lüliti ====== | ||
| + | //Vajalikud teadmised: | ||
| + | [HW] [[et: | ||
| + | [AVR] [[et: | ||
| + | [LIB] [[et: | ||
| + | [PRT] [[et: | ||
| + | |||
| + | ===== Teooria ===== | ||
| + | |||
| + | Lüliti on elektromehhaaniline seade elektriahela kokku- ja lahtiühendamiseks. Lüliteid on erinevaid, kuid tüüpiline mehhaaniline lüliti koosneb klemmidest, mida saab omavahel mehhaaniliselt ühendada. Klemmide ühenduse korral on elektriahel suletud ja lülitit võib läbida elektrivool. Kui klemmid on lahti, on elektriahel avatud ja elektrivool lülitit läbida ei saa. | ||
| + | |||
| + | Lülititega saab otseselt elektriahelaid pingestada, kuid neid saab kasutada ka anduritena. Lüliti anduri funktsioonis on ka selle harjutuse teema, seepärast on vaatluse alt välja jäetud spetsiifilised kõrgepinge ja suure voolu lülitid. Lülitid erinevad ka kontaktide arvu ja nende ühendamise meetodilt. | ||
| + | |||
| + | Erinevat liiki lülititel on erinev skemaatiline tähis. Järgnevalt on toodud tüüpilisemad elektroonikaskeemides kasutatavad lülitid ja nende elektrilised tähised: | ||
| + | |||
| + | /*^ Surunupp-lüliti ^ Pöiallüliti ^ Klahvlüliti ^ Mikrolüliti ^ DIL-lüliti ^ | ||
| + | |{{: | ||
| + | | {{: | ||
| + | |||
| + | ^ Surunupp-lüliti ^ Pöiallüliti ^ Klahvlüliti ^ Mikrolüliti ^ DIL-lüliti ^ | ||
| + | |{{: | ||
| + | | {{: | ||
| + | |||
| + | Lüliti kasutamiseks andurina mikrokontrolleri juures ühendatakse lüliti üks kontakt mikrokontrolleri viiguga, mis määratakse programmis sisendiks. Kui toimub kontakti ühendamine maa- või toitepotentsiaaliga, | ||
| + | |||
| + | [{{ : | ||
| + | [{{ : | ||
| + | |||
| + | Häired teevadki lülitite kasutamise keerukamaks. Üks peamine meetod määramata olekute vältimiseks on mikrokontrolleri sisend ühendada läbi takisti kas maa- või toitepotentsiaaliga. Sellises funktsioonis olevat takistit nimetatakse inglise keeles kas // | ||
| + | |||
| + | //Pull-up// või // | ||
| + | |||
| + | Olgu öeldud, et mehhaaniliste lülititega kaasneb siiski veel üks probleem – kontaktide põrkumine. Kuna kontaktid on tehtud metallist, millel on teatav elastsus, siis kontaktide ühendamise või lahti-ühendamise hetkel need põrkuvad ning tulemusena tekib hulga väärlülitusi. Lülituste arv ja kestus sõltub lülitist, kuid enamasti jääb see mõne millisekundi piiresse. Kui lülitit kasutatakse mõne elektriseadme käivitamiseks, | ||
| + | |||
| + | <code c> | ||
| + | // Kodulabori Kasutajaliidese mooduli nupu testimise näidisprogramm | ||
| + | #include < | ||
| + | |||
| + | // Põhiprogramm | ||
| + | int main(void) | ||
| + | { | ||
| + | // LED-i viigu väljundiks ja nupu viigu sisendiks seadmine | ||
| + | pin_setup_output(led_green); | ||
| + | pin_setup_input(S1); | ||
| + | |||
| + | // Lõputu tsükkel | ||
| + | while (1) | ||
| + | { | ||
| + | // Nupule S1 vastab roheline LED, | ||
| + | // mis süttib nupu alla vajutades | ||
| + | if(pin_get_value(S1) == 1) | ||
| + | { | ||
| + | pin_set(led_green); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | pin_clear(led_green); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Lüliti põrkumise filtreerimine ==== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Põhiline kontaktide põrkumisest tekkinud väärlülitusi välistav meetod on filtreerimine. Filtreerida saab nii elektriliselt kui ka tarkvaraliselt. Elektriliseks filtreerimiseks tuleb lüliti ühendada läbi madalpääsu filtri – näiteks RC filter - mis silub pingemuutusi ja sellest tulenevalt ei omanda mikrokontrolleri viik hetkelisi väärtusi. Tarkvaraline filtreerimine toimub põhimõttel, | ||
| + | |||
| + | Tarkvaraliseks filtreerimiseks on mitmeid meetodeid. Seda võib teha lihtsalt ja keeruliselt, | ||
| + | |||
| + | Töökindlam on programm, mis kontrollib nupu olekut teatud aja jooksul mitu korda (mida rohkem ja mida pikema aja jooksul, seda kindlam). | ||
| + | |||
| + | ===== Praktika ===== | ||
| + | |||
| + | Kodulabori Kasutajaliidese mooduli plaadil on kolm surunupp-lülitit. Lülitid ühendavad mikrokontrolleri viike maaga, kuid mitte otse, vaid läbi takisti – seda põhjusel, et juhuslikul mikrokontrolleri viikude väljundiks määramisel neid nupuvajutusel ei lühistataks. Lülititel on ka //pull-up// takistid, kuid need on palju suurema takistusega kui kaitsetakistid, | ||
| + | |||
| + | Lülitite asukohad on toodud riistvarakirjelduses. Lülitite oleku lugemiseks tuleb mikrokontrolleri vastavad viigud määrata sisendiks. AVR siseseid //pull-up// takisteid ei pea tööle rakendama, sest, nagu öeldud, viikudel juba on välised takistid. Kui nupp alla vajutada, on viigule vastaval siinil biti väärtus 0, kui nupp lahti lasta, siis väärtus 1. Selleks et näha, kas mikrokontroller sai nupuvajutusest aru, võib kasutada plaadil olevaid LED indikaatoreid. | ||
| + | |||
| + | Järgnevalt on toodud Kasutajaliidese mooduli nupu filtreeritud väärtuse lugemise funktsioon: | ||
| + | |||
| + | <code c> | ||
| + | // Funktsioon lüliti filtreeritud väärtuse lugemiseks | ||
| + | unsigned char button_read(pin button) | ||
| + | { | ||
| + | unsigned char buffer = 0xAA; | ||
| + | unsigned char timeout = 100; | ||
| + | |||
| + | // Ootame, kuni nupu olek on selgunud või oleku selgitamine aegunud | ||
| + | while (timeout-- > 0) | ||
| + | { | ||
| + | // 8-kohalise (bitise) olekupuhvri pidamine | ||
| + | // Kõik eelmised olekud (bitid) nihutatakse vasakule | ||
| + | // ja paremale lisatakse uus olek (bitt) | ||
| + | buffer <<= 1; | ||
| + | buffer |= (pin_get_value(pin) ? 0x01 : 0x00); | ||
| + | |||
| + | // Kui kõik 8 bitti on madalad, siis | ||
| + | // nupp on kindlasti üleval | ||
| + | if (buffer == 0xFF) | ||
| + | { | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | // Kui kõik 8 bitti on kõrged, siis | ||
| + | // nupp on kindlasti alla vajutatud | ||
| + | if (buffer == 0x00) | ||
| + | { | ||
| + | return 1; | ||
| + | } | ||
| + | |||
| + | // Paus 1 millisekund | ||
| + | _delay_ms(1); | ||
| + | } | ||
| + | // Kui olekut ei õnnestunud välja selgitada, siis oletame, | ||
| + | // et nuppu ei vajutatud | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | See funktsioon kasutab viite tekitamise funktsiooni, | ||
| + | |||
| + | Järgnev näide illustreerib nuppude kasutamist ja mitmekordse loenduse elimineerimist kasutades tühja tsüklit, mille korral oodatakse nuppu vabastamist. | ||
| + | <code c> | ||
| + | // Kodulabori nuppude kontaktide põrkumise filtreerimise näidisprogramm | ||
| + | #include < | ||
| + | |||
| + | // Põhiprogramm | ||
| + | int main(void) | ||
| + | { | ||
| + | int counter = 0; | ||
| + | |||
| + | // LED-ide viikude väljundiks seadmine | ||
| + | pin_setup_output(led_red); | ||
| + | pin_setup_output(led_yellow); | ||
| + | pin_setup_output(led_green); | ||
| + | |||
| + | // Nupu viigu sisendiks seadmine | ||
| + | pin_setup_input(S1); | ||
| + | |||
| + | // Lõputu tsükkel | ||
| + | while (1) | ||
| + | { | ||
| + | // Nupu alla vajutamise kontroll | ||
| + | if(button_read(S1)) | ||
| + | { | ||
| + | // Loenduri väärtusele vastava LED-i süütamine | ||
| + | if(counter == 0) led_on(led_green); | ||
| + | else led_off(led_green); | ||
| + | if(counter == 1) led_on(led_yellow); | ||
| + | else led_off(led_yellow); | ||
| + | if(counter == 2) led_on(led_red); | ||
| + | else led_off(led_red); | ||
| + | |||
| + | // Loenduri suurendamine ja mooduli 3 võtmine | ||
| + | counter = (counter + 1) % 3; | ||
| + | |||
| + | // Nupu vabastamise ootamine tühjas tsüklis | ||
| + | while(button_read(S1) != 0); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Kui nüüd programmi proovida, siis LED-id süttivad täpselt sellises järjekorras nagu kasutaja nupplülitit vajutab. Nuppude kasutamise näidiskood põhineb Kodulabori viikude teegil, mida on tutvustatud valgusdioodi näites. | ||
| + | |||
| + | Tabelis on näha teegis kirjeldatud nuppude konstandid ja vastavad Kontrollermooduli viigud. | ||
| + | ^Konstandi nimi^Kodulabor I & II viik^Kodulabor III viik^Kirjeldus^ | ||
| + | |S0|PC2|PQ2|Kontrollermoodulil olev testnupp| | ||
| + | |S1|PC0|PH2|Kasutajaliidese moodulil olev alumine nupp| | ||
| + | |S2|PC1|PH1|Kasutajaliidese\ moodulil\ olev\ keskmine\ nupp| | ||
| + | |S3|PC2|PH0|Kasutajaliidese moodulil olev ülemine nupp| | ||
| + | |||
| + | |||
| + | <code c> | ||
| + | // Kodulabori nuppude testimise näidisprogramm | ||
| + | #include < | ||
| + | |||
| + | // Põhiprogramm | ||
| + | int main(void) | ||
| + | { | ||
| + | // LED-ide viikude väljundiks seadmine | ||
| + | pin_setup_output(led_red); | ||
| + | pin_setup_output(led_yellow); | ||
| + | pin_setup_output(led_green); | ||
| + | |||
| + | // Nuppude viikude sisendiks seadmine | ||
| + | pin_setup_input(S1); | ||
| + | pin_setup_input(S2); | ||
| + | pin_setup_input(S3); | ||
| + | |||
| + | // Lõputu tsükkel | ||
| + | while (1) | ||
| + | { | ||
| + | // Igale nupule vastab üks LED, | ||
| + | // mis süttib nupu alla vajutades | ||
| + | if(button_read(S1)) led_on(led_green); | ||
| + | else led_off(led_green); | ||
| + | if(button_read(S2)) led_on(led_yellow); | ||
| + | else led_off(led_yellow); | ||
| + | if(button_read(S3)) led_on(led_red); | ||
| + | else led_off(led_red); | ||
| + | } | ||
| + | } | ||
| + | </ | ||