diff --git a/UART/circular_buf.c b/UART/circular_buf.c new file mode 100644 index 0000000..3f09963 --- /dev/null +++ b/UART/circular_buf.c @@ -0,0 +1,42 @@ +#include +#include + +#define BUFFER_SIZE 10 + +typedef struct { + int buffer[BUFFER_SIZE]; + int BufHead; + int BufTail; +} CircularBuffer; + +void initializeBuffer(CircularBuffer* cb) { + cb->BufHead = 0; + cb->BufTail = 0; +} +// Проверка, является ли буфер пустым +int BufferEmpty(const CircularBuffer* cb) { + return cb->BufHead == cb->BufTail; +} +// Проверка, является ли буфер полным +int BufferFull(const CircularBuffer* cb) { + return (cb->BufTail + 1) % BUFFER_SIZE == cb->BufHead;//проверяем слудеющее число, если оно будет совпадать с индексом головы то будет false, при совпадении вывыедет true +} +// Запись элемента в буфер +void writeBuffer(CircularBuffer* cb, int value) { + if (BufferFull(cb)) { // проверка на заполненность + return; + } + cb->buffer[cb->BufTail] = value;//записывает значение value в элемент массива buffer в хвост + cb->BufTail = (cb->BufTail + 1) % BUFFER_SIZE;//присваивается cb->BufTail, обновляя его значение на следующий индекс в кольцевом буфере +} +// Чтение элемента из буфера +int readBuffer(CircularBuffer* cb) { + if (BufferEmpty(cb)) { //проверяет буффер на пустоту + return -1;// -1 в качестве индикатора ошибки + } + int value = cb->buffer[cb->BufHead]; //читаем значение из массива по индексу головы + cb->BufHead = (cb->BufHead + 1) % BUFFER_SIZE; //увеличиваем индекс головы +1 + return value; +} + + diff --git a/UART/circular_buf.h b/UART/circular_buf.h new file mode 100644 index 0000000..33d820c --- /dev/null +++ b/UART/circular_buf.h @@ -0,0 +1,18 @@ +#ifndef CIRCULAR_BUFFER_H +#define CIRCULAR_BUFFER_H + +#define BUFFER_SIZE 10 + +typedef struct { + int buffer[BUFFER_SIZE]; + int BufHead; + int BufTail; +} CircularBuffer; + +void initializeBuffer(CircularBuffer* cb); +int BufferEmpty(const CircularBuffer* cb); +int BufferFull(const CircularBuffer* cb); +void writeBuffer(CircularBuffer* cb, int value); +int readBuffer(CircularBuffer* cb); + +#endif /* CIRCULAR_BUFFER_H */ diff --git a/UART/main.atsln b/UART/main.atsln new file mode 100644 index 0000000..5c0a235 --- /dev/null +++ b/UART/main.atsln @@ -0,0 +1,22 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "main", "main\main.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.ActiveCfg = Debug|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.Build.0 = Debug|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.ActiveCfg = Release|AVR + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/UART/main.c b/UART/main.c new file mode 100644 index 0000000..4d943bd --- /dev/null +++ b/UART/main.c @@ -0,0 +1,156 @@ +#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< + + + + + + Device + Startup + + + Atmel + 1.7.0 + D:/atmel studio\7.0\Packs + + + + + D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\include\ + + include + C + + + include/ + + + + + D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\include\avr\iom328p.h + + header + C + 4leX2H78R90/kvebBjYSOw== + + include/avr/iom328p.h + + + + + D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\templates\main.c + template + source + C Exe + WuscJm7SWE9tRkxyEb0ntg== + + templates/main.c + Main file (.c) + + + + D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\templates\main.cpp + template + source + C Exe + mkKaE95TOoATsuBGv6jmxg== + + templates/main.cpp + Main file (.cpp) + + + + D:/atmel studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega328p + + libraryPrefix + GCC + + + gcc/dev/atmega328p + + + + + ATmega_DFP + D:/atmel studio/7.0/Packs/atmel/ATmega_DFP/1.7.374/Atmel.ATmega_DFP.pdsc + 1.7.374 + true + ATmega328P + + + + Resolved + Fixed + true + + + \ No newline at end of file diff --git a/UART/ring_buf.c b/UART/ring_buf.c new file mode 100644 index 0000000..3f09963 --- /dev/null +++ b/UART/ring_buf.c @@ -0,0 +1,42 @@ +#include +#include + +#define BUFFER_SIZE 10 + +typedef struct { + int buffer[BUFFER_SIZE]; + int BufHead; + int BufTail; +} CircularBuffer; + +void initializeBuffer(CircularBuffer* cb) { + cb->BufHead = 0; + cb->BufTail = 0; +} +// Проверка, является ли буфер пустым +int BufferEmpty(const CircularBuffer* cb) { + return cb->BufHead == cb->BufTail; +} +// Проверка, является ли буфер полным +int BufferFull(const CircularBuffer* cb) { + return (cb->BufTail + 1) % BUFFER_SIZE == cb->BufHead;//проверяем слудеющее число, если оно будет совпадать с индексом головы то будет false, при совпадении вывыедет true +} +// Запись элемента в буфер +void writeBuffer(CircularBuffer* cb, int value) { + if (BufferFull(cb)) { // проверка на заполненность + return; + } + cb->buffer[cb->BufTail] = value;//записывает значение value в элемент массива buffer в хвост + cb->BufTail = (cb->BufTail + 1) % BUFFER_SIZE;//присваивается cb->BufTail, обновляя его значение на следующий индекс в кольцевом буфере +} +// Чтение элемента из буфера +int readBuffer(CircularBuffer* cb) { + if (BufferEmpty(cb)) { //проверяет буффер на пустоту + return -1;// -1 в качестве индикатора ошибки + } + int value = cb->buffer[cb->BufHead]; //читаем значение из массива по индексу головы + cb->BufHead = (cb->BufHead + 1) % BUFFER_SIZE; //увеличиваем индекс головы +1 + return value; +} + + diff --git a/UART/timer.c b/UART/timer.c new file mode 100644 index 0000000..24cbfd0 --- /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..cd7f72f --- /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