Skip to content

Commit ef870c0

Browse files
Implementazione libreria UART con I/O avanzato
Questo commit aggiunge una libreria completa per la comunicazione seriale UART su STM32. Funzionalità principali: - Funzioni di output simili a printf (serial_printf, serial_printfln) - Input con supporto per editing di linea (backspace, gestione terminale) - Funzioni di input formattato simili a scanf - Comandi di controllo del terminale (clear screen) Tutti i file sono ampiamente documentati con commenti in stile Doxygen.
1 parent 95d57af commit ef870c0

2 files changed

Lines changed: 303 additions & 0 deletions

File tree

serial.c

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/**
2+
* @file serial.c
3+
* @brief Implementazione delle funzioni di I/O tramite UART per STM32.
4+
*
5+
* Questo file contiene l'implementazione delle funzioni necessarie per
6+
* leggere e scrivere dati tramite UART, inclusi la lettura di righe,
7+
* l'invio di stringhe e la gestione del formato di input.
8+
*/
9+
10+
#include "serial.h"
11+
12+
/**
13+
* @brief Stampa una stringa su UART
14+
*
15+
* Questa funzione invia una stringa tramite UART, senza aggiungere newline.
16+
*
17+
* @param message Stringa da stampare
18+
*/
19+
void serial_print(char *message) {
20+
// Utilizza la funzione HAL_UART_Transmit per inviare i caratteri della stringa
21+
// attraverso la UART, considerando la lunghezza calcolata con strlen().
22+
HAL_UART_Transmit(&hlpuart1, (uint8_t*) message, strlen(message),
23+
HAL_MAX_DELAY);
24+
}
25+
26+
/**
27+
* @brief Stampa una nuova riga su UART ("\r\n")
28+
*
29+
* Invia un carattere di ritorno a capo seguito da newline, simile alla
30+
* stampa di una nuova riga in un terminale.
31+
*/
32+
void serial_newline(void) {
33+
// Utilizza la funzione serial_print per inviare i caratteri di ritorno a capo e newline.
34+
serial_print("\r\n");
35+
}
36+
37+
/**
38+
* @brief Stampa una stringa seguita da una nuova riga
39+
*
40+
* Questa funzione invia una stringa tramite UART, seguita automaticamente
41+
* da un ritorno a capo (`\r\n`).
42+
*
43+
* @param message Stringa da stampare
44+
*/
45+
void serial_println(char *message) {
46+
// Stampa la stringa fornita utilizzando serial_print.
47+
serial_print(message);
48+
49+
// Aggiunge una nuova riga alla fine della stringa.
50+
serial_newline();
51+
}
52+
53+
/**
54+
* @brief Stampa una stringa formattata su UART (come printf)
55+
*
56+
* Questa funzione invia una stringa formattata tramite UART, simile
57+
* alla funzione `printf`.
58+
*
59+
* @param format Formato della stringa
60+
* @param ... Argomenti da formattare
61+
* @return Numero di caratteri scritti
62+
*/
63+
int serial_printf(const char *format, ...) {
64+
char buffer[256];
65+
66+
va_list args;
67+
68+
// Inizializza la lista degli argomenti variabili.
69+
va_start(args, format);
70+
71+
// Scrive la stringa formattata nel buffer utilizzando vsnprintf.
72+
int ret = vsnprintf(buffer, sizeof(buffer), format, args);
73+
74+
// Termina la gestione degli argomenti variabili.
75+
va_end(args);
76+
77+
// Trasmette la stringa formattata tramite UART.
78+
serial_print(buffer);
79+
80+
// Restituisce il numero di caratteri scritti.
81+
return ret;
82+
}
83+
84+
/**
85+
* @brief Stampa una stringa formattata seguita da una nuova riga
86+
*
87+
* Questa funzione invia una stringa formattata tramite UART, seguita
88+
* automaticamente da un ritorno a capo (`\r\n`), simile a `printf`.
89+
*
90+
* @param format Formato della stringa
91+
* @param ... Argomenti da formattare
92+
* @return Numero di caratteri scritti
93+
*/
94+
int serial_printfln(const char *format, ...) {
95+
char buffer[256];
96+
97+
va_list args;
98+
99+
// Inizializza la lista degli argomenti variabili.
100+
va_start(args, format);
101+
102+
// Scrive la stringa formattata nel buffer utilizzando vsnprintf.
103+
int ret = vsnprintf(buffer, sizeof(buffer), format, args);
104+
105+
// Termina la gestione degli argomenti variabili.
106+
va_end(args);
107+
108+
// Trasmette la stringa formattata tramite UART.
109+
serial_print(buffer);
110+
111+
// Aggiunge una nuova riga alla fine della stringa trasmessa.
112+
serial_newline();
113+
114+
// Restituisce il numero di caratteri scritti.
115+
return ret;
116+
}
117+
118+
/**
119+
* @brief Legge una riga da UART con supporto a frecce sinistra/destra e backspace
120+
*
121+
* Questa funzione permette la lettura di una riga con un buffer di input,
122+
* supportando la gestione del backspace per rimuovere i caratteri e
123+
* la gestione di un terminale che simula il comportamento di frecce sinistra e destra.
124+
*
125+
* @param buffer Buffer dove salvare la stringa
126+
* @param length Lunghezza massima del buffer (incluso null terminator)
127+
*/
128+
void serial_readline(char *buffer, int length) {
129+
size_t i = 0;
130+
131+
// Itera fino a riempire il buffer o fino a rilevare un carattere di terminazione
132+
while (i < length - 1) {
133+
uint8_t c;
134+
135+
// Riceve un carattere dalla UART con un timeout massimo
136+
if (HAL_UART_Receive(&hlpuart1, &c, 1, HAL_MAX_DELAY) == HAL_OK) {
137+
// Se il carattere ricevuto è '\r' o '\n', termina la stringa
138+
if (c == '\r' || c == '\n') {
139+
buffer[i] = '\0'; // Aggiunge terminatore di stringa
140+
serial_print("\r\n"); // Stampa ritorno a capo
141+
break;
142+
}
143+
// Gestisce il backspace (127 o 8)
144+
else if (c == 127 || c == 8) {
145+
if (i > 0) {
146+
i--; // Rimuove l'ultimo carattere
147+
serial_print("\b \b"); // Emette sequenza per cancellare il carattere
148+
}
149+
}
150+
// Gestisce caratteri normali
151+
else {
152+
buffer[i++] = c; // Aggiunge il carattere al buffer
153+
HAL_UART_Transmit(&hlpuart1, &c, 1, HAL_MAX_DELAY); // Echo del carattere
154+
}
155+
}
156+
}
157+
158+
buffer[i] = '\0'; // Termina la stringa con il carattere nullo
159+
}
160+
161+
/**
162+
* @brief Versione personalizzata di scanf che legge da UART
163+
*
164+
* Questa funzione legge una riga tramite `serial_readline()` e converte
165+
* il formato dell'input con `sscanf()`, simile a come farebbe `scanf()`.
166+
*
167+
* @param format Stringa di formato come in scanf
168+
* @param ... Argomenti variabili da riempire
169+
* @return Numero di elementi letti con successo
170+
*/
171+
int serial_scanf(const char *format, ...) {
172+
char buffer[128];
173+
174+
// Legge una riga di input dalla UART e la salva nel buffer.
175+
serial_readline(buffer, sizeof(buffer));
176+
177+
va_list args;
178+
179+
// Inizializza la lista di argomenti variabili.
180+
va_start(args, format);
181+
182+
// Usa sscanf per convertire il formato dell'input dal buffer in base ai parametri specificati.
183+
int ret = vsscanf(buffer, format, args);
184+
185+
// Termina la gestione degli argomenti variabili.
186+
va_end(args);
187+
188+
// Restituisce il numero di elementi letti con successo.
189+
return ret;
190+
}
191+
192+
/**
193+
* @brief Pulisce lo schermo del terminale
194+
*
195+
* Invia una sequenza di escape per pulire lo schermo del terminale
196+
* tramite UART, se supportato dal terminale stesso.
197+
*/
198+
void serial_clear(void) {
199+
// Invia una sequenza di escape ANSI tramite UART per pulire
200+
// lo schermo e riposizionare il cursore.
201+
serial_print("\033[2J\033[H");
202+
}

serial.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* @file serial.h
3+
* @brief Interfaccia per la gestione dell'I/O su UART con comportamento da terminale
4+
*
5+
* Questo file header fornisce le dichiarazioni delle funzioni per la stampa,
6+
* la lettura formattata e la gestione dell'input da UART con funzioni avanzate
7+
* di editing linea e visualizzazione simile a un terminale.
8+
*/
9+
10+
#ifndef INC_SERIAL_H_
11+
#define INC_SERIAL_H_
12+
13+
#include "usart.h"
14+
#include "string.h"
15+
#include "stdio.h"
16+
#include "stdarg.h"
17+
18+
/**
19+
* @brief Stampa una stringa su UART
20+
*
21+
* Questa funzione invia una stringa tramite UART, senza aggiungere newline.
22+
*
23+
* @param message Stringa da stampare
24+
*/
25+
void serial_print(char *message);
26+
27+
/**
28+
* @brief Stampa una nuova riga su UART ("\r\n")
29+
*
30+
* Invia un carattere di ritorno a capo seguito da newline, simile alla
31+
* stampa di una nuova riga in un terminale.
32+
*/
33+
void serial_newline(void);
34+
35+
/**
36+
* @brief Stampa una stringa seguita da una nuova riga
37+
*
38+
* Questa funzione invia una stringa tramite UART, seguita automaticamente
39+
* da un ritorno a capo (`\r\n`).
40+
*
41+
* @param message Stringa da stampare
42+
*/
43+
void serial_println(char *message);
44+
45+
/**
46+
* @brief Stampa una stringa formattata su UART (come printf)
47+
*
48+
* Questa funzione invia una stringa formattata tramite UART, simile
49+
* alla funzione `printf`.
50+
*
51+
* @param format Formato della stringa
52+
* @param ... Argomenti da formattare
53+
* @return Numero di caratteri scritti
54+
*/
55+
int serial_printf(const char *format, ...);
56+
57+
/**
58+
* @brief Stampa una stringa formattata seguita da una nuova riga
59+
*
60+
* Questa funzione invia una stringa formattata tramite UART, seguita
61+
* automaticamente da un ritorno a capo (`\r\n`), simile a `printf`.
62+
*
63+
* @param format Formato della stringa
64+
* @param ... Argomenti da formattare
65+
* @return Numero di caratteri scritti
66+
*/
67+
int serial_printfln(const char *format, ...);
68+
69+
/**
70+
* @brief Legge una riga da UART con supporto a frecce sinistra/destra e backspace
71+
*
72+
* Questa funzione permette la lettura di una riga con un buffer di input,
73+
* supportando la gestione del backspace per rimuovere i caratteri e
74+
* la gestione di un terminale che simula il comportamento di frecce sinistra e destra.
75+
*
76+
* @param buffer Buffer dove salvare la stringa
77+
* @param length Lunghezza massima del buffer (incluso null terminator)
78+
*/
79+
void serial_readline(char *buffer, int length);
80+
81+
/**
82+
* @brief Versione personalizzata di scanf che legge da UART
83+
*
84+
* Questa funzione legge una riga tramite `serial_readline()` e converte
85+
* il formato dell'input con `sscanf()`, simile a come farebbe `scanf()`.
86+
*
87+
* @param format Stringa di formato come in scanf
88+
* @param ... Argomenti variabili da riempire
89+
* @return Numero di elementi letti con successo
90+
*/
91+
int serial_scanf(const char *format, ...);
92+
93+
/**
94+
* @brief Pulisce lo schermo del terminale
95+
*
96+
* Invia una sequenza di escape per pulire lo schermo del terminale
97+
* tramite UART, se supportato dal terminale stesso.
98+
*/
99+
void serial_clear(void);
100+
101+
#endif /* INC_SERIAL_H_ */

0 commit comments

Comments
 (0)