Изменил(а) на 'UART/main.c'

This commit is contained in:
Никита Солодянкин 2023-06-16 22:19:56 +00:00
parent f83f5bfa9f
commit cb281d378e

View File

@ -8,92 +8,73 @@
#define F_CPU 16000000 #define F_CPU 16000000
#define SIZE_BUF 16 #define SIZE_BUF 16
CircularBuffer usartTxBuffer;
CircularBuffer usartRxBuffer;
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) { void UARTInit(void) {
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << TXCIE0); UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0); // &#1074;&#1082;&#1083;&#1102;&#1095;&#1072;&#1077;&#1084; &#1087;&#1088;&#1077;&#1088;&#1099;&#1074;&#1072;&#1085;&#1080;&#1077; &#1087;&#1086; &#1087;&#1088;&#1080;&#1077;&#1084;&#1091; &#1080; &#1086;&#1087;&#1091;&#1089;&#1090;&#1086;&#1096;&#1077;&#1085;&#1080;&#1102; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080;
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
UBRR0H = 0; UBRR0H = 0;
UBRR0L = 103; UBRR0L = 103;
} }
void UARTSend(uint8_t* data, size_t length) { void UARTSend(uint8_t* data, size_t length) {
for (size_t i = 0; i < length; i++) { // Ждём опустошения буфера передачи (читаем флаг). for (size_t i = 0; i < length; i++) {
while (!(UCSR0A & (1 << UDRE0))); if (!BufferFull(&usartTxBuffer)) {
UDR0 = data[i];// Записываем в регистр значение переменной "data" для передачи. writeBuffer(&usartTxBuffer, data[i]);
} else {
break; // &#1073;&#1091;&#1092;&#1077;&#1088; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080; &#1079;&#1072;&#1087;&#1086;&#1083;&#1085;&#1077;&#1085;, &#1087;&#1088;&#1077;&#1088;&#1099;&#1074;&#1072;&#1077;&#1084; &#1086;&#1090;&#1087;&#1088;&#1072;&#1074;&#1082;&#1091;
}
} }
UCSR0B |= (1 << UDRIE0); // &#1042;&#1082;&#1083;&#1102;&#1095;&#1072;&#1077;&#1084; &#1087;&#1088;&#1077;&#1088;&#1099;&#1074;&#1072;&#1085;&#1080;&#1077; &#1087;&#1086; &#1086;&#1087;&#1091;&#1089;&#1090;&#1086;&#1096;&#1077;&#1085;&#1080;&#1102; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080;
} }
//положить символ в буфер //&#1087;&#1086;&#1083;&#1086;&#1078;&#1080;&#1090;&#1100; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083; &#1074; &#1073;&#1091;&#1092;&#1077;&#1088;
void USART_PutChar(unsigned char sym) { void USART_PutChar(unsigned char sym) {
if (((UCSR0A & (1 << UDRE0)) != 0) && (txCount == 0)) { if (((UCSR0A & (1 << UDRE0)) != 0) && BufferEmpty(&usartTxBuffer)) {
UDR0 = sym; UDR0 = sym;
} else { } else {
if (txCount < SIZE_BUF) { if (!BufferFull(&usartTxBuffer)) {
usartTxBuf[txBufTail] = sym; writeBuffer(&usartTxBuffer, sym);
txCount++; } else {
txBufTail++; // &#1041;&#1091;&#1092;&#1077;&#1088; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080; &#1087;&#1086;&#1083;&#1086;&#1085;, &#1086;&#1073;&#1088;&#1072;&#1073;&#1086;&#1090;&#1082;&#1072; &#1086;&#1096;&#1080;&#1073;&#1082;&#1080; &#1080;&#1083;&#1080; &#1076;&#1088;&#1091;&#1075;&#1072;&#1103; &#1083;&#1086;&#1075;&#1080;&#1082;&#1072;
if (txBufTail == SIZE_BUF) {
txBufTail = 0;
}
} }
} }
} }
//взять символ из буфера //&#1074;&#1079;&#1103;&#1090;&#1100; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083; &#1080;&#1079; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072;
unsigned char GetChar(void) { int GetChar(unsigned char* sym) {
unsigned char sym = 0; if (!BufferEmpty(&usartTxBuffer)) {
if (txCount > 0) { *sym = readBuffer(&usartTxBuffer);
sym = usartTxBuf[txBufHead]; return 1; // &#1059;&#1089;&#1087;&#1077;&#1096;&#1085;&#1086; &#1087;&#1088;&#1086;&#1095;&#1080;&#1090;&#1072;&#1085; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083; &#1080;&#1079; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080;
txCount--; } else {
txBufHead++; return 0; // &#1041;&#1091;&#1092;&#1077;&#1088; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080; &#1087;&#1091;&#1089;&#1090;, &#1074;&#1086;&#1079;&#1085;&#1080;&#1082;&#1083;&#1072; &#1086;&#1096;&#1080;&#1073;&#1082;&#1072; &#1095;&#1090;&#1077;&#1085;&#1080;&#1103;
if (txBufHead == SIZE_BUF) {
txBufHead = 0;
}
} }
return sym;
} }
//функция загрузки строк //&#1092;&#1091;&#1085;&#1082;&#1094;&#1080;&#1103; &#1079;&#1072;&#1075;&#1088;&#1091;&#1079;&#1082;&#1080; &#1089;&#1090;&#1088;&#1086;&#1082;
void USART_SendStr(const unsigned char* data) { void USART_SendStr(const unsigned char* data) {
while (*data) { while (*data) {
USART_PutChar(*data++); USART_PutChar(*data++);
} }
} }
//получаем данные из буфера //&#1087;&#1086;&#1083;&#1091;&#1095;&#1072;&#1077;&#1084; &#1076;&#1072;&#1085;&#1085;&#1099;&#1077; &#1080;&#1079; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072;
void UARTReceive(uint8_t* data) { void UARTReceive(uint8_t* data) {
uint32_t timeout_ms_mb = 100;//timeout 100ms, в нашем случае, иногда по 1 сек, и даже по 4-5 с, если байт повредился и идет около 1-2секунд, то штора может сломаться uint32_t timeout_ms_mb = 100;
uint32_t timeout_ms = 4; uint32_t timeout_ms = 4;
uint32_t start_time = millis();//запоминаем время начала ожидания uint32_t start_time = millis();
while (rxCount == 0) { //ожидание наличия данных в буфере приёма while (BufferEmpty(&usartRxBuffer)) {
if ((millis() - start_time) > timeout_ms_mb) { //если время ожидания истекло if ((millis() - start_time) > timeout_ms_mb) {
return 0; //выходим из цикла // &#1054;&#1073;&#1088;&#1072;&#1073;&#1086;&#1090;&#1082;&#1072; &#1086;&#1096;&#1080;&#1073;&#1082;&#1080; &#1080;&#1083;&#1080; &#1090;&#1072;&#1081;&#1084;&#1072;&#1091;&#1090;&#1072; &#1087;&#1088;&#1080;&#1077;&#1084;&#1072;
return 0;
} }
} }
data[0] = usartRxBuf[rxBufHead];//считывание байта из буфера data[0] = readBuffer(&usartRxBuffer);
rxCount--; start_time = millis();
rxBufHead++; while (!BufferEmpty(&usartRxBuffer)) {
if (rxBufHead == SIZE_BUF) { if ((millis() - start_time) > timeout_ms) {
rxBufHead = 0; break;
}
start_time = millis();//обнуляем таймаут, так как данные начали приходить
while (rxCount > 0) { //ожидание окончания приёма данных
if ((millis() - start_time) > timeout_ms) { //если время ожидания истекло
break; //выходим из цикла ожидания
} }
} }
} }
int main(void) { int main(void) {
sei(); sei();
UARTInit(); UARTInit();
@ -101,49 +82,31 @@ int main(void) {
DDRD = 0xFF; DDRD = 0xFF;
uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09}; uint8_t buff[] = {0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x09};
UARTSend(buff, sizeof(buff)); UARTSend(buff, sizeof(buff));
//for (int i = 0; i < 7; i++) {
//UARTSend(buff, sizeof(buff));
//}
uint8_t receivedData[SIZE_BUF]; uint8_t receivedData[SIZE_BUF];
UARTReceive(receivedData); UARTReceive(receivedData);
UARTSend(receivedData, sizeof(receivedData)); UARTSend(receivedData, sizeof(receivedData));
while (1) { while (1) {
//unsigned long currentTime = millis(); //unsigned long currentTime = millis();
// Делайте что-то с текущим временем...
} }
return 0; return 0;
} }
ISR(USART_RX_vect) { ISR(USART_RX_vect) {
if (rxCount < SIZE_BUF) { if (!BufferFull(&usartRxBuffer)) {
usartRxBuf[rxBufTail] = UDR0; writeBuffer(&usartRxBuffer, UDR0);// &#1047;&#1072;&#1087;&#1080;&#1089;&#1099;&#1074;&#1072;&#1077;&#1084; &#1087;&#1088;&#1080;&#1085;&#1103;&#1090;&#1099;&#1081; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083; &#1074; &#1073;&#1091;&#1092;&#1077;&#1088; &#1087;&#1088;&#1080;&#1077;&#1084;&#1072;
rxBufTail++; }
if (rxBufTail == SIZE_BUF) {
rxBufTail = 0; if (!BufferEmpty(&usartTxBuffer)) {
} UDR0 = readBuffer(&usartTxBuffer);// &#1054;&#1090;&#1087;&#1088;&#1072;&#1074;&#1083;&#1103;&#1077;&#1084; &#1089;&#1080;&#1084;&#1074;&#1086;&#1083; &#1080;&#1079; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080;
rxCount++; } else {
UCSR0B &= ~(1 << UDRIE0); // &#1054;&#1090;&#1082;&#1083;&#1102;&#1095;&#1072;&#1077;&#1084; &#1087;&#1088;&#1077;&#1088;&#1099;&#1074;&#1072;&#1085;&#1080;&#1077; &#1087;&#1086; &#1086;&#1087;&#1091;&#1089;&#1090;&#1086;&#1096;&#1077;&#1085;&#1080;&#1102; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072; &#1087;&#1077;&#1088;&#1077;&#1076;&#1072;&#1095;&#1080;
} }
} }
////обработчик прерывания по завершению передачи
//ISR(USART_TXC_vect) {
//if (txCount > 0){ //если буфер не пустой
//UDR0 = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера
//txCount--; //уменьшаем счетчик символов
//txBufHead++; //инкрементируем индекс головы буфера
//if (txBufHead == SIZE_BUF)
//txBufHead = 0;
//}
//else {
//UCSR0B &= ~(0<<TXCIE0);
//}
// //
//// rx_data = UDR0; //Â íåì äàííûå èç ïðèåìíîãî áóôåðà UDR ïåðåíîñÿòñÿ â ãëîáàëüíóþ ïåðåìåííóþ rx_data //// rx_data = UDR0; //Â íåì äàííûå èç ïðèåìíîãî áóôåðà UDR ïåðåíîñÿòñÿ â ãëîáàëüíóþ ïåðåìåííóþ rx_data
//// rx_flag = 1; //âûñòàâëÿåòñÿ ôëàã rx_flag, ãîâîðÿùèé î òîì, ÷òî ïðèåì çàâåðøåí //// rx_flag = 1; //âûñòàâëÿåòñÿ ôëàã rx_flag, ãîâîðÿùèé î òîì, ÷òî ïðèåì çàâåðøåí