@@ -2,12 +2,14 @@
# include <avr/interrupt.h>
# include <stdint.h>
# include <string.h>
# include "timer.h"
# include "circular_buf.h"
# include "uart.h"
struct circular_buffer uartRxBuffer ;
struct circular_buffer uartTxBuffer ;
void UART_init ( void ) {
UCSR0B = ( 1 < < RXEN0 ) | ( 1 < < TXEN0 ) | ( 1 < < RXCIE0 ) | ( 1 < < UDRIE0 ) ; // прерывание по приему и опустошению буфера передачи
UCSR0B = ( 1 < < RXEN0 ) | ( 1 < < TXEN0 ) | ( 1 < < RXCIE0 ) | ( 1 < < TXCIE0 ) | ( 1 < < UDRIE0 ) ; // прерывание по приему и передаче
UCSR0C = ( 1 < < UCSZ01 ) | ( 1 < < UCSZ00 ) ;
UBRR0H = 0 ;
UBRR0L = 103 ;
@@ -15,50 +17,45 @@ void UART_init(void) {
void UART_send ( uint8_t * data , size_t length ) {
for ( size_t i = 0 ; i < length ; i + + ) {
if ( ! buffer_full ( & usartTxBuffer ) ) {
write_buffer ( & usartTxBuffer , data [ i ] ) ;
if ( ! buffer_full ( & uartTxBuffer ) ) {
write_buffer ( & uartTxBuffer , data [ i ] ) ;
} else {
break ; // если буфер передачи заполнен, то отправка прерывается
}
}
UCSR0B | = ( 1 < < UDRIE0 ) ; // В ключаем прерывание по опустошению буфера
UCSR0B | = ( 1 < < TXCIE0 ) ; // в ключаем прерывание по завершении передачи
}
// Получение данных из буфера
int UART_receive ( uint8_t * data , size_t length ) {
char overflow = 0 ; // Флаг переполнения, который устанавливается, если превышен размер массива
uint32_t byteCount = 0 ; // Счетчик байтов, принятых из буфера приема
uint32_t timeout_ms = 4 ; // Таймаут в миллисекундах для общего времени приема данных
uint32_t start_time = millis ( ) ;
//Цикл приема данных с таймаутом
while ( 1 )
{
// Пока буфер приема не пуст и не истек таймаут общего времени,
// Пока буфер приема не пуст и не превышен лимит длины массива,
// функция продолжает читать байты из буфера и сохранять их в массив data.
while ( ! buffer_empty ( & usartRxBuffer ) ) {
int reader = read_buffer ( & usartRxBuffer ) ; //п рием и запись символа в переменную
if ( byteCount < = length ) {
data [ byteCount ] = reader ; // запись в массив с индексом byteCount
while ( ! buffer_empty ( & uartRxBuffer ) & & byteCount < length ) {
int reader = read_buffer ( & uartRxBuffer ) ; // П рием и запись символа в переменную
data [ byteCount ] = reader ; // Запись в массив с индексом byteCount
byteCount + + ;
}
else {
// Проверка переполнения
if ( byteCount > length ) {
overflow = 1 ;
}
byteCount + + ;
start_time = millis ( ) ;
}
if ( ( millis ( ) - start_time ) > timeout_ms ) { // если превышение времени в 4 ms
break ;
}
}
return overflow ? - 1 : byteCount ; // возвращает количество успешно принятых байт или -1
return overflow ? - 1 : byteCount ; // Возвращает количество успешно принятых байт или -1 в случае переполнения
}
// прерывание по завершению приема
ISR ( USART_RX_vect ) {
uint8_t data = UDR0 ; // читаем из регистра UDR0
if ( ! buffer_full ( & usartRxBuffer ) ) {
write_buffer ( & usartRxBuffer , data ) ; // записываем символ в буфер приема
if ( ! buffer_full ( & uartRxBuffer ) ) {
write_buffer ( & uartRxBuffer , data ) ; // записываем символ в буфер приема
}
}
ISR ( USART_TX_vect ) {
if ( ! buffer_empty ( & uartTxBuffer ) ) {
UDR0 = read_buffer ( & uartTxBuffer ) ;
} else {
UCSR0B & = ~ ( 1 < < TXCIE0 ) ; // отключаем прерывание, когда все данные отправлены
}
}