Operácie

Vstupná jednotka s palcovým prepínačom TS211

Zo stránky SensorWiki

Verzia z 13:20, 24. jún 2026, ktorú vytvoril Balogh (diskusia | príspevky)
(rozdiel) ← Staršia verzia | Aktuálna úprava (rozdiel) | Novšia verzia → (rozdiel)

Záverečný projekt predmetu MIPS / LS2026 - Sofiia Nevzorova


Zadanie

Navrhnite a realizujte vstupnú jednotku na báze dvojsekčného palcového prepínača TS211 s BCD kódovaním pripojenú k vývojovej doske ACROB. Programovo zabezpečte čítanie hodnôt z oboch sekcií prepínača (desiatky a jednotky) v negatívnej logike s využitím interných pull-up rezistorov mikrokontroléra ATmega328P. Implementujte algoritmus na prevod BCD kódov z portov PORTC a PORTD na výsledné dekadické číslo v rozsahu 00 až 99. Zabezpečte výpis aktuálnej hodnoty cez rozhranie UART do konzoly pri každej zmene nastavenia(na overenie).

Vývojová doska ACROB.

Literatúra:

Analýza a opis riešenia

Základným komponentom tohto riešenia je dvojsekčný palcový prepínač TS211. Každá sekcia prepínača funguje ako mechanický dekodér, ktorý prevádza nastavenú číslicu (0–9) na 4-bitový signál v kóde BCD (Binary Coded Decimal). Prepínač má pre každú sekciu 5 výstupov: jeden spoločný kontakt (Common) a štyri dátové kontakty s váhami 1, 2, 4 a 8.

Celkový pohľad na zariadenie.

Princíp činnosti a softvérové spracovanie: Vstupy mikrokontroléra sú nakonfigurované v režime s aktivovanými internými pull-up rezistormi. To znamená, že piny pracujú v negatívnej logike: Ak je kontakt v prepínači otvorený, pull-up rezistor drží na pine logickú 1. Ak je kontakt zopnutý (číslica je zvolená), pin sa prepojí so zemou (GND) a procesor načíta logickú 0. V programe sa preto načítané hodnoty z registrov PINC a PIND najskôr bitovo invertujú (~). Pre desiatky (PORTC) sa priamo maskujú spodné 4 bity. Pre jednotky (PORTD) sa využíva bitový posun doprava o 2 miesta (>> 2), aby sa bity z pozícií D2–D5 dostali na pozície 0–3 pre správny výpočet váhy BCD kódu.

Výsledné číslo sa vypočíta podľa vzťahu: Hodnota = (Desiatky * 10) + Jednotky, a následne sa posiela cez rozhranie UART do konzoly PuTTY.

Schéma zapojenia.

Hardvérové zapojenie: Prepojenie s mikrokontrolérom ATmega328P na doske ACROB bolo realizované nasledovne: Ľavý blok (Desiatky): Výstupy s váhami 1, 2, 4, 8 sú pripojené na piny A0, A1, A2 a A3 (čo zodpovedá portu PORTC, bity 0–3). Pravý blok (Jednotky): Výstupy sú pripojené na digitálne piny D2, D3, D4 a D5 (port PORTD, bity 2–5). Spoločné kontakty (C): Obe sekcie majú spoločný kontakt pripojený na GND (zem). Z hľadiska mechanickej konštrukcie bolo kvôli nedostatočnej dĺžke kontaktov prepínača pre montáž priamo do breadboardu zvolené pripojenie pomocou flexibilných vodičov, čím sa zabezpečil spoľahlivý elektrický kontakt.


Algoritmus a program

V programe sme využili 8-bitovú premennú uint8_t na uloženie stavu jednotlivých sekcií prepínača. Hodnota z portov sa po inverzii maskuje pomocou 0x0F, čím získame čistý BCD kód (0–9).

V úvode funkcie main prebieha inicializácia smerových registrov DDR a nastavenie vstupov:

DDRC &= ~0x0F; PORTC |= 0x0F;

DDRD &= ~0x3C; PORTD |= 0x3C;

Týmto krokom aktivujeme vnútorné pull-up rezistory ešte pred vstupom do hlavného cyklu while(1), čo zabezpečuje stabilné čítanie hodnôt z prepínača hneď po štarte mikrokontroléra.

Výsledná hodnota sa vypočíta podľa vzťahu:

total = (tens * 10) + units;

Pre výpočet desiatkovej hodnoty z portu D sme použili bitový posun o 2 miesta doprava, pretože fyzické pripojenie prepínača na piny D2 až D5 posúva dáta v registri PIND.

Vzťah pre prepočet je:

tens = (~PIND >> 2) & 0x0F;

Táto úprava je nevyhnutná, aby sa logické úrovne zarovnali do intervalu 0 až 9, ktorý zodpovedá číslam na prepínači. Všetky výpočty sú vykonávané v celočíselnej aritmetike, čo je pre daný rozsah 0–99 úplne postačujúce.

Na riadenie výpisu do konzoly bola použitá pomocná premenná last_val:

if (total != last_val) {

printf("Value: %02u\n", total);

last_val = total;

}

Táto podmienka zabezpečuje, že mikrokontrolér odosiela dáta cez UART len v momente, keď dôjde k fyzickej zmene nastavenia na prepínači. Týmto sa minimalizuje zaťaženie sériovej linky a terminál PuTTY zostáva prehľadný. Pri implementácii boli využité štandardné typy

uint8_t pre dáta z portov a

uint16_t pre výslednú hodnotu, čo je z hľadiska pamäťových nárokov na procesor ATmega328P optimálne.

V hlavnom cykle programu je zaradené krátke oneskorenie _delay_ms(150);. Táto pauza slúži na stabilizáciu hodnôt pri mechanickom prepínaní kontaktov a zabraňuje náhodným chybám v načítaných dátach počas pohybu prepínača.

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "uart.h"

FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);

uint8_t read_bcd_tens(void) {
    uint8_t status = ~PINC;
    return (status & 0x0F); 
}

uint8_t read_bcd_units(void) {
    uint8_t status = ~PIND;
    return ((status >> 2) & 0x0F); 
}

int main(void)
{
    uart_init();
    stdout = &mystdout; 
    
    DDRC &= ~0x0F; PORTC |= 0x0F;      
    DDRD &= ~0x3C; PORTD |= 0x3C;      

    uint8_t last_val = 255; 

    while(1)
    {
        uint8_t tens = read_bcd_tens();   
        uint8_t units = read_bcd_units(); 
        
        uint16_t total = (tens * 10) + units;
        
        if (total != last_val) {
            printf("Value: %02u\n", total);
            last_val = total;
        }
        
        _delay_ms(150); 
    }
    return 0;
}
#include <avr/io.h>

void adc_init(void);                                   // A/D converter initialization

unsigned int adc_read(char a_pin);


Zdrojový kód: projekt_Nevzorova

Overenie

Správna funkcia projektu bola overená sledovaním sériového výstupu v termináli PuTTY. Pri každej mechanickej zmene polohy palcového prepínača sa v konzole okamžite zobrazila zodpovedajúca dvojciferná hodnota. Testovaním všetkých polôh oboch sekcií (0–9) sa potvrdilo, že program správne interpretuje BCD kód a bezchybne vypočítava výsledné dekadické číslo v rozsahu 00 až 99.

Video:

Čo by som urobila inak

V budúcej verzii by som namiesto neustáleho dopytovania sa na stav portov v cykle (polling) skúsila implementovať čítanie pomocou externých prerušení (interrupts), čo by zvýšilo efektivitu programu. Taktiež by som pridala ďalšiu sekciu prepínača pre zadávanie trojciferných čísel a navrhla kompaktný plošný spoj, aby som nahradila veľké množstvo prepojovacích káblov stabilnejším riešením.