From 0a9eb215dbeca8563a8a9e75ea02d44f17f36ad2 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Tue, 7 Nov 2023 12:01:09 +0300 Subject: [PATCH 1/4] uart modified --- UART/circular_buf.c | 36 +++++++++++++ UART/circular_buf.h | 18 +++++++ UART/main.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ UART/timer.c | 23 +++++++++ UART/timer.h | 7 +++ UART/uart.c | 119 ++++++++++++++++++++++++++++++++++++++++++ UART/uart.h | 11 ++++ main.c | 25 --------- uart_module.c | 82 ----------------------------- uart_module.h | 20 ------- 10 files changed, 337 insertions(+), 127 deletions(-) create mode 100644 UART/circular_buf.c create mode 100644 UART/circular_buf.h create mode 100644 UART/main.c create mode 100644 UART/timer.c create mode 100644 UART/timer.h create mode 100644 UART/uart.c create mode 100644 UART/uart.h delete mode 100644 main.c delete mode 100644 uart_module.c delete mode 100644 uart_module.h 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/main.c b/UART/main.c new file mode 100644 index 0000000..70784a5 --- /dev/null +++ b/UART/main.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#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 USART_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 get_char(unsigned char* sym) { + if (!buffer_empty(&usartTxBuffer)) { + *sym = read_buffer(&usartTxBuffer); + return 1; // Символ успешно прочитан + } else { + return 0; // Буфер пуст, ошибка чтения + } +} + +void USART_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) + { + + 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; +} + + + +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);// записываем символ в буфер приема + } + +} +//перезаписать чтоб освободитть байт, из udr0 diff --git a/UART/timer.c b/UART/timer.c new file mode 100644 index 0000000..a886d1f --- /dev/null +++ b/UART/timer.c @@ -0,0 +1,23 @@ +#include +#include + +static volatile unsigned long timerMillis = 0; + +void timerInit() { + TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); + OCR1A = 249; + TIMSK1 |= (1 << OCIE1A); + sei(); +} + +unsigned long millis() { + unsigned long ms; + cli(); + ms = timerMillis; + sei(); + 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..d2eaa22 --- /dev/null +++ b/UART/uart.c @@ -0,0 +1,119 @@ +#include +#include +#include + +#define F_CPU 16000000 +#define SIZE_BUF 8 + +// кольцевой буфер +volatile unsigned char usartTxBuf[SIZE_BUF]; +unsigned char txBufTail = 0; // указатель хвоста буфера +unsigned char txBufHead = 0; // указатель головы буфера +volatile unsigned char txCount = 0; // счетчик символов + +uint8_t receive = 0; +uint8_t rx_data = 0; +volatile uint8_t rx_flag = 0; + +void UARTInit(void) { + UCSR1B=0; UCSR1C=0; // Обнулим регистры статуса и контроля + UBRR0H = 0; // Старшие биты регистра скорости + UBRR0L = 103; // Скорость передачи данных 9600 + UCSR0B = (1< 0){ // если буфер не пустой + sym = cycleBuf[head]; // считываем символ из буфера + count--; // уменьшаем счетчик символов + head++; // увеличиваем индекс головы + if (head == SIZE_BUF) head = 0; + } + return sym; +} + +// загрузка строк +void USART_SendStr(unsigned char * data) +{ + unsigned char sym; + while(*data){ // пока не считан символ конца строки + sym = *data++; + USART_PutChar(sym); + } +} +// unsigned char UARTGet() { +// while(!rx_flag); //пока значение флага не станет равно "1" +// rx_flag = 0; +// return rx_data; //возвращет состояние переменной rx_data +// } + +int main(void) { + sei(); + UARTInit(); + DDRL = 0b11111111; // Определим порт "L" на выход + while(1) { + receive = UARTGet(); + receive++; + UARTSend(receive); + } +} + +// обработчик прерывания по завершению передачи +ISR(USART_TXC_vect) { + if (txCount > 0){ // если буфер не пустой + UDR0 = usartTxBuf[txBufHead]; // записываем в UDR символ из буфера + txCount--; // уменьшаем счетчик символов + txBufHead++; // увеличиваем индекс головы буфера + if (txBufHead == SIZE_BUF) + txBufHead = 0; + } + else { + UCSR0B &= ~(0< -#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 From e6a1ad36c216a074f5b5ca87c20692255a0ef8f8 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Tue, 7 Nov 2023 18:02:54 +0300 Subject: [PATCH 2/4] unused files deleted --- UART/uart.c | 119 ---------------------------------------------------- UART/uart.h | 11 ----- 2 files changed, 130 deletions(-) delete mode 100644 UART/uart.c delete mode 100644 UART/uart.h diff --git a/UART/uart.c b/UART/uart.c deleted file mode 100644 index d2eaa22..0000000 --- a/UART/uart.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include - -#define F_CPU 16000000 -#define SIZE_BUF 8 - -// кольцевой буфер -volatile unsigned char usartTxBuf[SIZE_BUF]; -unsigned char txBufTail = 0; // указатель хвоста буфера -unsigned char txBufHead = 0; // указатель головы буфера -volatile unsigned char txCount = 0; // счетчик символов - -uint8_t receive = 0; -uint8_t rx_data = 0; -volatile uint8_t rx_flag = 0; - -void UARTInit(void) { - UCSR1B=0; UCSR1C=0; // Обнулим регистры статуса и контроля - UBRR0H = 0; // Старшие биты регистра скорости - UBRR0L = 103; // Скорость передачи данных 9600 - UCSR0B = (1< 0){ // если буфер не пустой - sym = cycleBuf[head]; // считываем символ из буфера - count--; // уменьшаем счетчик символов - head++; // увеличиваем индекс головы - if (head == SIZE_BUF) head = 0; - } - return sym; -} - -// загрузка строк -void USART_SendStr(unsigned char * data) -{ - unsigned char sym; - while(*data){ // пока не считан символ конца строки - sym = *data++; - USART_PutChar(sym); - } -} -// unsigned char UARTGet() { -// while(!rx_flag); //пока значение флага не станет равно "1" -// rx_flag = 0; -// return rx_data; //возвращет состояние переменной rx_data -// } - -int main(void) { - sei(); - UARTInit(); - DDRL = 0b11111111; // Определим порт "L" на выход - while(1) { - receive = UARTGet(); - receive++; - UARTSend(receive); - } -} - -// обработчик прерывания по завершению передачи -ISR(USART_TXC_vect) { - if (txCount > 0){ // если буфер не пустой - UDR0 = usartTxBuf[txBufHead]; // записываем в UDR символ из буфера - txCount--; // уменьшаем счетчик символов - txBufHead++; // увеличиваем индекс головы буфера - if (txBufHead == SIZE_BUF) - txBufHead = 0; - } - else { - UCSR0B &= ~(0< Date: Wed, 17 Jan 2024 16:11:54 +0300 Subject: [PATCH 3/4] UART modified and added header file --- UART/{main.c => uart.c} | 32 +++++++++++++++++--------------- UART/uart.h | 12 ++++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-) rename UART/{main.c => uart.c} (66%) create mode 100644 UART/uart.h diff --git a/UART/main.c b/UART/uart.c similarity index 66% rename from UART/main.c rename to UART/uart.c index 70784a5..a0ba34e 100644 --- a/UART/main.c +++ b/UART/uart.c @@ -28,7 +28,7 @@ void UART_send(uint8_t* data, size_t length) { UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера } -void USART_put_char(unsigned char sym) { +void UART_put_char(unsigned char sym) { if (((UCSR0A & (1 << UDRE0)) != 0) && buffer_empty(&usartTxBuffer)) { UDR0 = sym; } else { @@ -40,38 +40,42 @@ void USART_put_char(unsigned char sym) { } } -int get_char(unsigned char* sym) { - if (!buffer_empty(&usartTxBuffer)) { - *sym = read_buffer(&usartTxBuffer); +int UART_get_char(unsigned char* sym) { + if (!buffer_empty(&usartRxBuffer)) { + *sym = read_buffer(&usartRxBuffer); return 1; // Символ успешно прочитан } else { return 0; // Буфер пуст, ошибка чтения } } -void USART_send_str(const unsigned char* data) { +void UART_send_str(const unsigned char* data) { while (*data) { USART_put_char(*data++); } } -uint32_t receivedByteCount = 0; +//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; + 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){ @@ -89,7 +93,7 @@ int UART_receive(uint8_t* data, size_t length) { } } - return overflow?-1:byteCount; + return overflow?-1:byteCount; // возвращает количество успешно принятых байт или -1 } @@ -108,7 +112,6 @@ int main(void) { while (1) { //unsigned long currentTime = millis(); - } return 0; } @@ -120,4 +123,3 @@ ISR(USART_RX_vect) { } } -//перезаписать чтоб освободитть байт, из udr0 diff --git a/UART/uart.h b/UART/uart.h new file mode 100644 index 0000000..c92e55b --- /dev/null +++ b/UART/uart.h @@ -0,0 +1,12 @@ +#ifndef UART_H +#define UART_H + +void UART_init(void); +void UART_send(uint8_t* data, size_t length); +void UART_put_char(unsigned char sym); +int UART_get_char(unsigned char* sym); +void UART_send_str(const unsigned char* data); +int UART_receive(uint8_t* data, size_t length); + + +#endif /* UART_H */ \ No newline at end of file From 1f38dff368fc41eebc3881d315ffce87e353b16b Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Mon, 29 Jan 2024 19:53:00 +0300 Subject: [PATCH 4/4] uart.c updated and some code refactoring --- UART/timer.c | 4 +--- UART/uart.c | 63 +--------------------------------------------------- UART/uart.h | 12 +++++++--- 3 files changed, 11 insertions(+), 68 deletions(-) diff --git a/UART/timer.c b/UART/timer.c index a886d1f..ca35795 100644 --- a/UART/timer.c +++ b/UART/timer.c @@ -5,16 +5,14 @@ static volatile unsigned long timerMillis = 0; void timerInit() { TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); - OCR1A = 249; + OCR1A = 250; TIMSK1 |= (1 << OCIE1A); sei(); } unsigned long millis() { unsigned long ms; - cli(); ms = timerMillis; - sei(); return ms; } diff --git a/UART/uart.c b/UART/uart.c index a0ba34e..355d7ee 100644 --- a/UART/uart.c +++ b/UART/uart.c @@ -4,11 +4,7 @@ #include #include "timer.h" #include "circular_buf.h" - -#define F_CPU 16000000 - -struct circular_buffer usartTxBuffer; -struct circular_buffer usartRxBuffer; +#include "uart.h" void UART_init(void) { UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // прерывание по приему и опустошению буфера передачи @@ -28,49 +24,12 @@ void UART_send(uint8_t* data, size_t length) { 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) { @@ -96,30 +55,10 @@ int UART_receive(uint8_t* data, size_t length) { 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);// записываем символ в буфер приема } - } diff --git a/UART/uart.h b/UART/uart.h index c92e55b..e9fa4eb 100644 --- a/UART/uart.h +++ b/UART/uart.h @@ -1,11 +1,17 @@ #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); -void UART_put_char(unsigned char sym); -int UART_get_char(unsigned char* sym); -void UART_send_str(const unsigned char* data); int UART_receive(uint8_t* data, size_t length);