Operácie

Sériové komunikačné rozhranie: Rozdiel medzi revíziami

Z SensorWiki

(2. Základný princíp prenosu cez USART)
(39 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 1: Riadok 1:
 +
 
__NOTOC__
 
__NOTOC__
 
== Sériové komunikačné rozhranie (UART) ==
 
== Sériové komunikačné rozhranie (UART) ==
Riadok 8: Riadok 9:
 
# Vyskúšajte demonštračný program, na strane PC použite terminál
 
# Vyskúšajte demonštračný program, na strane PC použite terminál
 
# Vytvorte si knižnice pre prácu so sériovou linkou, preštudujte využitie knižnice <stdio.h> a demonštrujte.
 
# Vytvorte si knižnice pre prácu so sériovou linkou, preštudujte využitie knižnice <stdio.h> a demonštrujte.
# Oboznámte sa s programom StampPlot a zobrazte časový priebeh.
+
# Napíšte program, ktorý klávesami +/- bude meniť jas LED diódy.
 +
 
 +
 
 +
'''Literatúra:'''
  
 +
2021
 +
* [http://ebook.pldworld.com/_Semiconductors/Atmel/Databook%20CDROM/Atmel/acrobat/doc1451.pdf 1AVR306: Using the AVR® UART in C] with examples.
 +
* [http://ww1.microchip.com/downloads/en/Appnotes/Atmel-1451-Using-the-AVR-USART-on-tinyAVR-and-megaAVR-devices_ApplicationNote_AVR306.pdf  8-bit AVR Microcontrollers AVR306: Using the AVR USART on tinyAVR andmegaAVR devices]. Atmel Application Note.
 +
* [http://ww1.microchip.com/downloads/en/Appnotes/doc0941.pdf AVR304: Half Duplex Interrupt Driven Software UART] Application note.
 +
* https://appelsiini.net/2011/simple-usart-with-avr-libc/#registers
  
Literatúra:
 
  
 
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=45341 Using the USART with AVR-GCC]
 
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=45341 Using the USART with AVR-GCC]
 
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=48188 Interrupt driven USARTs]
 
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=48188 Interrupt driven USARTs]
 
* Ako používať USART: [[AVR Serial.c|knižnica a príklady...]]
 
* Ako používať USART: [[AVR Serial.c|knižnica a príklady...]]
 +
* Ako nastaviť prenosovú rýchlosť - tabuľky s odchýlkami http://ruemohr.org/~ircjunk/avr/baudcalc/avrbaudcalc-1.0.8.php?postbitrate=9600&postclock=16
 +
* Programovanie [[AP Blok 3|Programovanie sériovej linky pod Windows]] - tretí blok z Architektúry počítačov
 +
 +
 +
 +
 +
 +
=== 1. Hardvér ===
 +
 +
Podrobnejší popis hardvéru pre sériové komunikačné rozhranie presahuje rámec tohoto cvičenia, záujemcov odkazujeme na text [http://senzor.robotika.sk/ap/texty/rs232.php Normy pre fyzickú vrstvu komunikačných rozhraní].
 +
 +
Pripomenieme na tomto mieste len skutočnosť, že prepojenie cez sériové rozhranie sa môže uskutočniť buď priamo v TTL (resp. CMOS) logických úrovniach 5V, napríklad takto sa dajú prepojiť dve Arduino dosky medzi sebou
  
=== 1. Základný princíp prenosu cez USART ===
+
<div style='text-align: center;'>
 +
[[Súbor:MIPS_Arduino-ArduinoCOM.png]]<BR>
 +
''Schéma prepojenia dvoch Arduino dosiek.''
 +
</div>
  
Ukážkový program s vysvetlivkami - nahrajte si do AVRstudia a odkrokujte.  
+
Iným príkladom je [https://www.sparkfun.com/products/10097 LCD displej so sériovým prevodníkom], ktorý potrebuje na pripojenie len 3 (2) vodiče.
 +
 
 +
Ak by sme riešili pripojenie zariadenia, ktoré má skutočne rozhranie RS-232, t.j. napäťové úrovne +/-10V, potrebujeme prevodník, ktorý z TTL úrovne vyrobí príslušné napätia. Typickým zástupcom širokého spektra takýchto prevodníkov je obvod MAX232 (Maxim Integrated), ktorý obsahuje malý spínaný menič, takže potrebné napätia +/-10V si vyrobí priamo na čipe z jedného napájacieho napätia 5V. Typická schéma zapojenia je na obrázku nižšie.
 +
 
 +
<div style='text-align: center;'>
 +
[[Súbor:MIPS_SerialMAX232.png|700px]]<BR>
 +
''Schéma prevodníka na úrovne RS-232.''
 +
</div>
 +
 
 +
 
 +
Arduino nepoužíva pre komunikáciu s PC ani jeden z vyššieuvedených spôsobov, ale pripája sa na zbernicu USB (Universal Serial Bus). Na to je tiež potrebný špeciálny prevodník. Pri prvých verziách Arduino dosky sa používal špeciálny itegrovaný obvod [http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf FT232RL] (FTDI Chips), v lacných klonoch sa menej spoľahlivá kópia [https://cdn.sparkfun.com/datasheets/Dev/Arduino/Other/CH340DS1.PDF CH340G],  neskôr sa rozhranie USB zrealizovalo pomocou špecializovaného mikroprocesora Atmel ATmega16U2, ktorý má potrebné rozhranie už integrované. Ako to funguje sa dá pozrieť na schéme zapojenia.
 +
* [https://www.sparkfun.com/datasheets/DevTools/Arduino/FTDI%20Basic-v21-5V.pdf Prevodník s čipom FT232RL]
 +
* [https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf Arduino UNO v3 schematic diagram]
 +
 
 +
 
 +
 
 +
 
 +
 
 +
=== 2. Základný princíp prenosu cez USART ===
 +
 
 +
Ukážkový program v ktorom je všetko pohromade: inicializácia, príjem aj vysielanie. Program čaká na prijatý znak a vráti znak s ASCII kódom o jedna väčším. Mohol by vrátiť aj rovnaký, ale to by sme nevedeli rozlíšiť od funkcie "local echo" v niektorých termináloch.
  
 
<source lang="c">
 
<source lang="c">
Riadok 25: Riadok 68:
  
 
#define BAUDRATE      9600
 
#define BAUDRATE      9600
#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)
+
#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1) // vzorček z datasheetu
  
  
Riadok 35: Riadok 78:
 
                                                          
 
                                                          
 
   UBRR0 = (unsigned char)BAUD_PRESCALE;                // Set baud rate: Load the UBRR register
 
   UBRR0 = (unsigned char)BAUD_PRESCALE;                // Set baud rate: Load the UBRR register
 +
 +
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);                    // Set format: 8data, 1stop bit
  
 
   UCSR0B = (1 << RXEN0) | (1 << TXEN0);                // Enable receiver and transmitter
 
   UCSR0B = (1 << RXEN0) | (1 << TXEN0);                // Enable receiver and transmitter
  
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);                      // Set format: 8data, 2stop bit
 
  
 
   for (;;)                                              // Loop forever
 
   for (;;)                                              // Loop forever
Riadok 69: Riadok 113:
  
  
=== 2. Jednoduchá knižnica ===
+
 
 +
Väčšina parametrov je vždy rovnaká (8 bitov, bez parity, 1 stop bit), meniť sa zvykne len rýchlosť. Treba však upozorniť, že pre spoľahlivý asynchrónny prenos by sa nemali hodiny vysielača a prijímača líšiť o viac ako 2%. To sa dá dosiahnuť veľmi jednoducho pre špeciálne hodnoty oscilátora (napr. kryštál 18,432 MHz), ale pre nami používaný oscilátor 16 MHz sú niektoré rýchlosti menej vhodné.
 +
 
 +
<div style='text-align: center;'>
 +
[[Súbor:MIPS_UARTspeedTavle.png]]<BR>
 +
''Tabuľka s prensovými rýchlosťami pre 16 MHz.''
 +
</div>
 +
 
 +
=== 3. Jednoduchá knižnica ===
  
 
Nebudeme sa zaoberať detailmi implementácie sériového komunikačného rozhrania procesorov AVR, pre naše účely postačí jednoduchá knižnica, ktorá obsahuje základné funkcie na prenos jedného znaku. Parametre prenosu pre túto knižnicu sú 9600,n,8,1.
 
Nebudeme sa zaoberať detailmi implementácie sériového komunikačného rozhrania procesorov AVR, pre naše účely postačí jednoduchá knižnica, ktorá obsahuje základné funkcie na prenos jedného znaku. Parametre prenosu pre túto knižnicu sú 9600,n,8,1.
  
'''serial.h'''
+
<tabs>
<source lang="c">
+
<tab name="uart.h"><source lang="c++" style="background: LightYellow;">
/* ************************************************************************* */
 
/* FileName          : serial.h                                             */
 
/* ************************************************************************* */
 
        void inituart( void );
 
        void sendchar( unsigned char );
 
unsigned char recchar( void );
 
</source>
 
 
 
'''serial.c'''
 
<source lang="c">
 
 
/* ************************************************************************* */
 
/* ************************************************************************* */
/*                                                                          */
+
/* FileName          : uart.h                                             */
/* Description      : UART communication routines                          */
 
/*                    Based on AppNote AVR109 - Self-programming            */
 
/*                                                                          */
 
/* FileName          : serial.c                                             */
 
/*                                                                          */
 
 
/* ************************************************************************* */
 
/* ************************************************************************* */
  
#include <avr\io.h>
+
void uart_init( void );
 
+
      
// Following calculation assumes that F_CPU is assigned in 'Project/Options'
+
void uart_putc( char c );
#define BAUDRATE      9600      
+
void uart_puts( const char *s );
#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)
 
 
 
 
 
/* definitions for UART control */     
 
                                        // Valid for ATmega328
 
#define BAUD_RATE_REG         UBRR0  //
 
#define UART_STATUS_REG UCSR0A  // OK, checked (but also control reg.)
 
#define UART_CONTROL_REG_B UCSR0B  // OK, checked
 
#define UART_CONTROL_REG_C      UCSR0C  // Added for mode setting
 
#define ENABLE_TRANSMITTER_BIT TXEN0  // OK, checked
 
#define ENABLE_RECEIVER_BIT RXEN0  // OK, checked
 
#define DATA_REGISTER_EMPTY_BIT UDRE0  // Added, for possible speed-up
 
#define TRANSMIT_COMPLETE_BIT TXC0    // OK, checked
 
#define RECEIVE_COMPLETE_BIT RXC0    // OK, checked
 
#define UART_DATA_REG UDR0    // OK, checked
 
  
 +
char uart_getc( void );
 +
</source></tab>
 +
<tab name="uart.c"><source lang="c++" style="background: LightYellow;">
 +
#include <avr/io.h>
 +
#include <util/setbaud.h>
  
void inituart(void)
+
void uart_init( void )  
 
{
 
{
BAUD_RATE_REG = (unsigned char)BAUD_PRESCALE;   // Set baud rate: Load the UBRR register
+
    UBRR0H = UBRRH_VALUE;
 +
    UBRR0L = UBRRL_VALUE;
  
UART_CONTROL_REG_B = (1 << ENABLE_RECEIVER_BIT)|
+
#if USE_2X
                    (1 << ENABLE_TRANSMITTER_BIT); // Enable receive + transmit
+
    UCSR0A |= _BV(U2X0);
 +
#else
 +
    UCSR0A &= ~(_BV(U2X0));
 +
#endif
  
UART_CONTROL_REG_C = (3<<UCSZ00);                 // Added: Async. UART, None
+
    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
                                                  // Parity, 8-data, 1 stopbit
+
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);  /* Enable RX and TX */
                                                 
 
 
}
 
}
  
  
void sendchar(unsigned char c)
+
void uart_putc(char c)  
 
{
 
{
  UART_DATA_REG = c;                                   // prepare transmission
+
  if (c == '\n')
  while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT)));// wait until byte sendt
+
    {
  UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT);         // delete TXCflag
+
      uart_putc('\r');
 +
    }
 +
  loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
 +
  UDR0 = c;
 
}
 
}
  
  
unsigned char recchar(void)
+
void uart_puts(const char *s)
 
{
 
{
   while( !(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT)) );  // wait for data
+
   /* toto je vasa uloha */
  return UART_DATA_REG;
 
 
}
 
}
</source>
 
  
Testovací program:
+
char uart_getc(void) {
 +
    loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
 +
    return UDR0;
 +
}
  
'''main.c'''
 
<source lang="c">
 
#include <avr\io.h>
 
#include "serial.h"              // Nasa kniznica...
 
  
int main(void)
+
</source></tab>
{
+
<tab name="demo.c"><source lang="c++" style="background: LightYellow;">
char c;
+
#define BAUD 9600
  
  DDRD = 0b00000010;
+
#include <avr/io.h>
PORTD = 0b00000011;    // Set TxD pin as an output, RxD input
+
#include "uart.h"
 
inituart();
 
  
sendchar('O');
+
                             
sendchar('K');
+
int main(void)
sendchar('\n');
+
{
 +
  char ReceivedChar;
  
for (c=32;c<=127;c++)
+
  uart_init();
  sendchar(c);
 
  
for (;;) {
+
  while(1)
    /* Do nothing */
+
  {
          }
+
    ReceivedChar = uart_getc();                              // Fetch the recieved byte (blocking command!)
 +
    uart_putc(ReceivedChar+1);
 +
    }
 +
  return(0);
 
}
 
}
</source>
+
</source></tab>
 
+
</tabs>
 
 
  
 
== <TT>printf()</TT> na jednočipe? ==
 
== <TT>printf()</TT> na jednočipe? ==
Riadok 182: Riadok 212:
 
#include <stdio.h>
 
#include <stdio.h>
  
FILE mystdout = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE);
+
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
                              // 'sendchar' je nova funkcia pre jeden znak
+
 
  
 
int main(void)
 
int main(void)
{  
+
{
inituart();               // Inicializacia seriovej linky
+
  uart_init();                 // Inicializacia seriovej linky
stdout = &mystdout;          // Odteraz funguje printf();
+
  stdout = &mystdout;          // Odteraz funguje printf();
  
 
  printf("Hello, world!");
 
  printf("Hello, world!");
 +
 
  return 0;
 
  return 0;
 
}
 
}
Riadok 196: Riadok 227:
  
 
Takto potom môžete používať naozaj aj funkciu printf() so všetkými jej vymoženosťami...
 
Takto potom môžete používať naozaj aj funkciu printf() so všetkými jej vymoženosťami...
Úplne rovnako sa dá implementovať printf() aj na LCD displej, len ho treba na začiatku zinicializovať a namiesto funkcie sendchar napísať niečo ako LCDsendchar().
+
Úplne rovnako sa dá implementovať printf() aj na LCD displej, len ho treba na začiatku zinicializovať a namiesto funkcie <code>uart_putc</code> napísať niečo ako <code>lcd_putc</code>.
  
 +
Kompletný vstup/výstup potom vyzerá takto:
  
Pozn.: pre MiniMEXLE - Prevod TTL úrovní na RS-232 je realizovaný takto -
+
<source lang="c">
[[Media:232Converter.png|schéma zapojenia]], ktorá vychádza z [http://www.kmitl.ac.th/~kswichit/ap275/ap275.htm tohoto návodu].
+
 
 +
FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
 +
FILE uart_input  = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ);
 +
 
 +
int main(void) {
  
 +
    uart_init();
 +
    stdout = &uart_output;
 +
    stdin = &uart_input;
 +
               
 +
    char input;
  
=== 3. Vizualizácia ===
+
    while(1) {
 +
        puts("Hello world!");
 +
        input = getchar();
 +
        printf("You wrote %c\n", input);
 +
    }
 +
       
 +
    return 0;
 +
}
 +
 
 +
</source>
 +
 
 +
 
 +
 
 +
 
 +
 
 +
=== '''Úloha''' ===
 +
 
 +
# Vyskúšajte si najjednoduchší prenos po sériovej linke.
 +
# Nainštalujte si na PC niektorý terminálový program.
 +
# Vytvorte si knižnicu uart.h
 +
# Napíšte program, ktorý bude meniť jas LED diódy pomocou kláves + a - na klávesnici počitača. Aktuálnu hodnotu PWM registra OCR zobrazte na termináli a prípadne aj na LCD displeji.
 +
# '''🡆 Úloha pre pokročilých:''' [[Sériové rozhranie a Processing]]
 +
 
 +
=== 4. Terminál ===
 +
 
 +
[[Súbor:SerialTerminal_VT100.jpg|right|300px]]
 +
 
 +
Terminál je jednoduché elektronické zariadenie, ktoré slúži na komunikáciu s počítačom. Vytvára tak vzdialené užívateľské rozhranie (angl. ''Human-Machine Interface'', HMI), cez ktoré je možné počítač ovládať, spúšťať programy, zadávať vstupné dáta (klávesnicou) a zobrazovať výstupy (na monitore). Zjednodušene si ho môžeme predstaviť, ako klávesnicu a monitor osobného počítača, pričom samotný počítač na ktorom pracujeme sa nachádza niekde inde - napr. aj v inej budove. Ku jednému takémuto počítaču je obvykle pripojených viacero terminálov (aj niekoľko desiatok). Pôvodné terminály boli znakové a pripájali sa k počítaču pomocou sériovej linky, telefónneho modemu, neskôr aj počítačovej siete. Neskôr vznikli aj grafické terminály, označované aj ako tenký klient (''thin client'').
 +
 
 +
Jedným z prvých (1978) sériovo vyrábaných terminálov bol typ VT100 ('''V'''ideo '''T'''erminal) spoločnosti Digital Equipment Corporation (DEC). Ako jeden z prvých podporoval tzv. ANSI sekvencie pre riadenie pohybu kurzora na obrazovke. V súčasnosti sa hardvérové terminály už prakticky nepoužívajú, jednoduchšie je využívať softvérové '''emulátory''', ktorých je k dispozícíí niekoľko desiatok (napr. PuTTY, xterm, konsole, Br@y Terminal a mnoho ďalších).
 +
 
 +
* [https://learn.sparkfun.com/tutorials/terminal-basics Podrobný prehľad a detaily...]
 +
 
 +
Na príjem a vysielanie znakov na strane PC máme k dispozícii niekoľko takýchto emulátorov (pozn. pre školské počítače: len niektoré z nich umožňujú spustenie pod Windows bez administrátorského oprávnenia - napr. Br@y Terminal). Jedným z najdôležitejších rozlišovacích znakov pre terminálové programy je možnosť rozdeliť okno na vysielacie a prijímacie alebo spoločné okno pre oba kanály.
 +
 
 +
 
 +
 
 +
=== Serial Terminal by Bray ===
 +
 
 +
[[Súbor:IconTerminal.png|left]] Na testovanie a prvé pokusy so sériovým rozhraním sa vám určite zíde aj nejaký terminálový program. Terminál je jednoduchý program, v ktorom sa zobrazujú všetky prijaté znaky a naopak, je možné nejaké iné znaky odvysielať. Dajú sa samozrejme aj nastaviť základné komunikačné parametre.
 +
 
 +
* [https://sites.google.com/site/terminalbpp/ Terminal by Bray++], neinštaluje sa, len spustí.
 +
* [http://senzor.robotika.sk/zp/Terminal.exe Terminal] -- lokálna kópia
 +
 
 +
 
 +
[[Súbor:TerminalExample.png]]
 +
 
 +
Ukážka práce s Terminalom vrátane správneho nastavenia parametrov. Prenosovú rýchlosť nastavte podľa skutočnosti, napr. 9600 Bd.
 +
V tomto programe je vysielacie a prijímacie okno rozdelené.
 +
 
 +
=== PuTTY ===
 +
 
 +
[[Súbor:IconPuTTY.png|left|63px]]  PuTTY is an SSH and telnet client, developed originally by Simon Tatham for the Windows platform. PuTTY is open source software that is available with source code and is developed and supported by a group of volunteers.
 +
 
 +
* [https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html PuTTY download].
 +
* [http://senzor.robotika.sk/zp/putty.exe Terminal] -- lokálna kópia
 +
* Video, ktoré vám pomôže integrovať PuTTY priamo do Atmel Studia.
 +
 
 +
[[Súbor:PuTTYExample.png]]
 +
 
 +
Ukážka práce s programom PuTTY vrátane správneho nastavenia parametrov. Prenosovú rýchlosť nastavte podľa skutočnosti, napr. 9600 Bd.
 +
V tomto programe je vysielacie a prijímacie okno spojené do jedného. Na prvý pohľad to môže vyzerať neprehľadne, ale zasa rozumie ANSI sekvenciám terminálu VT100, takže sa tu dá pekne formátovať výstup.
 +
 
 +
=== Núdzové riešenie I: Arduino ===
 +
 
 +
Aj programové prostredie Arduino má v sebe zabudovaný jednoduchý sériový terminál.ň
 +
 
 +
 
 +
[[Súbor:ArduinoSerialTerminalWindow.png]]
 +
 
 +
=== Núdzové riešenie II: cmd.exe ===
 +
 
 +
V núdzi vám možno pomôže aj obyčajný príkazový riadok. Takto ho prepneme do režimu, v ktorom bude prijímať znaky zo sériovej linky:
 +
 
 +
<source lang="bat">
 +
mode com5: baud=9600 parity=None data=8 stop=1
 +
 
 +
copy com5 con:
 +
 
 +
</source>
 +
 
 +
Režim sa ukončí Ctrl+Z alebo Ctrl+C.
 +
 
 +
Poslať pár znakov z príkazového riadku sa dá takto:
 +
 
 +
<source lang="bat">
 +
echo X > com5
 +
</source>
 +
 
 +
Pre čísla portov nad 9 treba použiť <code>\\.\COM22</code>
 +
 
 +
Žiaľ, nepoznám spôsob, ako uskutočniť prenos oboma smermi.
 +
 
 +
 
 +
 
 +
=== 5. Vizualizácia ===
  
 
Vizualizáciu dát môžeme robiť rozlične. Jeden z možných spôsobov je vypisovať
 
Vizualizáciu dát môžeme robiť rozlične. Jeden z možných spôsobov je vypisovať
Riadok 209: Riadok 345:
 
maticu do Matlabu a tam nakresliť graf, priebeh, čo treba...
 
maticu do Matlabu a tam nakresliť graf, priebeh, čo treba...
  
 +
<!--
 +
<S>
 
Iná možnosť je použiť napr. program StampPlot, ktorý kreslí prichádzajúce data
 
Iná možnosť je použiť napr. program StampPlot, ktorý kreslí prichádzajúce data
 
priamo ako graf, s výnimkou reťazcov, ktoré začínajú znakom '!', tie považuje za
 
priamo ako graf, s výnimkou reťazcov, ktoré začínajú znakom '!', tie považuje za
 
konfiguračné príkazy.  
 
konfiguračné príkazy.  
 +
* Download: [http://www.parallax.com/Portals/0/Downloads/sw/spl.zip StampPlotLite1.7]
 +
* Príklad: [[AVR StampPlotExample.c]]
 +
* Manual: [[Stamp Plot Manual]]
 +
</S>
 +
-->
  
Download: [http://www.selmaware.com/stampplotlite/StampPlotLite_V17.zip StampPlotLite1.7]
+
=== Serial Plotter ===
  
Príklad: [[AVR StampPlotExample.c]]
+
[[Súbor:IconSerialPlotter.png|left]] Serial Plotter je trocha sofistikovanejší program ako Terminal, jeho úlohou je zakresliť graficky všetky prijaté informácie. Najjednoduchšie je posielať mu čísla, pričom ich môže byť aj viac, oddelených čiarkami. Každá jedna n-tica hodnôt musí končíť znakom pre nový riadok. V knižnici Serial použite bloky Serial Write Number pre čísla, Serial Write String pre čiarky a Serial Write Line pre ukončenie riadka. Neposielajte hodnoty príliš často, aby sa nepreplnil vstupný buffer.
Manual: [[Stamp Plot Manual]]
+
* [https://hackaday.io/project/5334-serialplot-realtime-plotting-software Domovská stránka programu]
 +
* [http://senzor.robotika.sk/zp/serialplot.zip Lokálna kópia]
  
 +
<BR><BR>
  
 +
[[Súbor:SerialPlotter01.png]]
 +
 +
 +
=== Serial Studio ===
 +
 +
[[Súbor:IconSerialConsole.png|68px|left]] Serial Console je ešte sofistikovanejší program ako Serial Plotter, dokážeme s ním vytvárať rozličné panely s údajmi zoskupenými do rozličných skupín a s možnosťou grafického záznamu, použitia rozličných virtuálnych prístrojov a jednoduchou konfiguráciou.
 +
 +
* [https://www.alex-spataru.com/blog/introducing-serial-studio Stručný úvod k programu]
 +
* [https://github.com/Serial-Studio/Serial-Studio/wiki/Basic-usage-of-Serial-Studio GitHub so zdrojákmi aj podrobným opisom protokolu]
 +
 +
<BR><BR>
 +
 +
[[Súbor:SerialStudio01.png]][[Súbor:SerialStudio02.png]]
  
  
Riadok 226: Riadok 384:
 
[[Obrázok:Icon_Terminal.png]] [http://braypp.googlepages.com/Terminal20080315.zip Terminal 1.9b]
 
[[Obrázok:Icon_Terminal.png]] [http://braypp.googlepages.com/Terminal20080315.zip Terminal 1.9b]
  
[[Obrázok:Icon_StampPlotLite.png]] [http://www.selmaware.com/stampplotlite/StampPlotLite_V17.zip StampPlot Lite 1.7]
+
[[Obrázok:IconPuTTY.png|40px]] [https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html PuTTY latest]
 +
 
 +
[[Súbor:IconSerialPlotter.png|40px]] [https://serialplot.ozderya.net/downloads/serialplot-0.11.0-win32.exe Serial Plot 0.1.11]
 +
 
 +
[[Súbor:IconSerialConsole.png|40px]] [https://github.com/Serial-Studio/Serial-Studio/releases/ Serial Studio 1.0.12]
 +
 
  
  
  
  
 +
[[Mikropočítačové systémy (MIPS)#Cvičenia|Návrat na zoznam cvičení...]]
  
  
[[Category:AVR]][[Category:MMP]][[Category:DVPS]]
+
[[Category:AVR]][[Category:MIPS]][[Category:MMP]][[Category:DVPS]]

Verzia zo dňa a času 07:20, 8. apríl 2021


Sériové komunikačné rozhranie (UART)

Úlohy

  1. Nakonfigurujte USART na asynchrónnu prevádzku s parametrami N,9600,8,1
  2. Vyskúšajte demonštračný program, na strane PC použite terminál
  3. Vytvorte si knižnice pre prácu so sériovou linkou, preštudujte využitie knižnice <stdio.h> a demonštrujte.
  4. Napíšte program, ktorý klávesami +/- bude meniť jas LED diódy.


Literatúra:

2021




1. Hardvér

Podrobnejší popis hardvéru pre sériové komunikačné rozhranie presahuje rámec tohoto cvičenia, záujemcov odkazujeme na text Normy pre fyzickú vrstvu komunikačných rozhraní.

Pripomenieme na tomto mieste len skutočnosť, že prepojenie cez sériové rozhranie sa môže uskutočniť buď priamo v TTL (resp. CMOS) logických úrovniach 5V, napríklad takto sa dajú prepojiť dve Arduino dosky medzi sebou

MIPS Arduino-ArduinoCOM.png
Schéma prepojenia dvoch Arduino dosiek.

Iným príkladom je LCD displej so sériovým prevodníkom, ktorý potrebuje na pripojenie len 3 (2) vodiče.

Ak by sme riešili pripojenie zariadenia, ktoré má skutočne rozhranie RS-232, t.j. napäťové úrovne +/-10V, potrebujeme prevodník, ktorý z TTL úrovne vyrobí príslušné napätia. Typickým zástupcom širokého spektra takýchto prevodníkov je obvod MAX232 (Maxim Integrated), ktorý obsahuje malý spínaný menič, takže potrebné napätia +/-10V si vyrobí priamo na čipe z jedného napájacieho napätia 5V. Typická schéma zapojenia je na obrázku nižšie.

MIPS SerialMAX232.png
Schéma prevodníka na úrovne RS-232.


Arduino nepoužíva pre komunikáciu s PC ani jeden z vyššieuvedených spôsobov, ale pripája sa na zbernicu USB (Universal Serial Bus). Na to je tiež potrebný špeciálny prevodník. Pri prvých verziách Arduino dosky sa používal špeciálny itegrovaný obvod FT232RL (FTDI Chips), v lacných klonoch sa menej spoľahlivá kópia CH340G, neskôr sa rozhranie USB zrealizovalo pomocou špecializovaného mikroprocesora Atmel ATmega16U2, ktorý má potrebné rozhranie už integrované. Ako to funguje sa dá pozrieť na schéme zapojenia.



2. Základný princíp prenosu cez USART

Ukážkový program v ktorom je všetko pohromade: inicializácia, príjem aj vysielanie. Program čaká na prijatý znak a vráti znak s ASCII kódom o jedna väčším. Mohol by vrátiť aj rovnaký, ale to by sme nevedeli rozlíšiť od funkcie "local echo" v niektorých termináloch.

#include <avr/io.h>

#define BAUDRATE       9600
#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)  // vzorček z datasheetu


int main (void)
{
   char ReceivedChar;

   /* Initialize UART */
                                                         
   UBRR0 = (unsigned char)BAUD_PRESCALE;                 // Set baud rate: Load the UBRR register

   UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);                     // Set format: 8data, 1stop bit 

   UCSR0B = (1 << RXEN0) | (1 << TXEN0);                 // Enable receiver and transmitter


   for (;;)                                              // Loop forever
   {
      while ((UCSR0A & (1 << RXC0)) == 0)                // Wait for data to be received 
	  {
	    // Do nothing until data have been recieved and is ready to be read from UDR
	  }; 
      ReceivedChar = UDR0;                               // Fetch the recieved byte 

   
      while ( !( UCSR0A & (1<<UDRE0)) )                  // Wait for empty transmit buffer 
   	  {
	   // Do nothing until UDR is ready for more data to be written to it
	  };
      UDR0 = ReceivedChar+1;                             // Echo back the modified received byte 
   }


}


Ak vám program fungoval, nahrajte ho do procesora a otestujte komunikáciu s terminálom. Na prácu so sériovou linkou na vašom PC odporúčame program Terminal by Bray, ale môžete to skúsiť aj s Hyperterminálom.


Väčšina parametrov je vždy rovnaká (8 bitov, bez parity, 1 stop bit), meniť sa zvykne len rýchlosť. Treba však upozorniť, že pre spoľahlivý asynchrónny prenos by sa nemali hodiny vysielača a prijímača líšiť o viac ako 2%. To sa dá dosiahnuť veľmi jednoducho pre špeciálne hodnoty oscilátora (napr. kryštál 18,432 MHz), ale pre nami používaný oscilátor 16 MHz sú niektoré rýchlosti menej vhodné.

MIPS UARTspeedTavle.png
Tabuľka s prensovými rýchlosťami pre 16 MHz.

3. Jednoduchá knižnica

Nebudeme sa zaoberať detailmi implementácie sériového komunikačného rozhrania procesorov AVR, pre naše účely postačí jednoduchá knižnica, ktorá obsahuje základné funkcie na prenos jedného znaku. Parametre prenosu pre túto knižnicu sú 9600,n,8,1.

/* ************************************************************************* */
/* FileName          : uart.h                                              */
/* ************************************************************************* */

void uart_init( void );
     
void uart_putc( char c );
void uart_puts( const char *s );

char uart_getc( void );
#include <avr/io.h>
#include <util/setbaud.h>

void uart_init( void ) 
{
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;

#if USE_2X
    UCSR0A |= _BV(U2X0);
#else
    UCSR0A &= ~(_BV(U2X0));
#endif

    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);   /* Enable RX and TX */
}


void uart_putc(char c) 
{
   if (c == '\n') 
    {
       uart_putc('\r');
    }
   loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
   UDR0 = c;
}


void uart_puts(const char *s)
{
  /* toto je vasa uloha */
}

char uart_getc(void) {
    loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
    return UDR0;
}
#define BAUD 9600

#include <avr/io.h>
#include "uart.h"

                              
int main(void)
{
  char ReceivedChar;

  uart_init();

  while(1)
  {
    ReceivedChar = uart_getc();                               // Fetch the recieved byte (blocking command!)
    uart_putc(ReceivedChar+1);
    }
  return(0);
}

printf() na jednočipe?

Ak si napíšete vlastnú funkciu na zobrazenie jedného znaku na displej, alebo pre vyslanie jedného znaku po sériovej linke, potom môžete používať naozaj aj funkciu printf so všetkými jej vymoženosťami. Využívame pre tom knižnicu stdio.h, ktorá sa používa takto:

...
#include <stdio.h>

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


int main(void)
{
  uart_init();                  // Inicializacia seriovej linky
  stdout = &mystdout;           // Odteraz funguje printf();

 printf("Hello, world!");

 return 0;
}

Takto potom môžete používať naozaj aj funkciu printf() so všetkými jej vymoženosťami... Úplne rovnako sa dá implementovať printf() aj na LCD displej, len ho treba na začiatku zinicializovať a namiesto funkcie uart_putc napísať niečo ako lcd_putc.

Kompletný vstup/výstup potom vyzerá takto:

FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
FILE uart_input  = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ);

int main(void) {

    uart_init();
    stdout = &uart_output;
    stdin = &uart_input;
                
    char input;

    while(1) {
        puts("Hello world!");
        input = getchar();
        printf("You wrote %c\n", input);
    }
        
    return 0;
}



Úloha

  1. Vyskúšajte si najjednoduchší prenos po sériovej linke.
  2. Nainštalujte si na PC niektorý terminálový program.
  3. Vytvorte si knižnicu uart.h
  4. Napíšte program, ktorý bude meniť jas LED diódy pomocou kláves + a - na klávesnici počitača. Aktuálnu hodnotu PWM registra OCR zobrazte na termináli a prípadne aj na LCD displeji.
  5. 🡆 Úloha pre pokročilých: Sériové rozhranie a Processing

4. Terminál

SerialTerminal VT100.jpg

Terminál je jednoduché elektronické zariadenie, ktoré slúži na komunikáciu s počítačom. Vytvára tak vzdialené užívateľské rozhranie (angl. Human-Machine Interface, HMI), cez ktoré je možné počítač ovládať, spúšťať programy, zadávať vstupné dáta (klávesnicou) a zobrazovať výstupy (na monitore). Zjednodušene si ho môžeme predstaviť, ako klávesnicu a monitor osobného počítača, pričom samotný počítač na ktorom pracujeme sa nachádza niekde inde - napr. aj v inej budove. Ku jednému takémuto počítaču je obvykle pripojených viacero terminálov (aj niekoľko desiatok). Pôvodné terminály boli znakové a pripájali sa k počítaču pomocou sériovej linky, telefónneho modemu, neskôr aj počítačovej siete. Neskôr vznikli aj grafické terminály, označované aj ako tenký klient (thin client).

Jedným z prvých (1978) sériovo vyrábaných terminálov bol typ VT100 (Video Terminal) spoločnosti Digital Equipment Corporation (DEC). Ako jeden z prvých podporoval tzv. ANSI sekvencie pre riadenie pohybu kurzora na obrazovke. V súčasnosti sa hardvérové terminály už prakticky nepoužívajú, jednoduchšie je využívať softvérové emulátory, ktorých je k dispozícíí niekoľko desiatok (napr. PuTTY, xterm, konsole, Br@y Terminal a mnoho ďalších).

Na príjem a vysielanie znakov na strane PC máme k dispozícii niekoľko takýchto emulátorov (pozn. pre školské počítače: len niektoré z nich umožňujú spustenie pod Windows bez administrátorského oprávnenia - napr. Br@y Terminal). Jedným z najdôležitejších rozlišovacích znakov pre terminálové programy je možnosť rozdeliť okno na vysielacie a prijímacie alebo spoločné okno pre oba kanály.


Serial Terminal by Bray

IconTerminal.png
Na testovanie a prvé pokusy so sériovým rozhraním sa vám určite zíde aj nejaký terminálový program. Terminál je jednoduchý program, v ktorom sa zobrazujú všetky prijaté znaky a naopak, je možné nejaké iné znaky odvysielať. Dajú sa samozrejme aj nastaviť základné komunikačné parametre.


TerminalExample.png

Ukážka práce s Terminalom vrátane správneho nastavenia parametrov. Prenosovú rýchlosť nastavte podľa skutočnosti, napr. 9600 Bd. V tomto programe je vysielacie a prijímacie okno rozdelené.

PuTTY

IconPuTTY.png
PuTTY is an SSH and telnet client, developed originally by Simon Tatham for the Windows platform. PuTTY is open source software that is available with source code and is developed and supported by a group of volunteers.
  • PuTTY download.
  • Terminal -- lokálna kópia
  • Video, ktoré vám pomôže integrovať PuTTY priamo do Atmel Studia.

PuTTYExample.png

Ukážka práce s programom PuTTY vrátane správneho nastavenia parametrov. Prenosovú rýchlosť nastavte podľa skutočnosti, napr. 9600 Bd. V tomto programe je vysielacie a prijímacie okno spojené do jedného. Na prvý pohľad to môže vyzerať neprehľadne, ale zasa rozumie ANSI sekvenciám terminálu VT100, takže sa tu dá pekne formátovať výstup.

Núdzové riešenie I: Arduino

Aj programové prostredie Arduino má v sebe zabudovaný jednoduchý sériový terminál.ň


ArduinoSerialTerminalWindow.png

Núdzové riešenie II: cmd.exe

V núdzi vám možno pomôže aj obyčajný príkazový riadok. Takto ho prepneme do režimu, v ktorom bude prijímať znaky zo sériovej linky:

mode com5: baud=9600 parity=None data=8 stop=1

copy com5 con:

Režim sa ukončí Ctrl+Z alebo Ctrl+C.

Poslať pár znakov z príkazového riadku sa dá takto:

echo X > com5

Pre čísla portov nad 9 treba použiť \\.\COM22

Žiaľ, nepoznám spôsob, ako uskutočniť prenos oboma smermi.


5. Vizualizácia

Vizualizáciu dát môžeme robiť rozlične. Jeden z možných spôsobov je vypisovať po sériovej linke v pravidelných intervaloch holé data a tie potom uložiť ako maticu do Matlabu a tam nakresliť graf, priebeh, čo treba...


Serial Plotter

IconSerialPlotter.png
Serial Plotter je trocha sofistikovanejší program ako Terminal, jeho úlohou je zakresliť graficky všetky prijaté informácie. Najjednoduchšie je posielať mu čísla, pričom ich môže byť aj viac, oddelených čiarkami. Každá jedna n-tica hodnôt musí končíť znakom pre nový riadok. V knižnici Serial použite bloky Serial Write Number pre čísla, Serial Write String pre čiarky a Serial Write Line pre ukončenie riadka. Neposielajte hodnoty príliš často, aby sa nepreplnil vstupný buffer.



SerialPlotter01.png


Serial Studio

IconSerialConsole.png
Serial Console je ešte sofistikovanejší program ako Serial Plotter, dokážeme s ním vytvárať rozličné panely s údajmi zoskupenými do rozličných skupín a s možnosťou grafického záznamu, použitia rozličných virtuálnych prístrojov a jednoduchou konfiguráciou.



SerialStudio01.pngSerialStudio02.png


Download

Icon Terminal.png Terminal 1.9b

IconPuTTY.png PuTTY latest

IconSerialPlotter.png Serial Plot 0.1.11

IconSerialConsole.png Serial Studio 1.0.12



Návrat na zoznam cvičení...