Машинка на ДУ управлении своими руками. Цифровая последовательность. Приёмник (AVR)

На этом уроке мы с Вами разберём программную реализацию приёмника цифровой байт ориентированной последовательности на микроконтроллере AVR.

Программа работает следующим образом. После инициализации периферии, производится поиск первого байта стартовой последовательности в потоке данных передаваемых передатчиком…

 findByte(0b01000001);

После его нахождения принимаются два следующих бита, которые являются вторым и третьим байтами стартовой последовательности…

 reciveByte(); if (rxBuffer != 0b01000010) continue;  reciveByte(); if (rxBuffer != 0b01000011) continue;

При любом несовпадении приём стартовой последовательности начинается заново. Далее принимаются данные, контрольная сумма и бит чётности.

 reciveByte(); //Приём байта мощности powerEngine = rxBuffer;  reciveByte(); //Приём байта commandBuffer commandBuffer = rxBuffer;  reciveBit(); //Приём бита чётности if (rxBuffer & (1 << 0)) parityBit = HIGH; else parityBit = LOW;  reciveByte(); //Приём байта контрольной суммы checkSum = rxBuffer;

В завершении производится приём трёх стоповых байт.

 reciveByte(); if (rxBuffer != 0b01000100) continue;  reciveByte(); if (rxBuffer != 0b01000101) continue;  reciveByte(); if (rxBuffer != 0b01000110) continue;

При любом несовпадении приём кадра начинается заново. По завершению приёма кадра начинается проверка данных: бита чётности и контрольной суммы…

 //Вычисляем контрольную суммы принятых данных controlCheckSum = powerEngine + commandBuffer;  //Проверяем чётность принятых данных if (controlCheckSum & (1 << 0)) controlParityBit = HIGH; else controlParityBit = LOW; if (controlParityBit != parityBit) continue;  //Проверяем контрольную сумму if (checkSum != controlCheckSum) continue;  При любом несовпадении приём кадра начинается заново. В случае прохождения проверки выполняем команды посланные пультом управления… 
 //Загружаем значение мощности OCR2 = powerEngine;  //Выполняем команды направления движения и поворота if (commandBuffer & (1 << 0)) PORTD |= (1 << PD0); else PORTD &= ~(1 << PD0); if (commandBuffer & (1 << 1)) PORTD |= (1 << PD1); else PORTD &= ~(1 << PD1); if (commandBuffer & (1 << 2)) PORTD |= (1 << PD2); else PORTD &= ~(1 << PD2);

Функция поиска байта работает следующим образом. Очищаем буфер приёмника…

 rxBuffer = 0; //Очищаем буфер приёмника

Допустим, что в данный момент передатчик передаёт логическую единицу. Проверяем это…

 if (PINB & (1 << PB0)) {...

…передаём управление секции приёма логической единицы.  Для измерения длительности мы будем использовать таймер. Включаем его…

 TCCR1B |= (0 << CS02)|(0 << CS01)|(1 << CS00); //Включить таймер

Ждём, пока длится импульс, и пока значение счётного регистра таймера меньше выбранной нами длительности…

 while(PINB & (1 << PB0) && TCNT1 < PULSE_DURATION); //Ожидание... 

Выключаем таймер…

 TCCR1B &= ~(0 << CS02|0 << CS01|1 << CS00); //Выключить таймер

Проверяем длительность импульса…

 if (TCNT1 > PULSE_DURATION) {...

Если измеренная длительность импульса соответствует выбранной уставке, регистрируем принятый бит…

 rxBuffer++; //Записываем в буфер "1"

Устанавливаем флаг «данные приняты»…

 dataReceived = TRUE; //Данные приняты

Обнуляем счётчик отсчётов…

 TCNT1 = 0; //Очищаем счётчик отсчётов

Переходим к секции сравнения…

 //Проверяем на совпадение...   if (rxBuffer == byteforComparing) {  rxBuffer = 0; //Очищаем буфер приёмника break; //При совпадении выходим из цикла }

Если совпадение произошло, выполнение функции прекращается. Если нет, переходим к секции контроля.

Если «данные приняты»…

 //Если данные приняты, но совпадения не произошло...     if (dataReceived == TRUE) {...

Освобождаем новый разряд для приёма следующего бита, очищаем флаг «данные приняты»…

 rxBuffer  << = 1; //Освобождаем новый разряд dataReceived = FALSE; //Очищаем флаг статуса приёма данных

Эта процедура будет выполняется до тех пор, пока не будет принят заданный байт.

Процедура приёма бита работает аналогично и пояснений не требует. Про процедуру приёма байта я вообще молчу

Проект с исходным кодом и симуляция в Proteus во вложении!