Operácie

UART Kalkulačka: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
Riadok 51: Riadok 51:


</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
<tab name="filename.h"><syntaxhighlight  lang="c++" style="background: LightYellow;">
 
<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);
}


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


unsigned int adc_read(char a_pin);
</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'.

Vývojová doska Arduino UNO.

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.

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

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


Aplikácia.

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.