Главная страница
Навигация по странице:

  • Линия неактивна 4Т 2Т Стартовый импульс Т = 4Т = 2,40 мс 2Т = мс Рис. 4.59.

  • 4.24. ПРИЕМНИК СИГНАЛОВ ДИСТАНЦИОННОГО УПРАВЛЕНИЯ

  • 4.25. СОВМЕЩЕНИЕ РАБОТЫ ДЕТЕКТОРА ОБЪЕКТОВ И ПРИЕМНИКА КОМАНД ДИСТАНЦИОННОГО УПРАВЛЕНИЯ

  • Устройства управления роботами, схемотехника и программирование (М. Предко, 2004). Устройства управления роботами, схемотехника и программирование. Устройствауправления роботамисхемотехника и микроконтроллеров picmicro


    Скачать 6.79 Mb.
    НазваниеУстройствауправления роботамисхемотехника и микроконтроллеров picmicro
    АнкорУстройства управления роботами, схемотехника и программирование (М. Предко, 2004).pdf
    Дата29.08.2017
    Размер6.79 Mb.
    Формат файлаpdf
    Имя файлаУстройства управления роботами, схемотехника и программирование .pdf
    ТипРеферат
    #8441
    КатегорияПромышленность. Энергетика
    страница20 из 33
    1   ...   16   17   18   19   20   21   22   23   ...   33
    4.23. ДИСТАНЦИОННОЕ УПРАВЛЕНИЕ РОБОТОМ
    Всегда желательно иметь какую-либо возможность управлять действиями и/или передвижением робота. Разумеется, для этих целей лучше всего подходит беспро- водной метод, например радиоуправление или использование привычного пульта дистанционного управления. Для работы удобен стандартный телевизионный пульт, цифровые кнопки от 1 до 9 которого, расположенные в виде матрицы 3x3,
    хорошо подходят для выбора направления движения, а кнопки увеличения/
    уменьшения громкости - для регулирования скорости движения. Оставшиеся незанятыми кнопки (0 и включение питания) можно приспособить для подачи роботу каких-либо команд.
    Я использовал телевизионный пульт дистанционного управления фирмы Sony.
    Стандарт Sony предписывает передачу команд импульсами света инфракрасного диапазона; при этом применяется код Manchester. В манчестерской кодировке ин- формация представляется последовательностью импульсов, длительность каждо- го из которых может иметь одно из трех возможных значений: Т, 2Т или 4Т, где
    Т = 0,60 мс - период тактовых импульсов кодера. Пример сигнала в манчестер- ской кодировке представлен на рис. 4.59, а на рис. 4.60 показан сигнал на входе приемника, полученный с помощью осциллографа.
    Линия
    неактивна


    Стартовый
    импульс
    Т =
    4Т = 2,40 мс
    2Т =
    мс
    Рис. 4.59.
    код
    Рис. 4.60. Осциллограмма дистанционного управления

    Подключение к микроконтроллеру периферийных устройств 239
    Информационный пакет состоит из 13 импульсов отрицательной полярности.
    Это значит, что сигнал высокого уровня представляет паузу между импульсами,
    импульсы кодируются низким уровнем напряжения. Первый импульс низ- кого уровня, длительностью 4Т, является стартовым; за ним следуют информаци- онные. Логический 0 представляется импульсом низкого уровня длительностью
    2Т, а логическая 1 - длительностью Т. Все информационные импульсы отделяют- ся друг от друга синхроимпульсами высокого уровня длительностью Т.
    В табл. 4.13 показано, какие последовательности импульсов соответствуют раз- личным кнопкам пульта дистанционного управления Sony.
    Таблица
    Команды инфракрасного пульта
    дистанционного управления фирмы Sony
    Кнопка
    0
    Код
    1 ObOOllOlllOllll
    2
    3
    4
    5
    .6
    •7
    8
    9
    Увеличить громкость
    громкость
    Предыдущий канал
    Питание
    ObOOllllllOllll
    ObOlOlllllOllll
    ObOOOlllllOllll
    ObOllOllllOllll
    ObOlOOllllOllll
    ObOOOOllllOllll
    ObOlllOlllOllll
    ObOlOllOllOllll
    ObOOOllOllOllll
    ObOllllOllOllll
    ObOOlllOllOllll
    ObOOOlOOOlOllll
    ObOllOlOllOllll
    ObOOlOlOllOllll
    Каждый информационный пакет повторяется примерно каждые 50 мс. Передат- чик не имеет встроенной функции автоповтора, поэтому он должен обеспечиваться внутри приемника. При разработке дистанционно управляемых автоматических устройств это не является проблемой - ведь повторяющиеся команды удобны для того, чтобы поддерживать выполнение какой-либо функции в течение всего време- ни, пока нажата соответствующая клавиша. Во многих моих конструкциях двига- тель робота, выполнив очередную команду дистанционного управления, остается включенным еще в течение 200 мс, ожидая следующего пакета. Такой защитный интервал предотвращает остановку робота в случае, если следующий пакет данных не будет получен вовремя или связь между передатчиком и приемником на корот- кое время нарушится.
    Описанный здесь принцип работы пульта дистанционного управления доволь- но прост, но все же у разработчиков могут возникнуть проблемы с пониманием

    240 Устройства управления роботами того, как надлежащим образом декодировать поступающие команды. Наиболее очевидный способ заключается в том, чтобы принимать импульсы и на ходу опре- делять их длительность с помощью следующей программы:
    void
    // Декодирование команд дистанционного управления.
    {
    unsigned int i;
    unsigned int DataPacketStart; // Время получения начала импульса.
    unsigned int DataPacketEnd; // Время окончания импульса.
    unsigned int DataPacket; // Пакет данных.
    while (1 == 1) { // Бесконечный цикл.
    while (IRData == High); // Ждать прихода импульса низкого уровня.
    DataPacketStart = THRO; // Время начала импульса низкого while (IRData == low); // Ждать конца текущего импульса.
    DataPacketEnd = TMRO - DataPacketStart; // Длительность импульса.
    if ( (DataPacketEnd >
    (DataPacketEnd <
    ) <
    // Следующие 12 бит.
    DataPacket = i = 0; // Инициализация.
    DataPacketEnd =
    while ( (i < 12)
    (DataPacketEnd != 0) )
    while (IRData == High); // Ждать начала импульса.
    DataPacketStart = TMRO; // Запомнить время
    // начала while (IRData == low); // Ждать конца импульса.
    DataPacketEnd = TMRO - DataPacketStart;
    // Длительность if ( (DataPacketEnd > 0.45msec)
    (DataPacketEnd < 0.75msec) )
    DataPacket = (DataPacket
    1) + 1;
    else if
    > 0.95msec)
    (DataPacketEnd < 1.35msec)
    DataPacket = (DataPacket «1) + 1;
    else // Ошибка.
    DataPacketEnd = 0; // Конец.
    i++; // Указатель - на следующий бит.
    } // Конец внутреннего цикла if (DataPacketEnd != 0)
    printf ("Data Packet =
    DataPacket);
    } I/ Конец оператора if.
    } // Конец внешнего оператора while.
    > // Конец программы.
    Этот метод немного громоздкий, но хорошо показывает принцип работы при- емника сигналов дистанционного управления. Проблема, однако, в том, что при- веденная программа не может быть использована в наших конструкциях: во-пер- вых, нарушены все наши правила о разделении функций различных уровней,
    а во-вторых, опрос инфракрасного детектора производится постоянно, и мы не сможем совместить прием сигналов дистанционного управления с работой инф- ракрасного обнаружителя объектов.

    Подключение к микроконтроллеру периферийных устройств 241
    Разумней будет, если мы разрешим формирование запроса на прерывание по приходу каждого импульса на вход микроконтроллера, который подключен к инф- ракрасному детектору, а процедуру измерения длительности этих импульсов
    I! декодирования принимаемых команд поручим обработчику прерываний. В сле- разделе будет показано, как воплотить эту идею в жизнь.
    4.24. ПРИЕМНИК СИГНАЛОВ
    ДИСТАНЦИОННОГО УПРАВЛЕНИЯ
    Как уже упоминалось, многие радиолюбители избегают использования стандарт- ных инфракрасных пультов дистанционного управления в своих устройствах, бо- ясь сложностей, с которыми рассчитывают столкнуться при проектировании при- и декодера команд. В этом разделе мы рассмотрим пример такого приемника докажем, что эти опасения беспочвенны. Программная реализация нашего деко- ра не окажется слишком сложной, и он будет прекрасно работать совместно с другими интерфейсами, которые уже реализованы в вышеописанных проектах.
    В одной из моих предыдущих книг, «Programming and Customizing PICmicro
    Microcontrollers» (Программирование и использование микроконтроллеров PIC- micro), было рассмотрено несколько способов реализации приемника сигналов дистанционного управления на основе различных микроконтроллеров PICmicro.
    Как всегда, если какая-либо задача уже решена одним способом, то реализация других методов ее решения не вызывает особых проблем.
    В самом начале процесса проектирования необходимо четко определить,
    команды должен принимать декодер, в каком виде они будут подаваться и какие возможности микроконтроллера будут использоваться при декодировании.
    Если вы читали эту книгу с самого начала, то для вас уже должна быть очевид- ной формулировка, описывающая работу декодера: декодер должен принимать
    сигналы пульта дистанционного управления фирмы Sony и передавать биологичес-
    кому коду соответствующие команды.
    Здесь необходимо сделать два замечания. Во-первых, желательно выполнять отбраковку ошибочно принятых данных. Если длительность какого-либо импуль- са слишком отличается от трех разрешенных значений, то разумно будет проиг- норировать весь 12-битный пакет. Во-вторых, для простоты можно не принимать в расчет стартовый бит в начале каждого пакета.
    Мы уже обсуждали в главе 3 возможные источники прерываний в микрокон- троллерах
    Поэтому без лишних комментариев выберем для нашего про- екта вывод 6 микроконтроллера PIC16F84/PIC16F627 (RBO/INT), который мо- жет быть использован для формирования запроса на прерывание при каждом изменении уровня входного сигнала.
    Необходимо, чтобы обработчик прерывания вызывался каждый раз, когда уро- вень принятого инфракрасным детектором сигнала изменяется с низкого на высо- кий, как показано на рис. 4.61. Тогда, измеряя время, прошедшее с момента послед- него вызова, можно оценить ширину импульса и таким образом отличить 0 от 1.
    Для отсчета времени, как обычно, можно использовать таймер TMRO, сохра- няя его текущее значение в специально отведенной для этого переменной.

    242 Устройства управления роботами
    Линия неактивна Стартовый импульс
    Запрос на вырабатывается по положительному перепаду
    Рис.
    Формирование запроса на прерывание по
    фронту
    входного сигнала при приеме сигналов дистанционного
    Приведенная в предыдущем разделе программа учитывала длительность стар- тового импульса, но мы упростим код, если вовсе будем его игнорировать: ведь для определения длительности очередного импульса он совершенно не нужен.
    При каждом вызове обработчика прерываний, осуществляемом по приходе по- ложительного фронта очередного импульса, мы будем проверять, как давно был выполнен предыдущий вызов. Если прошло более 9 мс, то надо прекратить про- цесс декодирования до прихода следующего пакета. Как уже повторяются каждый 50 мс. Поэтому, пропустив текущий пакет, мы всегда имеем шанс без ошибок принять следующий.
    Для реализации нашего нового проекта не понадобится переделывать преды- дущую схему, но, разумеется, придется изменить текст программы. Для отобра- жения принимаемых команд будет использоваться все тот же жидкокристалли- ческий дисплей. Текст программы вы найдете в файле
    // 17 апреля 2002 - адаптировано к новой версии компилятора.
    // 15 февраля 2002 - прием и отображение команд инфракрасного пульта
    // дистанционного управления фирмы
    //
    // Для индикации используется жидкокристаллический дисплей,
    // подключенный к микроконтроллеру через двухпроводной интерфейс
    // на основе сдвигового регистра 74LS174.
    //
    // Используются прерывания от таймера
    //
    //
    // Формат пакета данных:
    //
    // Стартовый бит 1 О
    +
    +
    //
    I I I I I I
    +
    +
    //
    // | 2,4 мс мс |
    //
    //
    | 1,2 мс | 1,76 мс |
    //
    //
    | 300 | 440 |
    //

    Подключение к микроконтроллеру периферийных устройств 243
    // Замечания по аппаратным средствам:
    // Микроконтроллер PIC16F84/PIC16F627 работает на частоте 4
    // Используется внешний тактовый генератор.
    МГц.
    // Подключение микроконтроллера:
    //
    - детектор инфракрасного излучения
    // (прерывания по положительному перепаду):
    // RB1 - линия Clock интерфейса жидкокристаллического дисплея;
    // RB2 - линия Data интерфейса жидкокристаллического дисплея.
    // Глобальные переменные и константы:
    RTC = 0; // Счетчик реального volatile char LCDDlay 20; // Длительность volatile char LCDState = 1;
    текущего состояния
    // конечного автомата.
    static volatile bit Clock static volatile bit ClockTRIS
    static volatile bit Data static volatile bit DataTRIS
    @
    char »
    // Указатель на строку выводимого volatile char
    = 0; // Смещение текущего символа в строке.
    unsigned int
    // Входной сигнал инфракрасного приемника.
    // Число импульсов для приема.
    // Число принятых импульсов.
    // Время последнего прерывания.
    // Шаблон сообщения.
    unsigned char
    = 0;
    unsigned char DataReady = 0;
    int SaveRTC;
    int char Message[20] =
    // Слово
    «if defined
    PIC16F84 selected
    // Для МК PIC16F84:
    // кварцевый тактовый генератор,
    // таймер включен,
    // сторожевой таймер выключен,
    // защита кода defined(_16F627)
    PIC16F627 with external oscillator selected
    CONFIG(Ox03F61); // Для МК PIC16F627:
    // внешний тактовый генератор XT,
    // RA6/RA7 используются для ввода-вывода,
    // внешний сигнал сброса,
    // таймер включен,
    // сторожевой таймер
    // защита кода отключена,
    // детектор
    Unsupported
    MCU selected
    // Служебные
    LCDNybble(char Nybble, char RS)
    // Запись полубайта в

    244 Устройства управления роботами
    LCDByte(char Byte, char RS)
    // Запись байта в
    //
    ЖКИ.
    • const
    // Вывод строки на ЖКИ.
    // Обработчик прерываний:
    void interrupt char temp;
    if
    {
    0;
    RTC++;
    // Обработчик прерываний от таймера
    // Сбросить флаг прерываний от таймера
    // Инкремент счетчика реального времени.
    // Здесь можно разместить дополнительный код
    // для обработки прерываний от таймера TMRO.
    // Проверка времени последнего вызова обработчика
    // и пропуск текущего пакета при
    = (RTC & OxOFF) - ((SaveRTC
    8) & OxOFF);
    if (CurrentRTC < 0)
    CurrentRTC = 0 - CurrentRTC;
    if
    != 0) && (CurrentRTC >
    = 0; // Пропустить текущий пакет.
    // Конечный автомат для ЖКИ:
    } // Конец обработчика прерываний от таймера.
    // Здесь можно другие обработчики прерываний.
    if (INTF) { // Обработчик прерываний по положительному
    // фронту сигнала на выводе RBO/INT.
    if (DataReady) // Предыдущий пакет уже принят?
    ; // Игнорировать импульсы до конца else if (DatalnCount == 0) { // Начало нового пакета.
    DatalnCount = 12; //
    принять 12 импульсов.
    SaveRTC =
    & OxOFF)
    8) + TMRO;
    // Запомнили текущее время.
    = 0;
    } else { // Обработка очередного бита.
    CurrentRTC =
    & OxOFF)
    8) + TMRO;
    // Узнали текущее if
    = CurrentRTC - SaveRTC) < 0)
    SaveRTC = 0 - SaveRTC;
    if
    > 250) && (SaveRTC <
    {
    Dataln = (Dataln
    1) + 1; // Получена 1.
    if
    0)
    DataReady = 1;
    } else if
    > 390) && (SaveRTC <
    {
    Dataln = Dataln
    // Получен О.

    Подключение к микроконтроллеру периферийных устройств 245
    if
    == 0)
    } else // Ошибка.
    DatalnCount = 0;
    SaveRTC = CurrentRTC; // Запомнили текущее время.
    INTF = 0;
    // Сброс флага прерывания.
    } // Конец обработки прерываний по положительному фронту
    // сигнала на входе RBO/INT.
    } // Конец обработчика прерываний.
    //
    программа:
    void int i;
    OPTION = OxOD1;
    = 0;
    = 1;
    = 1;
    //
    работает с таймером
    // коэффициент равен 4.
    // Начальный сброс таймера
    // Разрешение прерываний от таймера TMRO.
    // Разрешение обработки прерываний.
    // Здесь можно проинициализировать другие периферийные устройства.
    // Инициализация порта, к которому подключен
    INTEDG = 1; // Прерывания по положительному фронту сигнала
    // на входе RBO/INT.
    INTE = 1; // Разрешить прерывания по изменению сигнала
    // на выходе RBO/INT.
    while (1 1) { // Бесконечный цикл.
    // Здесь можно разместить код верхнего уровня.
    // Если данные готовы.
    // Ждать готовности ЖКИ.
    if (DataReady) {
    while (LCDState != 0);
    for (i
    = 0; i < 12;
    {
    if
    & (1 7] =
    else
    + 7] =
    Dataln = Dataln
    } // Конец цикла вывода кода принятой команды.
    // Вывести сообщение.
    DataReady = 0; // Сбросить флаг
    // готовности данных.
    } // Конец оператора if.
    } // Конец оператора while.
    } // Конец главной программы.
    Код этой программы может показаться достаточно сложным, но на самом деле в нем не так уж трудно разобраться. Когда на входе RBO/INT микроконтроллера,
    к которому подключен инфракрасный приемник, уровень сигнала изменяется с низкого на высокий, то устанавливается
    INTF и генерируется запрос на

    246 Устройства управления роботами прерывание. В процедуре обработки прерываний проверяется состояние этого фла- га. Если он установлен, значит, источником прерывания послужил вход RBO/INT.
    В таком случае обработчик прерываний по значению счетчика про- веряет, первый ли это импульс. Если значение счетчика нулевое, оно свидетельству- ет о том, что пришел стартовый импульс нового пакета данных. Далее мы загружаем в счетчик число ожидаемых импульсов (то есть значение и запоминаем текущее время, чтобы при следующем вызове определить длительность импульса. Так про- должается до тех пор, пока не будут декодированы все импульсов пакета данных.
    После приема двенадцатого импульса устанавливается флаг
    - та- ким образом главной программе сообщается, что очередная команда дистанцион- ного управления декодирована. Обработчик будет игнорировать все остальные пакеты, пока главная программа, выполнив команду, не сбросит этот флаг.
    Принятая последовательность нулей и единиц для контроля выводится на жидкокристаллический дисплей. Заметим, что перед загрузкой в выводимую строку текста нового сообщения мы проверяем, закончился ли вывод предыдуще- го, чтобы содержимое строки Message случайно не изменилось, пока еще продол- жается ее вывод на дисплей. Если пренебречь этой проверкой, может оказаться,
    что на экране мы увидим начало предыдущей команды и конец следующей.
    В данном случае вероятность такого события не слишком велика, поскольку вывод на дисплей занимает времени намного меньше, чем промежуток между пакетами данных, но мы всегда должны быть готовы к тому, что нам придется модифицировать свои приложения для более сложных задач.
    4.25. СОВМЕЩЕНИЕ РАБОТЫ ДЕТЕКТОРА ОБЪЕКТОВ
    И ПРИЕМНИКА КОМАНД ДИСТАНЦИОННОГО УПРАВЛЕНИЯ
    Итак,
    робот уже умеет обнаруживать объекты и принимать сигналы дистанци- онного управления. В обоих проектах был использован детектор инфракрасного из- лучения. Поэтому будет логично объединить эти две функции в одном устройстве.
    Так как в одном устройстве будут объединены функции по обнаружению близ- ких объектов и приему сигналов дистанционного управления, то придется совме- стить оба типа сообщений на одном жидкокристаллическом дисплее. Сообщения о состоянии детектора объектов и об очередной принятой команде должны будут выводиться в разных частях экрана, не затирая друг друга.
    Сначала я полагал, что для реализации проекта достаточно лишь немного моди- фицировать код обработчика прерываний от таймера, срабатывающего каждую миллисекунду. При каждом его вызове можно было бы проверять состояние входа
    RBO/INT, и, если уровень сигнала на нем активный (низкий), начинать измерение длительности импульса пакета данных, пришедшего от пульта дистанционного управления. Если при входе в обработчик уровень сигнала высокий, можно было бы сгенерировать пакет импульсов частотой 38 кГц для инфракрасного излучателя. Идея казалась достаточно простой, но после нескольких часов безус- пешных попыток заставить все это работать я был вынужден еще раз пересмотреть свои требования к системе, чтобы, наконец, понять, что же я хочу получить.

    Подключение к микроконтроллеру периферийных устройств 247
    При первоначальной реализации проекта оказались допущены две ошибки.
    Во-первых, я забыл о своем решении игнорировать стартовый импульс пакета данных и использовать положительные (задние) фронты остальных двенадцати информационных импульсов для измерения длительности каждого из них. Совер- шенно справедливо посчитав, что раз ширина стартового импульса больше двух миллисекунд, то очередное прерывание от таймера, срабатывающего каждую мил- лисекунду, обязательно зафиксирует начало пакета данных, я забыл, что все еще использую задний фронт стартового импульса для вычисления длительности пер- вого бита в пакете.
    Поэтому в обработчике прерываний, обнаружив низкий уровень сигнала на входе RBO/INT, я разрешал прерывания по положительному перепаду напряже- ния на этом входе, а затем, как и в предыдущей программе, инициализировал счет- чик значением 12, хотя на самом деле надо было ожидать 13 срабаты- ваний обработчика. Устройство начало работать только после того, как я изменил указанное значение на 13 и обеспечил пропуск интервала между двумя первыми срабатываниями (с того момента, когда был замечен низкий уровень сигнала на входе RBO/INT и было разрешено формирование запросов на прерывание по это- му входу, до момента прихода первого такого запроса, соответствующего концу стартового импульса).
    Вторая ошибка была обнаружена при испытании правильности приема команд.
    Иногда в момент нажатия какой-либо кнопки пульта дистанционного управления на экране появлялось сообщение COLLISION, то есть вместо приемника команд сра- батывал детектор столкновений. Виновником ошибки оказался стартовый импульс пакета данных, в момент прихода которого инфракрасный излучатель обнаружите- ля объектов еще не успевал выключиться. Детектор воспринимал начало команды дистанционного управления как сигнал, отраженный от объекта.
    Пришлось сделать так, чтобы детектор реагировал на принятый сигнал только в том случае, если он действует более 3 мс. Так как длительность стартового им- пульса равна 2,4 мс, задержка срабатывания гарантирует, что стартовый будет проигнорирован детектором. Разумеется, уже с самого начало было непро- стительной ошибкой рапортовать о столкновении только на основании первого же срабатывания детектора. Я никогда бы не допустил подобной ошибки, если бы имел дело с механическим детектором столкновений, но, испытывая свои много- членные конструкции, основанные на инфракрасном обнаружителе объектов,
    я уже привык к его высокой надежности, поскольку еще ни разу не видел, чтобы он допускал ложные срабатывания.
    После всех описанных изменений устройство стало работать почти без оши- бок. Однако когда вблизи детектора находился какой-либо объект и в то же время я нажимал любую кнопку пульта дистанционного управления, каждый десятый раз при приеме команды происходила ошибка (единичный бит пакета данных принимался декодером за нулевой).
    Теоретически такая ошибка могла объясняться тем, что во время выполнения фрагмента обработчика прерываний, реализующего вывод сообщений на экран жидкокристаллического дисплея, устройство не успевало правильно измерить ши- рину очередного импульса. Эта идея подтверждалась тем, что ошибка пропадала

    248 Устройства управления роботами при отключении вывода сообщений на экран (или строки COLLISION, или кода принятой команды).
    Проблему можно решить, запретив работу приемника команд дистанционного управления на то время, пока подаются импульсы на светодиод обнаружителя объектов. Это не оказало бы влияния на работу приемника команд, так как пакеты от передатчика команд дистанционного управления повторяются каждые 50 мс,
    и, пропустив один из них, мы всегда имеем возможность принять и декодировать следующий.
    Окончательный вариант программы содержится в файле Code\Combine\com- bine.c:
    // 19 апреля 2002 - обьединение функций детектора столкновений
    // и приемника команд дистанционного управления.
    //
    // 15 февраля 2002 - прием команд инфракрасного пульта
    // дистанционного управления фирмы Sony и отображение их
    // на жидкокристаллическом индикаторе.
    //
    // Для работы инфракрасного детектора столкновений используется
    //
    частотой 38 кГц.
    //
    // Для индикации используется жидкокристаллический дисплей,
    // подключенный к микроконтроллеру через двухпроводной интерфейс
    • // на основе сдвигового регистра 74LS174.
    Формат пакета данных:
    Стартовый бит 1
    +
    +
    I I I I I
    2,4 мс |540мкс|660мкс|540мкс| 1,2 мс
    I
    мс
    |
    мс
    | 300 | 440
    // Замечания по аппаратным средствам:
    // Микроконтроллер PIC16F627 работает на частоте 4 МГц.
    // Используется внешний тактовый генератор.
    //
    // Подключение выводов
    //
    - детектор инфракрасного излучения
    // (прерывания по положительному перепаду);
    //
    - линия Clock интерфейса жидкокристаллического дисплея;
    // RB2 - линия Data интерфейса жидкокристаллического дисплея.
    // Глобальные переменные и константы:
    int RTC = 0; // Счетчик реального времени.
    к микроконтроллеру периферийных устройств 249
    volatile char LCDDlay = 20;
    volatile char LCDState = 1;
    static volatile bit Clock static volatile bit ClockTRIS
    static volatile bit Data static volatile bit DataTRIS
    // Длительность задержки.
    // Номер текущего состояния
    // конечного автомата.
    char
    Указатель на строку выводимого volatile char MessageOuti
    0; //
    текущего символа в строке.
    unsigned int
    // Входной сигнал инфракрасного unsigned char
    = 0; // Число импульсов для unsigned char DataReady = 0; // Число принятых int SaveRTC; // Время последнего int CurrentRTC;
    char
    // Шаблон для вывода декодированной команды.
    =
    // Очистка char Message2[12] =
    volatile char Collision = 0;
    volatile char OldCollision = 0;
    // Сначала обнаруженных нет.
    // Слово defined(_16F627)
    _CONFIG(Ox03F61);
    // Для
    PIC16F627:
    // внешний тактовый генератор XT,
    // RA6/RA7 используются для ввода-вывода,
    // внешний сигнал сброса,
    // таймер включен,
    // сторожевой таймер выключен,
    // защита кода отключена,
    // детектор BODEN включен.
    «else
    (terror Unsupported PICmicro selected
    // Служебные
    LCDNybble(char Nybble, char RS)
    // Запись полубайта в
    Byte, char RS)
    // Запись байта в ЖКИ.
    // Инициализация ЖКИ.
    * const LCDString) // Вывод строки на ЖКИ.
    // Обработчик прерываний:
    void interrupt char temp;

    250 Устройства управления роботами if (TOIF) { // Обработчик прерываний от таймера
    TOIF = 0; // Сбросить флаг прерываний от таймера TMRO.
    RTC++; // Инкремент счетчика реального времени.
    // Здесь можно разместить дополнительный код
    // для обработки прерываний от таймера TMRO.
    Проверка времени последнего вызова обработчика
    // и пропуск текущего пакета при if
    != 0) <
    if ((CurrentRTC = (RTC & OxOFF) -
    ((SaveRTC
    8) &
    < 0)
    CurrentRTC = 0 - CurrentRTC;
    // Сколько прошло времени?
    if (CurrentRTC > 9) { // Слишком много.
    DatalnCount = 0; // Пропустить этот пакет.
    INTE = 0;
    // Запретить прерывания по приходе данных.
    >
    } else if
    &&
    Пришел пакет?
    DatalnCount = 13;
    // Ждем конца стартового импульса
    // и еще 12 информационных импульсов.
    SaveRTC =
    & OxOFF)
    8) + TMRO;
    // Запомнили текущее время.
    INTF = 0; // Сбросить флаг прерывания
    INTE = 1;
    разрешить прерывания по приходе
    // сигнала на вход
    } else
    // Детектор столкновений.
    TRISB3 = 0; // Разрешить вывод while (TMRO < 64); // В течение 64 "тиков"
    // работы таймера TMRO.
    if (!RBO) // Если уровень низкий, то сработал
    // детектор столкновений.
    // Ждем трех срабатываний else
    Collision = 0;
    TRISB3 =
    // Запретить вывод ШИМ-сигнала.
    } // Конец кода для управления детектором столкновений.
    // Конечный автомат для ЖКИ:
    } // Конец обработчика прерываний от таймера.
    // Здесь можно разместить другие обработчики прерываний.
    if (INTF)
    // Обработчик прерываний по положительному
    // фронту сигнала на выводе RBO/INT.
    CurrentRTC =
    & OxOFF)
    8) + TMRO;
    //
    текущее if
    = CurrentRTC - SaveRTC) < 0)

    Подключение к микроконтроллеру периферийных
    251
    SaveRTC
    0 - SaveRTC;
    if
    > 250)
    (SaveRTC <
    {
    1) + 1; // Получена 1.
    if
    0) {
    DataReady
    = 0; // Конец, запретить прерывания,
    } //
    } else if
    > 390)
    (SaveRTC <
    {
    Dataln = Dataln
    1; // Получен О.
    if
    == 0) {
    DataReady = 1;
    INTE = 0; // Конец, запретить прерывания.
    } // endif
    } else if
    != 12) { // Ошибка.
    DatalnCount = 0;
    INTE = 0; // Конец, запретить прерывания.
    } // endif
    SaveRTC =
    // Запомнить текущее время.
    = 0; // Сбросить флаг прерывания.
    } // Конец обработки прерываний по положительному фронту
    // сигнала на входе RBO/INT.
    // Конец обработчика прерываний.
    //
    программа:
    void
    {
    int i;
    OPTION =
    //
    работает с таймером
    // коэффициент деления равен 4.
    TMRO = 0; // Начальный сброс таймера
    TOIE
    // Разрешение прерываний от таймера TMRO.
    = 1; // Разрешение обработки прерываний.
    // Здесь можно проинициализировать другие периферийные устройства.
    // Инициализация порта, к которому подключен ЖКИ.
    = 1; • // Прерывания по положительному фронту сигнала
    // на входе RBO/INT.
    CCPR1L = 13; // Ширина импульсов составляет 50% периода.
    CCP1CON =
    // Включить модуль ШИМ.
    PR2 = 26; // При частоте
    38 кГц
    // период должен быть равен 26
    •TMR2 = 0; // Сброс таймера TMR2.
    T2CON =
    // Включение таймера TMR2,
    // коэффициент
    1:1.
    while (1 == 1)
    // Бесконечный цикл.
    // Здесь можно разместить код верхнего уровня.
    if (DataReady) { // Если данные готовы,
    while (LCDState != 0); // ждать готовности ЖКИ.
    for (i
    = 0; i < 12; i++) {

    252 Устройства управления роботами if.
    & (1
    + 8] =
    else
    + 8] =
    Dataln Dataln
    1;
    } // Конец цикла вывода кода принятой команды.
    // Pass String to Output
    = 0; // Reset the Data Flag
    } // Конец оператора if.
    if
    == 0)
    ==
    OldCollision = Collision; // Запомнить текущее состояние детектора столкновений.
    >
    if
    == 3)
    (OldCollision
    {
    OldCollision = Collision; // Запомнить текущее состояние
    // детектора
    }
    } // Конец оператора while.
    } // Конец главной программы.
    1   ...   16   17   18   19   20   21   22   23   ...   33


    написать администратору сайта