From a2546d2931b363fe93acee2e8ebe394c74b948bf Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Mon, 5 Jun 2023 18:34:34 +0300 Subject: [PATCH 1/4] uart module added --- uart.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 uart.c diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..2b77e0c --- /dev/null +++ b/uart.c @@ -0,0 +1,101 @@ +#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«RXEN0)|(1«TXEN0)|(1«RXCIE0)|(1«TXCIE0)|(0«UDRIE0);//Включаем (подключаем ножки контроллера) приём и передачу по UART. +UCSR0C = (1«UCSZ01)|(1«UCSZ00); //8 bit + +} + +void UARTSend(uint8_t data) { +while (!(UCSR0A & (1«UDRE0))); // Ждём опустошения буфера передачи (читаем флаг). +UDR0 = data; // Записываем в регистр значение переменной "data" для передачи. +} + +//"очищает" буфер +void USART_FlushTxBuf(void) +{ +txBufTail = 0; +txCount = 0; +txBufHead = 0; + +//положить символ в буфер +void USART_PutChar(unsigned char sym) +{ +if(((UCSRA0 & (1«UDRE0)) != 0) && (txCount == 0)) UDR0 = sym; //Если модуль USART не занят и передающий буфер пустой, +else { //символ записывается в регистр UDR +if (txCount < SIZE_BUF){ //если в буфере еще есть место +usartTxBuf[txBufTail] = sym; //помещаем в него символ +txCount++; //инкрементируем счетчик символов +txBufTail++; //и индекс хвоста буфера +if (txBufTail == SIZE_BUF) txBufTail = 0; +} +} +} +//взять символ из буфера +unsigned char GetChar(void) +{ +unsigned char sym = 0; +if (count > 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_RXC_vect) { +if (txCount > 0){ //если буфер не пустой +UDR = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера +txCount--; //уменьшаем счетчик символов +txBufHead++; //инкрементируем индекс головы буфера +if (txBufHead == SIZE_BUF) txBufHead = 0; +} +// rx_data = UDR0; //В нем данные из приемного буфера UDR переносятся в глобальную переменную rx_data +// rx_flag = 1; //выставляется флаг rx_flag, говорящий о том, что прием завершен +} \ No newline at end of file From 4e3047071d7352730273e86d7c6d53c0a5238701 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Wed, 7 Jun 2023 12:34:54 +0300 Subject: [PATCH 2/4] fix --- main.c | 25 +++++++++++++ uart.c | 101 -------------------------------------------------- uart_module.c | 82 ++++++++++++++++++++++++++++++++++++++++ uart_module.h | 20 ++++++++++ 4 files changed, 127 insertions(+), 101 deletions(-) create mode 100644 main.c delete mode 100644 uart.c create mode 100644 uart_module.c create mode 100644 uart_module.h diff --git a/main.c b/main.c new file mode 100644 index 0000000..a421409 --- /dev/null +++ b/main.c @@ -0,0 +1,25 @@ +#include +#include "config.h" +#include +#include +#include +#include "uart_hal.h" + + +int main(void) +{ + + 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.c b/uart.c deleted file mode 100644 index 2b77e0c..0000000 --- a/uart.c +++ /dev/null @@ -1,101 +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«RXEN0)|(1«TXEN0)|(1«RXCIE0)|(1«TXCIE0)|(0«UDRIE0);//Включаем (подключаем ножки контроллера) приём и передачу по UART. -UCSR0C = (1«UCSZ01)|(1«UCSZ00); //8 bit - -} - -void UARTSend(uint8_t data) { -while (!(UCSR0A & (1«UDRE0))); // Ждём опустошения буфера передачи (читаем флаг). -UDR0 = data; // Записываем в регистр значение переменной "data" для передачи. -} - -//"очищает" буфер -void USART_FlushTxBuf(void) -{ -txBufTail = 0; -txCount = 0; -txBufHead = 0; - -//положить символ в буфер -void USART_PutChar(unsigned char sym) -{ -if(((UCSRA0 & (1«UDRE0)) != 0) && (txCount == 0)) UDR0 = sym; //Если модуль USART не занят и передающий буфер пустой, -else { //символ записывается в регистр UDR -if (txCount < SIZE_BUF){ //если в буфере еще есть место -usartTxBuf[txBufTail] = sym; //помещаем в него символ -txCount++; //инкрементируем счетчик символов -txBufTail++; //и индекс хвоста буфера -if (txBufTail == SIZE_BUF) txBufTail = 0; -} -} -} -//взять символ из буфера -unsigned char GetChar(void) -{ -unsigned char sym = 0; -if (count > 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_RXC_vect) { -if (txCount > 0){ //если буфер не пустой -UDR = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера -txCount--; //уменьшаем счетчик символов -txBufHead++; //инкрементируем индекс головы буфера -if (txBufHead == SIZE_BUF) txBufHead = 0; -} -// rx_data = UDR0; //В нем данные из приемного буфера UDR переносятся в глобальную переменную rx_data -// rx_flag = 1; //выставляется флаг rx_flag, говорящий о том, что прием завершен -} \ No newline at end of file diff --git a/uart_module.c b/uart_module.c new file mode 100644 index 0000000..6fa0926 --- /dev/null +++ b/uart_module.c @@ -0,0 +1,82 @@ +#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 new file mode 100644 index 0000000..284a941 --- /dev/null +++ b/uart_module.h @@ -0,0 +1,20 @@ +#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 bfd1776bba773023f6afd9062b29f78b4d78cf80 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Wed, 7 Jun 2023 12:41:42 +0300 Subject: [PATCH 3/4] fix --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index a421409..93e2b83 100644 --- a/main.c +++ b/main.c @@ -8,7 +8,7 @@ int main(void) { - + //example uint8_t data = 'A'; uart_init(9600,0); From d3b39dbc9f3feb8cf1b50e57a7bbf0b442907dff Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Wed, 7 Jun 2023 13:02:45 +0300 Subject: [PATCH 4/4] fix --- uart_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uart_module.c b/uart_module.c index 6fa0926..c4cbc2a 100644 --- a/uart_module.c +++ b/uart_module.c @@ -3,7 +3,7 @@ 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;