Operácie

Automatické nastavenie prenosovej rýchlosti: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
 
(3 medziľahlé úpravy od rovnakého používateľa nie sú zobrazené.)
Riadok 94: Riadok 94:
_delay_ms(200);
_delay_ms(200);
uart_puts("\nOcakavany znak: a\n");
opakovat:
znak = uart_getc_timeout(1500); // Caka na vstup znaku 1.5 sekundy
znak = uart_getc_timeout(2000); // Caka na vstup znaku 2 sekundy
if(znak=='\r'){
goto opakovat;
}
printf("Ziskany znak: %c\n",znak);
if(znak=='\n'){ // Ocakavany znak je "Enter"
if(znak=='a'){ // Ocakavany znak je 'a'
najdeny = 1;
najdeny = 1;
printf("Prenosova rychlost najdena: Baud = %lu \n",baud_rychlost[baud_index]);
printf("Komunikacia naviazana \n");
printf("Prenosova rychlost: Baud = %lu \n",baud_rychlost[baud_index]);
break;
break;
}
}
Riadok 191: Riadok 193:
</tabs>
</tabs>


'''Zdrojový kód:''' [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
'''Zdrojový kód:''' [[Médiá:ProjektMatusKral.zip|ProjektMatusKral.zip]]


=== Overenie ===
=== Overenie ===
Riadok 212: Riadok 214:




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


[[Category:AVR]] [[Category:MIPS]]
[[Category:AVR]] [[Category:MIPS]]

Aktuálna revízia z 11:10, 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.


Vývojová doska Arduino UNO.

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.


Schéma zapojenia.


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: ProjektMatusKral.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.
Arduino UNO

Video: