UART Kalkulačka: Rozdiel medzi revíziami
Zo stránky SensorWiki
| Riadok 51: | Riadok 51: | ||
</syntaxhighlight ></tab> | </syntaxhighlight ></tab> | ||
<tab name=" | |||
<tab name="uart.h"><syntaxhighlight lang="c++" style="background: LightYellow;"> | |||
#ifndef UART_H_ | |||
#define UART_H_ | |||
#include <avr/io.h> | |||
#include <stdio.h> | |||
void uart_init(void); | |||
//void uart_putc(char c); | |||
//char uart_getc(void); | |||
int uart_putc(char c, FILE *stream); | |||
int uart_getc(FILE *stream); | |||
void uart_puts(const char *s); | |||
#endif /* UART_H_ */ | |||
</syntaxhighlight ></tab> | |||
<tab name="uart.c"><syntaxhighlight lang="c++" style="background: LightYellow;"> | |||
#define F_CPU 16000000UL | |||
#define BAUD 9600 | |||
#define MYUBRR (F_CPU / 16 / BAUD - 1) | |||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <stdio.h> | |||
#include "uart.h" | |||
void uart_init(void) | |||
{ | |||
unsigned int ubrr = MYUBRR; | |||
/* nastavenie baud rate */ | |||
UBRR0H = (unsigned char)(ubrr >> 8); | |||
UBRR0L = (unsigned char)(ubrr); | |||
/* zapni RX a TX */ | |||
UCSR0B = (1 << RXEN0) | (1 << TXEN0); | |||
/* 8 datových bitov, 1 stop bit, bez parity */ | |||
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); | |||
} | |||
int uart_putc(char c, FILE *stream) | |||
{ | |||
if (c == '\n') | |||
uart_putc('\r', stream); | |||
while (!(UCSR0A & (1 << UDRE0))); /* čakaj kým je buffer prázdny */ | |||
UDR0 = c; | |||
return 0; | |||
} | |||
int uart_getc(FILE *stream) | |||
{ | |||
while (!(UCSR0A & (1 << RXC0))); /* čakaj na prijatý znak */ | |||
return UDR0; | |||
} | |||
void uart_puts(const char *s) | |||
{ | |||
while (*s) | |||
uart_putc(*s++, NULL); | |||
} | |||
</syntaxhighlight ></tab> | </syntaxhighlight ></tab> | ||
</tabs> | </tabs> | ||
Verzia z 22:41, 7. jún 2026
Záverečný projekt predmetu MIPS / LS2026 - Broňa Dzivjaková
Zadanie
Úlohou bolo implementovať kalkulačku komunikujúcu cez sériové rozhranie UART (minimálne použiť: +, -, *, /). Používateľ zadáva matematický príklad (napr. 10+5 alebo 3.14*2) priamo cez sériový terminál a Arduino UNO výsledok vypočíta a odošle späť. Po úspešnom výpočte sa rozsvieti vstavaná LED dióda na pine 13. Program taktiež uchováva históriu posledných troch príkladov v pamäti EEPROM, ktorá zostane zachovaná aj po vypnutí zariadenia. Históriu je možné zobraziť príkazom 'h' a vymazať príkazom 'clear'.

Literatúra:
Analýza a opis riešenia
Projekt je realizovaný na vývojovej doske Arduino UNO s mikrokontrolérom ATmega328P. Komunikácia prebieha cez UART rozhranie na rýchlosti 9600 baudov. Na vstup ani výstup nie sú potrebné žiadne externé súčiastky – využíva sa vstavaná LED dióda na pine 13 (PB5) a sériový port cez USB kábel.

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
Program je rozdelený do niekoľkých funkcií. Po spustení sa inicializuje UART (funkcia uart_init) a LED pin ako výstup. Hlavná slučka čaká na vstup od používateľa. Funkcia 'read_line' číta znaky zo sériového portu jeden po druhom a ukladá ich do buffera, kým nepríde 'Enter'.
Funkcia 'process' spracuje zadaný reťazec. Najprv vyhľadá operátor (+, -, *, /) v reťazci, následne skontroluje, či sú oba vstupné operandy platné čísla. Ak používateľ zadá písmeno namiesto čísla, program vypíše chybu. Funkcia 'atof()' konvertuje reťazce na desatinné čísla, čo umožňuje pracovať aj s desatinnými hodnotami (napr. 3.14*2). Výsledok sa vypíše cez UART a príklad sa uloží do EEPROM histórie.
#include <avr/io.h>
int main(void)
{
unsigned int measuredValue;
while (1)
{
/* relax */
}
return(0);
}
#ifndef UART_H_
#define UART_H_
#include <avr/io.h>
#include <stdio.h>
void uart_init(void);
//void uart_putc(char c);
//char uart_getc(void);
int uart_putc(char c, FILE *stream);
int uart_getc(FILE *stream);
void uart_puts(const char *s);
#endif /* UART_H_ */
#define F_CPU 16000000UL
#define BAUD 9600
#define MYUBRR (F_CPU / 16 / BAUD - 1)
#include <avr/io.h>
#include <stdio.h>
#include "uart.h"
void uart_init(void)
{
unsigned int ubrr = MYUBRR;
/* nastavenie baud rate */
UBRR0H = (unsigned char)(ubrr >> 8);
UBRR0L = (unsigned char)(ubrr);
/* zapni RX a TX */
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
/* 8 datových bitov, 1 stop bit, bez parity */
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
int uart_putc(char c, FILE *stream)
{
if (c == '\n')
uart_putc('\r', stream);
while (!(UCSR0A & (1 << UDRE0))); /* čakaj kým je buffer prázdny */
UDR0 = c;
return 0;
}
int uart_getc(FILE *stream)
{
while (!(UCSR0A & (1 << RXC0))); /* čakaj na prijatý znak */
return UDR0;
}
void uart_puts(const char *s)
{
while (*s)
uart_putc(*s++, NULL);
}
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:
Zdrojový kód: zdrojaky.zip
Overenie
Funkčnosť som overila pomocou sériového terminálu s knižnicou UART. Testovala som každú z ponúknutých operácií, operáciu s desatinnými číslami, a aj chybové stavy. • Základné operácie: 10+5 = 15, 8*3 = 24, 9-4 = 5, 10/4 = 2.5000 • Desatinné čísla: 3.14*2 = 6.2800 • Chybové stavy: delenie nulou, zadanie písmena namiesto čísla • História: príkaz 'h' zobrazí posledné 3 príklady, 'clc' ich vymaže • LED: po každom správnom výpočte blikne vstavaná LED na pine 13

Video:
Čo by som urobil inak
Projekt splnil požiadavky zadania, no v budúcnosti by som ho rozšírila o LCD displej, kde by sa príklady a výsledky zobrazovali priamo na zariadení bez potreby počítača a sériového terminálu. Taktiež by bolo zaujímavé pridať podporu pre viac operácií v jednom výraze s dodržaním matematickej priority (násobenie pred sčítaním).
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.