Automatické nastavenie prenosovej rýchlosti: Rozdiel medzi revíziami
Zo stránky SensorWiki
Riadok 94: | Riadok 94: | ||
_delay_ms(200); | _delay_ms(200); | ||
opakovat: | |||
znak = uart_getc_timeout(1500); // Caka na vstup znaku 1.5 sekundy | |||
znak = | if(znak=='\r'){ | ||
goto opakovat; | |||
} | |||
if(znak=='\n'){ // Ocakavany znak je "Enter" | |||
if(znak==' | |||
najdeny = 1; | najdeny = 1; | ||
printf("Prenosova rychlost | printf("Komunikacia naviazana \n"); | ||
printf("Prenosova rychlost: Baud = %lu \n",baud_rychlost[baud_index]); | |||
break; | break; | ||
} | } |
Verzia z 10:46, 8. máj 2025
Záverečný projekt predmetu MIPS / LS2025 - Matúš Kráľ
Zadanie
Pri sériovej komunikácii musíme nastaviť niekoľko parametrov.: Prenosovú rýchlosť, počet dátových bitov, paritu a počet stop bitov. Vytvorte program, na automatické testovanie nastavenej prenosovej rýchlosti „druhej strany“ komunikačného kanála.

Literatúra:
Analýza a opis riešenia
Použité komponenty:
- Vývojová doska Arduino UNO (ATmega328P-PU, 16 MHz).
- UART prevodník integrovaný cez USB.
Link pre Datasheet ATmega328P: Datasheet ATmega328P
Zapojenie:
- UART prevodník bude zapojený do Arduina UNO a pomocou zapojeného prevodníka budeme môcť komunikovať s Arduinom.

Algoritmus a program
Popis funkčnosti programu:
1. Program inicializuje premennú "velkost" a do nej následne zapíše počet prvkov v poli "baud_rychlost".
2. inicializuje premenné "baud_index", "najdeny", "znak".
3. Následne program vojde do slučky a v slučke "for" bude robiť toľko cyklov, koľko je prvkov v poli "baud_rychlost". V našom prípade bude robiť 12 cyklov.
4. V slučke vyberie Baud rýchlosť podľa premennej "i" a inicializuje UART, a potom počká 200ms na ustálenie komunikácie.
5. Vypíše jeho očakávaný znak a následne čaka 2 sekundy na vstup znaku.
6. Keď príjme znak, tak potom overí, že či znak sa rovná 'a'. Ak do 2 sekúnd nedostane očakávaný znak, tak potom ide naspäť na začiatok slučky a nastaví novú Baud rýchlosť.
7. Ak príjme očakávaný znak, tak potom vypíše nájdenú Baud rýchlosť komunikácie, a následne program bude vypisovať prijímané znaky.
#define F_CPU 16000000UL
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"
FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ);
const unsigned long baud_rychlost[] = {
600,
1200,
2400,
4800,
9600,
14400,
19200,
28800,
38400,
56000,
57600,
115200
};
int main(void)
{
int velkost = sizeof(baud_rychlost)/sizeof(baud_rychlost[0]);
int baud_index = 0;
int najdeny = 0;
char znak;
while (1)
{
if(najdeny == 0){
for(int i=0; i<velkost; i++){
baud_index = i;
uart_init(baud_rychlost[i]);
stdout = &uart_output;
stdin = &uart_input;
_delay_ms(200);
opakovat:
znak = uart_getc_timeout(1500); // Caka na vstup znaku 1.5 sekundy
if(znak=='\r'){
goto opakovat;
}
if(znak=='\n'){ // Ocakavany znak je "Enter"
najdeny = 1;
printf("Komunikacia naviazana \n");
printf("Prenosova rychlost: Baud = %lu \n",baud_rychlost[baud_index]);
break;
}
}
}
else{
znak = uart_getc();
uart_putc(znak);
}
}
}
void uart_init( unsigned long baudrate );
void uart_putc( char c );
void uart_puts( const char *s );
char uart_getc( void );
int uart_getc_timeout(unsigned long timeout);
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
void uart_init(unsigned long baudrate)
{
uint16_t prescaler;
if (baudrate > 9600) {
UCSR0A |= (1 << U2X0);
_delay_ms(50);
prescaler = (F_CPU / (8UL * baudrate)) - 1;
} else {
UCSR0A &= ~(1 << U2X0);
_delay_ms(50);
prescaler = (F_CPU / (16UL * baudrate)) - 1;
}
UBRR0H = (uint8_t)(prescaler >> 8);
UBRR0L = (uint8_t)prescaler;
UCSR0B = (1 << TXEN0) | (1 << RXEN0); // povoliť TX a RX
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8 bitov, 1 stop, no parity
}
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)
{
while(*s!='\0')
{
uart_putc(*s++);
}
}
char uart_getc(void) {
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
return UDR0;
}
int uart_getc_timeout(unsigned long timeout) {
unsigned long cas = 0;
while(cas < timeout){
if (UCSR0A & (1 << RXC0)) // ak prišiel znak
{
return UDR0;
}
_delay_ms(1);
cas++;
}
return -1; // timeout
}
Zdrojový kód: zdrojaky.zip
Overenie
Program budeme overovať použitím Serial Terminalu:
- Arduino pripojíme do počítača pomocou UART prevodníka.
- V Serail Terminale nastavíme Data bits: 8, Parity: none, Stop bits: 1.
- Nastavíme si Baud rate v rozsahu od 600 do 115200.
- Serial Terminal prepojíme s Arduinom.
- Cez Serial Terminal budeme opakovane posielať očakávaný znak "Enter" do Arduina.
- Budeme neustále posielať znak "Enter" do momentu, keď nám Arduino neodpovie, že našiel hodnotu prenosovej rýchlosti.
- Následne môžme posielať ľubovoľné znaky do Arduina a bude nám odpovedať rovnakými znakmi.

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