diff --git a/UART/main.c b/UART/main.c index 4d943bd..3d90545 100644 --- a/UART/main.c +++ b/UART/main.c @@ -1,156 +1,119 @@ -#include -#include -#include -#include -#include "timer.h" -#include "circular_buf.h" - -#define F_CPU 16000000 -#define SIZE_BUF 16 - - - -volatile unsigned char usartTxBuf[SIZE_BUF]; -volatile unsigned char txBufTail = 0; -volatile unsigned char txBufHead = 0; -volatile unsigned char txCount = 0; - -volatile unsigned char usartRxBuf[SIZE_BUF]; -volatile unsigned char rxBufTail = 0; -volatile unsigned char rxBufHead = 0; -volatile unsigned char rxCount = 0; - - - -void UARTInit(void) { - UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << TXCIE0); - UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); - UBRR0H = 0; - UBRR0L = 103; -} - -void UARTSend(uint8_t* data, size_t length) { - for (size_t i = 0; i < length; i++) { // Ждём опустошения буфера передачи (читаем флаг). - while (!(UCSR0A & (1 << UDRE0))); - UDR0 = data[i];// Записываем в регистр значение переменной "data" для передачи. - } -} -//положить символ в буфер -void USART_PutChar(unsigned char sym) { - if (((UCSR0A & (1 << UDRE0)) != 0) && (txCount == 0)) { - UDR0 = sym; - } else { - if (txCount < SIZE_BUF) { - usartTxBuf[txBufTail] = sym; - txCount++; - txBufTail++; - if (txBufTail == SIZE_BUF) { - txBufTail = 0; - } - } - } -} -//взять символ из буфера -unsigned char GetChar(void) { - unsigned char sym = 0; - if (txCount > 0) { - sym = usartTxBuf[txBufHead]; - txCount--; - txBufHead++; - if (txBufHead == SIZE_BUF) { - txBufHead = 0; - } - } - return sym; -} -//функция загрузки строк -void USART_SendStr(const unsigned char* data) { - while (*data) { - USART_PutChar(*data++); - } -} -//получаем данные из буфера -void UARTReceive(uint8_t* data) { - uint32_t timeout_ms_mb = 100;//timeout 100ms, в нашем случае, иногда по 1 сек, и даже по 4-5 с, если байт повредился и идет около 1-2секунд, то штора может сломаться - uint32_t timeout_ms = 4; - uint32_t start_time = millis();//запоминаем время начала ожидания - while (rxCount == 0) { //ожидание наличия данных в буфере приёма - if ((millis() - start_time) > timeout_ms_mb) { //если время ожидания истекло - return 0; //выходим из цикла - } - } - data[0] = usartRxBuf[rxBufHead];//считывание байта из буфера - rxCount--; - rxBufHead++; - if (rxBufHead == SIZE_BUF) { - rxBufHead = 0; - } - start_time = millis();//обнуляем таймаут, так как данные начали приходить - while (rxCount > 0) { //ожидание окончания приёма данных - if ((millis() - start_time) > timeout_ms) { //если время ожидания истекло - break; //выходим из цикла ожидания - } - } -} - - -int main(void) { - sei(); - UARTInit(); - timerInit(); - DDRD = 0xFF; - uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09}; - UARTSend(buff, sizeof(buff)); - //for (int i = 0; i < 7; i++) { - //UARTSend(buff, sizeof(buff)); - //} - - uint8_t receivedData[SIZE_BUF]; - UARTReceive(receivedData); - - - UARTSend(receivedData, sizeof(receivedData)); - - - - while (1) { - //unsigned long currentTime = millis(); - // Делайте что-то с текущим временем... - } - return 0; -} - -ISR(USART_RX_vect) { - if (rxCount < SIZE_BUF) { - usartRxBuf[rxBufTail] = UDR0; - rxBufTail++; - if (rxBufTail == SIZE_BUF) { - rxBufTail = 0; - } - rxCount++; - } -} - - -////обработчик прерывания по завершению передачи -//ISR(USART_TXC_vect) { - //if (txCount > 0){ //если буфер не пустой - //UDR0 = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера - //txCount--; //уменьшаем счетчик символов - //txBufHead++; //инкрементируем индекс головы буфера - //if (txBufHead == SIZE_BUF) - //txBufHead = 0; - //} - //else { - //UCSR0B &= ~(0< +#include +#include +#include +#include "timer.h" +#include "circular_buf.h" + +#define F_CPU 16000000 +#define SIZE_BUF 16 + +CircularBuffer usartTxBuffer; +CircularBuffer usartRxBuffer; + +void UARTInit(void) { + UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // включаем прерывание по приему и опустошению буфера передачи + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + UBRR0H = 0; + UBRR0L = 103; +} + +void UARTSend(uint8_t* data, size_t length) { + for (size_t i = 0; i < length; i++) { + if (!BufferFull(&usartTxBuffer)) { + writeBuffer(&usartTxBuffer, data[i]); + } else { + break; // буфер передачи заполнен, прерываем отправку + } + } + UCSR0B |= (1 << UDRIE0); // Включаем прерывание по опустошению буфера передачи +} +//положить символ в буфер +void USART_PutChar(unsigned char sym) { + if (((UCSR0A & (1 << UDRE0)) != 0) && BufferEmpty(&usartTxBuffer)) { + UDR0 = sym; + } else { + if (!BufferFull(&usartTxBuffer)) { + writeBuffer(&usartTxBuffer, sym); + } else { + // Буфер передачи полон, обработка ошибки или другая логика + } + } +} +//взять символ из буфера +int GetChar(unsigned char* sym) { + if (!BufferEmpty(&usartTxBuffer)) { + *sym = readBuffer(&usartTxBuffer); + return 1; // Успешно прочитан символ из буфера передачи + } else { + return 0; // Буфер передачи пуст, возникла ошибка чтения + } +} +//функция загрузки строк +void USART_SendStr(const unsigned char* data) { + while (*data) { + USART_PutChar(*data++); + } +} +//получаем данные из буфера +void UARTReceive(uint8_t* data) { + uint32_t timeout_ms_mb = 100; + uint32_t timeout_ms = 4; + uint32_t start_time = millis(); + while (BufferEmpty(&usartRxBuffer)) { + if ((millis() - start_time) > timeout_ms_mb) { + // Обработка ошибки или таймаута приема + return 0; + } + } + data[0] = readBuffer(&usartRxBuffer); + start_time = millis(); + while (!BufferEmpty(&usartRxBuffer)) { + if ((millis() - start_time) > timeout_ms) { + break; + } + } +} + +int main(void) { + sei(); + UARTInit(); + timerInit(); + DDRD = 0xFF; + uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09}; + UARTSend(buff, sizeof(buff)); + + uint8_t receivedData[SIZE_BUF]; + UARTReceive(receivedData); + UARTSend(receivedData, sizeof(receivedData)); + + while (1) { + //unsigned long currentTime = millis(); + + } + return 0; +} + +ISR(USART_RX_vect) { + if (!BufferFull(&usartRxBuffer)) { + writeBuffer(&usartRxBuffer, UDR0);// Записываем принятый символ в буфер приема + } + + if (!BufferEmpty(&usartTxBuffer)) { + UDR0 = readBuffer(&usartTxBuffer);// Отправляем символ из буфера передачи + } else { + UCSR0B &= ~(1 << UDRIE0); // Отключаем прерывание по опустошению буфера передачи + } +} + + + // + //// rx_data = UDR0; //В нем данные из приемного буфера UDR переносятся в глобальную переменную rx_data + //// rx_flag = 1; //выставляется флаг rx_flag, говорящий о том, что прием завершен +//} + + + - -