Display_Avr_3/UART/uart.c
2024-01-17 16:11:54 +03:00

126 lines
4.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>
#include "timer.h"
#include "circular_buf.h"
#define F_CPU 16000000
struct circular_buffer usartTxBuffer;
struct circular_buffer usartRxBuffer;
void UART_init(void) {
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // прерывание по приему и опустошению буфера передачи
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
UBRR0H = 0;
UBRR0L = 103;
}
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]);
} else {
break; // если буфер передачи заполнен, то отправка прерывается
}
}
UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера
}
void UART_put_char(unsigned char sym) {
if (((UCSR0A & (1 << UDRE0)) != 0) && buffer_empty(&usartTxBuffer)) {
UDR0 = sym;
} else {
if (!buffer_full(&usartTxBuffer)) {
write_buffer(&usartTxBuffer, sym);
} else {
// Буфер передачи полон, обработка ошибки или другая логика
}
}
}
int UART_get_char(unsigned char* sym) {
if (!buffer_empty(&usartRxBuffer)) {
*sym = read_buffer(&usartRxBuffer);
return 1; // Символ успешно прочитан
} else {
return 0; // Буфер пуст, ошибка чтения
}
}
void UART_send_str(const unsigned char* data) {
while (*data) {
USART_put_char(*data++);
}
}
//uint32_t receivedByteCount = 0;
// Получение данных из буфера
int UART_receive(uint8_t* data, size_t length) {
char overflow=0; // Флаг переполнения, который устанавливается, если превышен размер массива
uint32_t byteCount=0; // Счетчик байтов, принятых из буфера приема
uint32_t timeout_ms_mb = 100; // Таймаут в миллисекундах для ожидания первого байта в буфере приема
uint32_t timeout_ms = 4; // Таймаут в миллисекундах для общего времени приема данных
uint32_t start_time = millis();
// Цикл ожидания первого байта в буфере приема с учетом таймаута
while (buffer_empty(&usartRxBuffer)) {
if ((millis() - start_time) > timeout_ms_mb) {
// Обработка таймаута
return -1;
}
}
//Цикл приема данных с таймаутом
while(1)
{
// Пока буфер приема не пуст и не истек таймаут общего времени,
// функция продолжает читать байты из буфера и сохранять их в массив data.
while (!buffer_empty(&usartRxBuffer)) {
int reader = read_buffer(&usartRxBuffer);//прием и запись символа в переменную
if(byteCount<=length){
data[byteCount] = reader; // запись в массив с индексом byteCount
}
else{
overflow=1;
}
byteCount++;
start_time = millis();
}
if ((millis() - start_time) > timeout_ms) { // если превышение времени в 4 ms
break;
}
}
return overflow?-1:byteCount; // возвращает количество успешно принятых байт или -1
}
int main(void) {
sei();
UART_init();
timerInit();
DDRD = 0xFF;
uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09};
//UART_send(buff, sizeof(buff));
//
//uint8_t receivedData[BUFFER_SIZE];
//UART_receive(receivedData,sizeof(receivedData));
//UART_send(receivedData, sizeof(receivedData));
while (1) {
//unsigned long currentTime = millis();
}
return 0;
}
// прерывание по завершению приема
ISR(USART_RX_vect) {
uint8_t data = UDR0; // читаем из регистра UDR0
if (!buffer_full(&usartRxBuffer)) {
write_buffer(&usartRxBuffer, data);// записываем символ в буфер приема
}
}