diff --git a/UART/circular_buf.c b/UART/circular_buf.c new file mode 100644 index 0000000..e1b91c7 --- /dev/null +++ b/UART/circular_buf.c @@ -0,0 +1,36 @@ +#include +#include +#include "circular_buf.h" + + +void initialize_buffer(struct circular_buffer* cb) { + cb->buf_head = 0; + cb->buf_tail = 0; +} +// Проверка, пустой ли буфер +int buffer_empty(const struct circular_buffer* cb) { + return cb->buf_head == cb->buf_tail; +} +// Проверка, заполнен ли буфер +int buffer_full(const struct circular_buffer* cb) { + return (cb->buf_tail + 1) % BUFFER_SIZE == cb->buf_head; //проверяем следующее число, если оно будет совпадать с индексом головы то будет false, при совпадении вывод true +} +// Запись в буфер +void write_buffer(struct circular_buffer* cb, int value) { + if (buffer_full(cb)) { // проверяем, заполнен ли буфер + return; + } + cb->buffer[cb->buf_tail] = value;// записываем значение в элемент массива в хвост + cb->buf_tail = (cb->buf_tail + 1) % BUFFER_SIZE;// присваивается cb->buf_tail, обновляется его значение на следующий индекс в буфере +} +// Чтение элемента +int read_buffer(struct circular_buffer* cb) { + if (buffer_empty(cb)) { // проверка на пустоту + return -1;// -1 как индикатор в случае ошибки + } + int value = cb->buffer[cb->buf_head]; // чтение по индексу головы + cb->buf_head = (cb->buf_head + 1) % BUFFER_SIZE; // увеличиваем индекс на 1 + return value; +} + + diff --git a/UART/circular_buf.h b/UART/circular_buf.h new file mode 100644 index 0000000..22dc139 --- /dev/null +++ b/UART/circular_buf.h @@ -0,0 +1,18 @@ +#ifndef CIRCULAR_BUFFER_H +#define CIRCULAR_BUFFER_H + +#define BUFFER_SIZE 32 + +struct circular_buffer{ + unsigned char buffer[BUFFER_SIZE]; + unsigned char buf_head; + unsigned char buf_tail; +}; + +void initialize_buffer(struct circular_buffer* cb); +int buffer_empty(const struct circular_buffer* cb); +int buffer_full(const struct circular_buffer* cb); +void write_buffer(struct circular_buffer* cb, int value); +int read_buffer(struct circular_buffer* cb); + +#endif /* CIRCULAR_BUFFER_H */ diff --git a/UART/timer.c b/UART/timer.c new file mode 100644 index 0000000..ca35795 --- /dev/null +++ b/UART/timer.c @@ -0,0 +1,21 @@ +#include +#include + +static volatile unsigned long timerMillis = 0; + +void timerInit() { + TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); + OCR1A = 250; + TIMSK1 |= (1 << OCIE1A); + sei(); +} + +unsigned long millis() { + unsigned long ms; + ms = timerMillis; + return ms; +} + +ISR(TIMER1_COMPA_vect) { + timerMillis++; +} \ No newline at end of file diff --git a/UART/timer.h b/UART/timer.h new file mode 100644 index 0000000..f5b07fe --- /dev/null +++ b/UART/timer.h @@ -0,0 +1,7 @@ +#ifndef TIMER_H +#define TIMER_H + +void timerInit(); +unsigned long millis(); + +#endif // TIMER_H \ No newline at end of file diff --git a/UART/uart.c b/UART/uart.c new file mode 100644 index 0000000..355d7ee --- /dev/null +++ b/UART/uart.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include "timer.h" +#include "circular_buf.h" +#include "uart.h" + +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); // Включаем прерывание по опустошению буфера +} + +// Получение данных из буфера +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 + } + else{ + overflow=1; + } + byteCount++; + + start_time = millis(); + } + if ((millis() - start_time) > timeout_ms) { // если превышение времени в 4 ms + break; + } + + } + return overflow?-1:byteCount; // возвращает количество успешно принятых байт или -1 +} + +// прерывание по завершению приема +ISR(USART_RX_vect) { + uint8_t data = UDR0; // читаем из регистра UDR0 + if (!buffer_full(&usartRxBuffer)) { + write_buffer(&usartRxBuffer, data);// записываем символ в буфер приема + } +} diff --git a/UART/uart.h b/UART/uart.h new file mode 100644 index 0000000..e9fa4eb --- /dev/null +++ b/UART/uart.h @@ -0,0 +1,18 @@ +#ifndef UART_H +#define UART_H +#include +#include +#include "timer.h" +#include "circular_buf.h" + +#define F_CPU 16000000 + +struct circular_buffer usartRxBuffer; +struct circular_buffer usartTxBuffer; + +void UART_init(void); +void UART_send(uint8_t* data, size_t length); +int UART_receive(uint8_t* data, size_t length); + + +#endif /* UART_H */ \ No newline at end of file diff --git a/main.c b/main.c deleted file mode 100644 index 93e2b83..0000000 --- a/main.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include "config.h" -#include -#include -#include -#include "uart_hal.h" - - -int main(void) -{ - //example - uint8_t data = 'A'; - - uart_init(9600,0); - uart_send_byte(data); - sei(); - while (1) - { - if(uart_read_count() > 0){ - data = uart_read(); - uart_send_byte(data); - } - - } -} \ No newline at end of file diff --git a/uart_module.c b/uart_module.c deleted file mode 100644 index c4cbc2a..0000000 --- a/uart_module.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "uart_hal.h" - -volatile static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0}; -volatile static uint16_t rx_count = 0; -volatile static uint8_t uart_tx_busy = 1; -// кольцевой буффер -ISR(USART_RX_vect){ - - volatile static uint16_t rx_write_pos = 0; - - rx_buffer[rx_write_pos] = UDR0; - rx_count++; - rx_write_pos++; - if(rx_write_pos >= RX_BUFFER_SIZE){ - rx_write_pos = 0; - } - -} - - -ISR(USART_TX_vect){ - uart_tx_busy = 1; -} - - -void uart_init(uint32_t baud,uint8_t high_speed){ - - uint8_t speed = 16; - - if(high_speed != 0){ - speed = 8; - UCSR0A |= 1 << U2X0; - } - - baud = (F_CPU/(speed*baud)) - 1; - - UBRR0H = (baud & 0x0F00) >> 8; - UBRR0L = (baud & 0x00FF); - - UCSR0B |= (1 << TXEN0) | (1 << RXEN0) | (1 << TXCIE0) | (1 << RXCIE0); - -} - - -void uart_send_byte(uint8_t c){ - while(uart_tx_busy == 0); - uart_tx_busy = 0; - UDR0 = c; -} - -void uart_send_array(uint8_t *c,uint16_t len){ - for(uint16_t i = 0; i < len;i++){ - uart_send_byte(c[i]); - } -} - -void uart_send_string(uint8_t *c){ - uint16_t i = 0; - do{ - uart_send_byte(c[i]); - i++; - - }while(c[i] != '\0'); - uart_send_byte(c[i]); -} - -uint16_t uart_read_count(void){ - return rx_count; -} - -uint8_t uart_read(void){ - static uint16_t rx_read_pos = 0; - uint8_t data = 0; - - data = rx_buffer[rx_read_pos]; - rx_read_pos++; - rx_count--; - if(rx_read_pos >= RX_BUFFER_SIZE){ - rx_read_pos = 0; - } - return data; -} \ No newline at end of file diff --git a/uart_module.h b/uart_module.h deleted file mode 100644 index 284a941..0000000 --- a/uart_module.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef UART_HAL_H_ -#define UART_HAL_H_ - - -#include -#include "config.h" -#include -#include -#include - -#define RX_BUFFER_SIZE 128 - -void uart_init(uint32_t baud,uint8_t high_speed); -void uart_send_byte(uint8_t c); -void uart_send_array(uint8_t *c,uint16_t len); -void uart_send_string(uint8_t *c); -uint16_t uart_read_count(void); -uint8_t uart_read(void); - -#endif /* UART_HAL_H_ */ \ No newline at end of file