Реклама ⓘ
Главная » Радиоуправление
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

Машинка на ДУ управлении своими руками - передатчик и приёмник. PIC

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

Начнём с передатчика. Инициализируем периферию, настраиваем порты…

TRISAbits.TRISA0 = 1; //Вход ручки газа
TRISAbits.TRISA2 = 0; //Выход интерфейса

TRISBbits.TRISB1 = 1; //Вход кнопки заднего хода
TRISBbits.TRISB2 = 1; //Вход кнопки поворот вправо
TRISBbits.TRISB4 = 1; //Вход кнопки поворот влево

Настройка таймера 0 не требуется. Модули CCP не используем. Включаем АЦП…

ADON = 1;

Конфигурируем порт А следующим образом: линия AN0 - аналоговый вход, линии AN1 - AN5 цифровые, двунаправленные линии порта ввода вывода.

PCFG0 = 0;
PCFG1 = 1;
PCFG2 = 1;
PCFG3 = 1;

Настроим прерывания: разрешаем прерывания периферийных модулей…

PEIE = 1;

Включаем прерывания таймера 0…

T0IE = 1;

Разрешаем все прерывания…

GIE = 1;

В основном цикле запускаем измерение АЦП и опрашиваем клавиши пульта…

 while(1) //Основной цикл
{
GO_DONE = 1; //Начать измерение
__delay_us(100); //Ждём окончание измерения

//Направление движения
if (PORTBbits.RB1 == 0) direction_of_motion = 255; else direction_of_motion = 127;

//Направление поворота
if (PORTBbits.RB2 == 0) direction_of_rotation = 3; //Влево
if (PORTBbits.RB4 == 0) direction_of_rotation = 255; //Вправо
if (PORTBbits.RB2 == 1 && PORTBbits.RB4 == 1) direction_of_rotation = 127; //Прямо
}

Теперь про обработчик прерывания. У нашего МК один вектор прерывания! Поэтому внутри обработчика необходимо опрашивать флаги прерываний, чтобы выяснить что именно вызвало прерывание. Нам проще, т.к. прерывание у нас одно, поэтому проверять флаг T0IF нам нет смысла. Содержание обработчика прерывания идентично варианту для AVR, код говорит сам за себя…

interrupt void entry_point() //Точка входа в прерывание
{
OPTION_REGbits.T0CS = 1; //Выключить таймер

//Первый импульс, мощьность двигателя
if (counter_cycles == 400) PORTAbits.RA2 = 1; //Формируем фронт
if (counter_cycles == (400 + ADRESH)) PORTAbits.RA2 = 0; //Формируем срез

//Второй импульс, направление движения
if (counter_cycles == 705) PORTAbits.RA2 = 1; //Формируем фронт
if (counter_cycles == (705 + direction_of_motion)) PORTAbits.RA2 = 0; //Формируем срез

//Третий импульс, направления поворота
if (counter_cycles == 1010) PORTAbits.RA2 = 1; //Формируем фронт
if (counter_cycles == (1010 + direction_of_rotation)) PORTAbits.RA2 = 0; //Формируем срез

counter_cycles++; //Инкремент счётчика отсчётов

if (counter_cycles > 1265) counter_cycles = 0; //Проверяем признак окончания кадра

TMR0 = 0; //"Калибровочная константа"
OPTION_REGbits.T0CS = 0; //Включить таймер
INTCONbits.T0IF = 0; //Сбросить флаг прерывания
}

Теперь разберёмся с приёмником. Инициализируем периферию, настраиваем порты…

TRISAbits.TRISA2 = 1; //Вход интерфейса

TRISBbits.TRISB1 = 0; //Выход кнопки заднего хода
TRISBbits.TRISB2 = 0; //Выход кнопки поворот вправо
TRISBbits.TRISB4 = 0; //Выход кнопки поворот влево

TRISCbits.TRISC2 = 0; //Выход PWM

Настраиваем таймер 1, выберем предделитель на 4…

T1CKPS0 = 0;
T1CKPS1 = 1;

Настраиваем таймер 2 для работы с CCP модулем. Выберем предделитель на 16…

T2CKPS0 = 0;
T2CKPS1 = 1;

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

TMR2ON = 1;

Настроим модуль CCP. Выберем частоту ШИМ в 1,22кГц, для этого запишем в регистр уставку…

PR2 = 255;    //Установка периода 1,22кГц

Включаем CCP модуль в режиме ШИМ…

CCP1M0 = 0;
CCP1M1 = 0;
CCP1M2 = 1;
CCP1M3 = 1;

Несмотря не то, что АЦП не используется конфигурируем порт А следующим образом: линии AN0 - AN5 цифровые, двунаправленные линии порта ввода вывода…

PCFG0 = 0;
PCFG1 = 1;
PCFG2 = 1;
PCFG3 = 0;

Рассмотрим программу. В основном цикле декодируем стартовую паузу…

//Начало декодирования посылки
while(PORTAbits.RA2); //Ждём логического ноля

TMR1 = 0; //Сбросить счётчик отсчётов

TMR1ON = 1; //Включить таймер
while(!PORTAbits.RA2); //Считаем, пока принимаем логический ноль
TMR1ON = 0; //Выключить таймер

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

if (TMR1 < 38000) continue; //Если пауза не выдержана...

…если длительность соответствует, декодируем первый импульс…

//Декодирование первого импульса
TMR1 = 0; //Сбросить счётчик отсчётов

TMR1ON = 1; //Включить таймер
while(PORTAbits.RA2); //Считаем, пока принимаем логическую единицу
TMR1ON = 0; //Выключить таймер

Загружаем измеренное значение скважности, предварительно масштабировав его…

CCPR1L = TMR1/96; //Загружаем значение скважности

Аналогично декодируем второй импульс. Основываясь на измеренной длительности определяем направление движения…

if (TMR1 > 18000) PORTBbits.RB1 = 1; else PORTBbits.RB1 = 0;

Аналогично декодируем третий импульс. Основываясь на измеренной длительности определяем направление поворота…

if (TMR1 < 1000) PORTBbits.RB2 = 1; else PORTBbits.RB2 = 0;
if (TMR1 > 18000) PORTBbits.RB4 = 1; else PORTBbits.RB4 = 0;

На сегодня всё! До новых встреч!

ПРОЕКТ С ИСХОДНЫМ КОДОМ И СИМУЛЯЦИЯ В PROTEUS во вложении.

Прикрепленные файлы:

Теги:

Опубликована: 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (0) | Я собрал (0) | Подписаться

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Набор 4WD Kit Bluetooth
Набор 4WD Kit Bluetooth
Бокс для хранения компонентов Ручной фен 450 Вт с регулировкой температуры
вверх