Zámok na kód I.: Rozdiel medzi revíziami
Zo stránky SensorWiki
| Riadok 36: | Riadok 36: | ||
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>k je výsledný identifikátor tlačidla</li> | ||
<li>r predstavuje index riadku | <li>r predstavuje index riadku</li> | ||
<li>c predstavuje index stĺpca | <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. | ||
Verzia z 20:40, 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

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.

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.

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 PA0 až PA3 nastavené ako výstupy pre riadky klávesnice a piny PA4 až 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.
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)
{
// Rows ako výstupy
DDRA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
// Columns ako vstupy
DDRA &= ~((1<<PA4)|(1<<PA5)|(1<<PA6));
// Pull-up na columns
PORTA |= (1<<PA4)|(1<<PA5)|(1<<PA6);
// Rows default HIGH
PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
}
int keypad_getkey(void)
{
for (int row = 0; row < 4; row++)
{
// Všetky rows HIGH
PORTA |= (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
// Aktuálny row LOW
PORTA &= ~(1 << row);
_delay_us(5); // stabilizácia
// Čí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)
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.

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.