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