На этом уроке мы с Вами портируем программную реализацию интерфейса передатчика и приёмника с цифровой, байт ориентированной последовательностью на микроконтроллер PIC.
Рассмотрение программы начнём с заголовочного файла передатчика transmitter.h. Единственное изменение состоит в отличительном написании команды задержки...
__delay_ms(1); //Частота передачи 1000 бод
Настройки портов ввода-вывода и АЦП из файла initHard.c остаются прежними.
Теперь рассмотрим основную программу. Опрашиваем клавиши поворота и заднего хода...
//Опрос клавиши направление движения. Загрузить полученные данные в commandBuffer if (PORTBbits.RB1 == 0) commandBuffer |= (1 << 0); else commandBuffer &= ~(1 << 0); //Опрос клавиш направления поворота. Загрузить полученные данные в commandBuffer if (PORTBbits.RB2 == 0) commandBuffer |= (1 << 1); else commandBuffer &= ~(1 << 1); //Влево if (PORTBbits.RB4 == 0) commandBuffer |= (1 << 2); else commandBuffer &= ~(1 << 2); //Вправо
Сохраняем мгновенное значение мощности в буфер, вычисляем бит паритета и контрольную сумму...
//Загружаем мгновенное значение мощности powerEngine = ADRESH; //Вычисляем контрольную сумму checkSum = powerEngine + commandBuffer; //Проверяем на чётность передаваемые данные if (checkSum & (1 << 0)) parityBit = HIGH; else parityBit = LOW;
В отличии от AVR АЦП МК PIC режима автоматического перезапуска, поэтому...
GO_DONE = 1; //Начать измерение
В основном цикле передаём данные...
//Передача стартовых байт transmitString(START_SEQUENCE); //Передача байта мощности transmitByte(powerEngine); //Передача байта commandBuffer transmitByte(commandBuffer); //Передача бита чётности if (parityBit == EVEN) transmitBit(HIGH); else transmitBit(LOW); //Передача байта контрольной суммы transmitByte(checkSum); //Передача стоповых байт transmitString(STOP_SEQUENCE);
Функция transmitBit. Если при вызове аргумент функции равен HIGH, то конструкция...
if (txBuffer == HIGH) PORTAbits.RA2 = 1; //Формируем фронт
...формирует фронт логической единицы. Далее следует пауза...
PULSE_DURATION()...
...которая обеспечивает скорость передачи в 1000 бод. Следом формируется безусловный срез...
PORTAbits.RA2 = 0; //Формируем срез
В случае, если аргумент функции равен LOW, функция формирует паузу в 1ms.
Функция transmitByte, в качестве аргумента получает один байт, 8 бит которого передаются в цикле...
for (unsigned char i = 0; i < 8; i++) {...
Проверяем «нулевой» бит, в зависимости от его значения формируем фронт или срез...
//Формируем фронт/срез if (txBuffer & (1 << 7)) PORTAbits.RA2 = 1; else PORTAbits.RA2 = 0;
...формируем паузу...
PULSE_DURATION(); //Длительность логического состояния
Сдвигаем переменную txBuffer вправо на один разряд. Эта процедура повторяется 8 раз, для передачи 8 бит.
Функция transmitString, в качестве аргумента получает строку символов. Перед началом передачи вычисляется количество символов в строке, затем в цикле...
for (unsigned char i = 0; i < strlen(txBuffer); i++) {...
...загружаем первый передаваемый символ в буфер передатчика...
charBuffer = txBuffer[i];
...происходит передача 8 байт текущего байта...
for (unsigned char i = 0; i < 8; i++) { //Формируем фронт/срез if (charBuffer & (1 << 7)) PORTAbits.RA2 = 1; else PORTAbits.RA2 = 0; PULSE_DURATION(); //Длительность логического состояния charBuffer >>= 1; //Сдвиг вправо на одну позицию }
Эта процедура повторяется для каждого передаваемого символа.
Теперь о приёмнике... После инициализации периферии, производится поиск первого байта стартовой последовательности в потоке данных передаваемых передатчиком. После его нахождения принимаются два следующих бита, которые являются вторым и третьим байтами стартовой последовательности. При любом несовпадении приём стартовой последовательности начинается заново. Далее принимаются данные, контрольная сумма и бит чётности. В завершении производится приём трёх стоповых байт. При любом несовпадении приём кадра начинается заново. По завершению приёма кадра начинается проверка данных: бита чётности и контрольной суммы. При любом несовпадении приём кадра начинается заново. В случае прохождения проверки выполняем команды посланные пультом управления...
//Загружаем значение мощности OCR2 = powerEngine; //Выполняем команды направления движения и поворота if (commandBuffer & (1 << 0)) PORTBbits.RB1 = 1; else PORTBbits.RB1 = 0; if (commandBuffer & (1 << 1)) PORTBbits.RB2 = 1; else PORTBbits.RB2 = 0; if (commandBuffer & (1 << 2)) PORTBbits.RB4 = 1; else PORTBbits.RB4 = 0;
Функция findByte. Очищаем буфер приёмника…
rxBuffer = 0; //Очищаем буффер приёмника
Допустим, что в данный момент передатчик передаёт логическую единицу. Проверяем это...
if (PORTAbits.RA2 == 1) {...
...передаём управление секции приёма логической единицы. Для измерения длительности мы будем использовать таймер. Включаем его…
TMR1ON = 1; //Включить таймер
Ждём, пока длится импульс, и пока значение счётного регистра таймера меньше выбранной нами длительности...
while(PORTAbits.RA2 == 1 && TMR1 < PULSE_DURATION); //Ожидание...
Выключаем таймер...
TMR1ON = 0; //Выключить таймер
Проверяем длительность импульса...
if (TMR1 > PULSE_DURATION) {...
Если измеренная длительность импульса соответствует выбранной уставке, регистрируем принятый бит...
rxBuffer++; //Записываем в буффер "1"
Устанавливаем флаг «данные приняты»...
dataReceived = TRUE; //Даннее приняты
Обнуляем счётчик отсчётов...
TMR1 = 0; //Очищаем счётчик отсчётов
Переходим к секции сравнения...
//Проверяем на совпадение... if (rxBuffer == byteforComparing) { rxBuffer = 0; //Очищаем буфер приёмника break; //При совпадении выходим из цикла }
Если совпадение произошло, выполнение функции прекращается. Если нет, переходим к секции контроля.
Если «данные приняты»...
//Если данные приняты, но совпадения не произошло... if (dataReceived == TRUE) {...
Освобождаем новый разряд для приёма следующего бита, очищаем флаг «данные приняты»...
rxBuffer << = 1; //Освобождаем новый разряд dataReceived = FALSE; //Очищаем флаг статуса приёма данных
Эта процедура будет выполняется до тех пор, пока не будет принят заданный байт.
ПРОЕКТ С ИСХОДНЫМ КОДОМ И СИМУЛЯЦИЯ В PROTEUS во вложении.
Прикрепленные файлы:
- remote_control_ver_2_.rar (282 Кб)
Комментарии (0) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация