Operácie

Zámok na kód I.: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
 
(4 medziľahlé úpravy od rovnakého používateľa nie sú zobrazené.)
Riadok 32: Riadok 32:
Pre obsluhu 4×3 maticovej klávesnice bola vytvorená vlastná knižnica klavesnica.h. Čítanie stlačeného tlačidla je realizované pomocou princípu skenovania klávesnice po riadkoch. Všetky riadky sú štandardne nastavené na logickú úroveň HIGH (+5 V), pričom aktuálne skenovaný riadok je nastavený na LOW (uzemnený). Následne sa načítava stav stĺpcov. Ak je niektoré tlačidlo stlačené, dôjde k spojeniu príslušného riadku a stĺpca, čo umožní identifikovať konkrétne tlačidlo.
Pre obsluhu 4×3 maticovej klávesnice bola vytvorená vlastná knižnica klavesnica.h. Čítanie stlačeného tlačidla je realizované pomocou princípu skenovania klávesnice po riadkoch. Všetky riadky sú štandardne nastavené na logickú úroveň HIGH (+5 V), pričom aktuálne skenovaný riadok je nastavený na LOW (uzemnený). Následne sa načítava stav stĺpcov. Ak je niektoré tlačidlo stlačené, dôjde k spojeniu príslušného riadku a stĺpca, čo umožní identifikovať konkrétne tlačidlo.


V inicializačnej funkcii keypad_init() sú piny PA0 PA3 nastavené ako výstupy pre riadky klávesnice a piny PA4 PA6 ako vstupy pre stĺpce. Na vstupných pinoch sú aktivované interné pull-up rezistory, aby bol zabezpečený stabilný logický stav pri nestlačených tlačidlách.
V inicializačnej funkcii keypad_init() sú piny 22 25 nastavené ako výstupy pre riadky klávesnice a piny 26 28 ako vstupy pre stĺpce. Na vstupných pinoch sú aktivované interné pull-up rezistory, aby bol zabezpečený stabilný logický stav pri nestlačených tlačidlách.


Funkcia keypad_getkey() postupne skenuje jednotlivé riadky. Pre každý riadok nastaví všetky riadky do stavu HIGH a následne aktuálny riadok do stavu LOW. Po krátkej stabilizačnej pauze sa kontrolujú vstupy stĺpcov. Ak je detekované stlačené tlačidlo, funkcia vráti číselnú hodnotu reprezentujúcu jeho pozíciu v matici klávesnice. Táto hodnota je vypočítaná podľa vzťahu k = 3 * r + c kde:
Funkcia keypad_getkey() postupne skenuje jednotlivé riadky. Pre každý riadok nastaví všetky riadky do stavu HIGH a následne aktuálny riadok do stavu LOW. Po krátkej stabilizačnej pauze sa kontrolujú vstupy stĺpcov. Ak je detekované stlačené tlačidlo, funkcia vráti číselnú hodnotu reprezentujúcu jeho pozíciu v matici klávesnice. Táto hodnota je vypočítaná podľa vzťahu k = 3 * r + c kde:
<ul>
<ul>
<li>k je výsledný identifikátor tlačidla.</li>
<li>k je výsledný identifikátor tlačidla</li>
<li>r predstavuje index riadku,</li>
<li>r predstavuje index riadku</li>
<li>c predstavuje index stĺpca,</li>
<li>c predstavuje index stĺpca</li>
</ul>
</ul>
Tento spôsob nahrádza rozsiahle podmienky typu if-else jednoduchším a prehľadnejším výpočtom. Ak nie je stlačené žiadne tlačidlo, funkcia vracia hodnotu -1.
Tento spôsob nahrádza rozsiahle podmienky typu if-else jednoduchším a prehľadnejším výpočtom. Ak nie je stlačené žiadne tlačidlo, funkcia vracia hodnotu -1.


<tabs>
<tabs>
Riadok 210: Riadok 209:
void keypad_init(void)
void keypad_init(void)
{
{
     // Rows ako výstupy
     // Riadky ako výstupy
     DDRA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
     DDRA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);


     // Columns ako vstupy
     // Stĺpce ako vstupy
     DDRA &= ~((1<<PA4)|(1<<PA5)|(1<<PA6));
     DDRA &= ~((1<<PA4)|(1<<PA5)|(1<<PA6));


     // Pull-up na columns
     // Pull-up na stĺpcoch
     PORTA |= (1<<PA4)|(1<<PA5)|(1<<PA6);
     PORTA |= (1<<PA4)|(1<<PA5)|(1<<PA6);


     // Rows default HIGH
     // Riadky default HIGH
     PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
     PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
}
}
Riadok 227: Riadok 226:
     for (int row = 0; row < 4; row++)
     for (int row = 0; row < 4; row++)
     {
     {
         // Všetky rows HIGH
         // Všetky riadky HIGH
         PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
         PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);


         // Aktuálny row LOW
         // Aktuálny riadok LOW
         PORTA &= ~(1 << row);
         PORTA &= ~(1 << row);


         _delay_us(5); // stabilizácia
        // Stabilizácia bez tohto moze prestať funkovať prvý stĺpec prtože sa nestihnú nastaviť zmeny z PORTA &= ~(1 << row);
         _delay_us(5);


         // Čítanie columns (chatgpt upravil z if else stetmentov na toto kde stlačený button je reprezentovný číslom a dása dekódovať pomocou modula a delenia)
         // Čítanie stĺpcov
         if (!(PINA & (1<<PA6))) return row*3 + 0;
         if (!(PINA & (1<<PA6))) return row*3 + 0;
if (!(PINA & (1<<PA5))) return row*3 + 1;
if (!(PINA & (1<<PA5))) return row*3 + 1;

Aktuálna revízia z 21:45, 10. máj 2026

Záverečný projekt predmetu MIPS / LS2026 - Adam Čulák


Zadanie

Sem príde text zadania, ak bolo len voľne formulované, rozpíšte ho podrobnejšie

Vývojová doska Arduino MEGA CH340.

Literatúra:


Analýza a opis riešenia

Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami... Podrobne opíšte použité komponenty (okrem základnej dosky s ATmega328P procesorom), pridajte linky na datasheety alebo opis obvodu.

Celkový pohľad na zariadenie.

Nezabudnite doplniť schému zapojenia! V texte by ste mali opísať základné veci zo zapojenia, samotná schéma nie je dostačujúci opis.

Schéma zapojenia.


Algoritmus a program

Algoritmus programu využíva základné knižnice pre uart a lcd z cvičení, pričom knižnica pre lcd bola upravená tak, aby fungovala s doskou Arduino Mega 2560. Úprava spočíva najmä v zmene používaných portov, pretože porty požité pri mikrokontroléri ATmega2560 sa líšia od portov použitých pri mikrokontroléri ATmega328P.

Pre obsluhu 4×3 maticovej klávesnice bola vytvorená vlastná knižnica klavesnica.h. Čítanie stlačeného tlačidla je realizované pomocou princípu skenovania klávesnice po riadkoch. Všetky riadky sú štandardne nastavené na logickú úroveň HIGH (+5 V), pričom aktuálne skenovaný riadok je nastavený na LOW (uzemnený). Následne sa načítava stav stĺpcov. Ak je niektoré tlačidlo stlačené, dôjde k spojeniu príslušného riadku a stĺpca, čo umožní identifikovať konkrétne tlačidlo.

V inicializačnej funkcii keypad_init() sú piny 22 až 25 nastavené ako výstupy pre riadky klávesnice a piny 26 až 28 ako vstupy pre stĺpce. Na vstupných pinoch sú aktivované interné pull-up rezistory, aby bol zabezpečený stabilný logický stav pri nestlačených tlačidlách.

Funkcia keypad_getkey() postupne skenuje jednotlivé riadky. Pre každý riadok nastaví všetky riadky do stavu HIGH a následne aktuálny riadok do stavu LOW. Po krátkej stabilizačnej pauze sa kontrolujú vstupy stĺpcov. Ak je detekované stlačené tlačidlo, funkcia vráti číselnú hodnotu reprezentujúcu jeho pozíciu v matici klávesnice. Táto hodnota je vypočítaná podľa vzťahu k = 3 * r + c kde:

  • k je výsledný identifikátor tlačidla
  • r predstavuje index riadku
  • c predstavuje index stĺpca

Tento spôsob nahrádza rozsiahle podmienky typu if-else jednoduchším a prehľadnejším výpočtom. Ak nie je stlačené žiadne tlačidlo, funkcia vracia hodnotu -1.

#define F_CPU 16000000UL
#define BAUD 115200

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "uart.h"
#include "klavesnica.h"
#include "lcd_ch.h"

// Macra na nastavenie a vynulovanie bitu z cičenia
#define set_bit(ADDRESS, BIT) (ADDRESS |= (1 << BIT))
#define clear_bit(ADDRESS, BIT) (ADDRESS &= ~(1 << BIT))

// Funkcia delay z cvičenia
void delay(int delay)
{
	for (int i = 0; i< delay; i++) _delay_ms(1);
}

// Prerušenie pomomocov timeru na bliknutie LED
ISR(TIMER1_OVF_vect)
{
	TCCR1B = 0; // Vypnutie časovača 
	clear_bit(PORTB, PB0);
	clear_bit(PORTB, PB1);
}

int main(void)
{
    char password[] = "0159"; // Premenná ukladajúca nastavené heslo
    char guess[5] = ""; // Premenná ukladajúca hádané heslo
    int index = 0; // Index pola hádaného hesla
	int last_key = -1; // Premenná pre ulozenie posledného stlacenného tlacitka
	
	// Inicializácia knižníc
    uart_init();
    keypad_init();
	lcd_init();
	
    // Nastavenie pinou pre LED
	set_bit(DDRB, PB0);
	set_bit(DDRB, PB1);
	
	TIMSK1 |= (1 << TOIE1);
	
	// Mapovanie cisel k znakom
    char keys[4][3] = {
        {'1','2','3'},
        {'4','5','6'},
        {'7','8','9'},
        {'*','0','#'}
    };
    
	sei(); // Zapnutie interuptov pre zhasnutie LED diod
	
    while(1)
    {
        int k = keypad_getkey(); // Premenná pre numerickú hodnotu navrátenú z knižnice klavesnica
        
        if (k != -1 && last_key == -1)
        {
            _delay_ms(20);  // Debounce
            k = keypad_getkey();

            if (k != -1)
            {
				// Dekódovanie číselnej hodnoty na znak
                char key = keys[k/3][k%3];

                // BACKSPACE (*)
                if (key == '*' && index > 0)
                {
                    guess[--index] = '\0';
					lcd_clear();
					lcd_print(guess);
                }

                // Kontrola spravnosti hesla po stlaceni ENTER (#) alebo automaticky po 4 znakoch
                else if (key == '#' || index == 4)
                {
                    if (index == 4)
                    {
                        guess[4] = '\0'; // Nastavenie posledného znaku na string end

                        int same = 1; // Premenná pre kontrolu či sú heslá rovnaké
                        for (int i = 0; i < 4; i++)
                        {
                            if (guess[i] != password[i])
                            {
                                same = 0;
                                break;
                            }
                        }

						if (same) 
						{
							set_bit(PORTB, PB0); // Zasvietenie LED
							TCCR1B |= (1 << CS12) | (1 << CS10); // Prescale na 1024
							TCNT1 = 0xC2F7; // Nastavenie TCNT1 na hodnotu aby mi po 1s vyplo LED
							uart_puts("Spravne heslo\n"); // Výpis na uart
							lcd_clear();
							lcd_print("Spravne heslo"); // Výpis na LCD
						}							
                        else
						{
							set_bit(PORTB, PB1); // Zasvietenie LED
							TCCR1B |= (1 << CS12) | (1 << CS10); // Prescale na 1024
							TCNT1 = 0x85EE; // Nastavenie TCNT1 na hodnotu aby mi po 2s vyplo LED
							uart_puts("Nespravne heslo\n"); // Výpis na uart
							lcd_clear();
							lcd_print("Nespravne heslo"); // Výpis na LCD
						}							
                    }
                    else
                    {
						// Ak je stlacene # pred tým nez sa zadá úplne heslo
						set_bit(PORTB, PB1); // Zasvietenie LED
						TCCR1B |= (1 << CS12) | (1 << CS10); // Prescale na 1024
						TCNT1 = 0x85EE; // Nastavenie TCNT1 na hodnotu aby mi po 2s vyplo LED
                        uart_puts("Neuplne heslo\n"); // Výpis na uart
						lcd_clear();
						lcd_print("Neuplne heslo"); // Výpis na LCD
                    }


                    // Reset hádaného hesla
                    for (int i = 0; i < 5; i++)
                        guess[i] = '\0';	
                    index = 0;
                }

                // Stlacene tlacitko 0-9
                else if (index < 4 && key != '*' && key != '#')
                {
                    guess[index++] = key;
                    guess[index] = '\0';
					// Vypis na LCD display
					lcd_clear();
					lcd_print(guess);
					// Vypis na uart
                    uart_puts(guess);
                    uart_putc('\n');
                }
            }
        }
        // Aby sa nám tlacitko nestlacilo viac ako 1 krat
        last_key = k;
    }
}
void keypad_init(void);
int keypad_getkey(void);
#define F_CPU 16000000UL
#define BAUD 115200

#include <avr/io.h>
#include <util/delay.h>

void keypad_init(void)
{
    // Riadky ako výstupy
    DDRA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);

    // Stĺpce ako vstupy
    DDRA &= ~((1<<PA4)|(1<<PA5)|(1<<PA6));

    // Pull-up na stĺpcoch
    PORTA |= (1<<PA4)|(1<<PA5)|(1<<PA6);

    // Riadky default HIGH
    PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
}

int keypad_getkey(void)
{
    for (int row = 0; row < 4; row++)
    {
        // Všetky riadky HIGH
        PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);

        // Aktuálny riadok LOW
        PORTA &= ~(1 << row);

        // Stabilizácia bez tohto moze prestať funkovať prvý stĺpec prtože sa nestihnú nastaviť zmeny z PORTA &= ~(1 << row);
        _delay_us(5);

        // Čítanie stĺpcov
        if (!(PINA & (1<<PA6))) return row*3 + 0;
		if (!(PINA & (1<<PA5))) return row*3 + 1;
		if (!(PINA & (1<<PA4))) return row*3 + 2;
    }

    return -1; // Ak je nič nestlačené
}

Zdrojový kód: zdrojaky.zip

Overenie

Ako ste overili funkciu, napríklad... Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku hotového zariadenia.

Aplikácia.

Video:

Čo by som urobil inak

Zamyslite sa spätne nad problémom, ktorý ste riešili a napíšte, čo sa vám nepodarilo a nabudúce by ste spravili inak.


Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.