Цифрова послідовність. Приймач (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 у вкладенні!
Прикріплені файли:
- remote_control_ver_2_2.rar (85 Кб)