Устройства управления роботами, схемотехника и программирование (М. Предко, 2004). Устройства управления роботами, схемотехника и программирование. Устройствауправления роботамисхемотехника и микроконтроллеров picmicro
Скачать 6.79 Mb.
|
]В ] Катод ]С Рис. 4.27. Семисегментный светодиодный индикатор Формула расчета сопротивления ограничивающего резистора: R - - / где - напря- жение питания; падение напряжения на светодиоде в прямом включении; - номинальный ток, необходимый для свечения светодиода. Таким образом, при = 5 В, 2 В и R 470 Ом ток через светодиод равен 6,4 мА. — Прим. перев. Подключение к микроконтроллеру периферийных устройств 169 Кроме того что при этом уменьшается количество внешних выводов, такое соединение позволяет легко реализовать управление группой одинаковых инди- каторов, как показано на рис. 4.28. Здесь четыре светодиодных индикатора с об- щим катодом подключены к одним и тем же выводам микроконтроллера, а с по- мощью дополнительных выводов осуществляется их включение и выключение. Рис. Подключение светодиодного индикатора к микроконтроллеру Индикаторы включаются по очереди. В каждый момент времени на информа- ционные выходы микроконтроллера выводятся данные, предназначенные для одного индикатора; в это время все остальные отключены, для чего на затворы соответствующих транзисторов подается сигнал низкого уровня. Чтобы не было заметно мерцания светодиодов, каждый из них должен включаться и выключать- ся по крайней мере раз в секунду. Если микроконтроллер управляет четырь- мя индикаторами, то длительность работы каждого из них со- ставляет не более 25% всего времени. Увеличение числа индикаторов приводит к уменьшению той доли времени, в течение которой ток течет через Для управления индикаторами хорошо подходит наш стандартный метод реа- лизации интерфейсных функций с помощью прерываний от таймера, генерируе- мых каждую 1 мс. Соответствующий фрагмент обработчика прерываний: // Управление четырьмя семисегментными светодиодными = 0; // Выключить текущий индикатор. = RTC & 3; // Младшие два бита используются // для адресации индикаторов. DataOut = // Данные для текущего индикатора. ControlPin[01dRTC] = 1; // Разрешить вывод нового символа. Здесь предполагается, что - это порт ввода-вывода, например PORTB микроконтроллера PIC16F627. ControlPin - это массив, состоящий из четырех одноразрядных элементов, которые используются для включения соответствующих Устройства управления роботами индикаторов (в приложении указано, как на языке С описать битовую структу- ру). Массив Data заполняется в главной программе и определяет информацию, отображаемую на индикаторах. При выполнении этой программы каждый индикатор включается примерно 250 раз в секунду, поэтому глаз человека не может заметить мигания светодиодов. УПРАВЛЕНИЕ СВЕТОДИОДНЫМ ИНДИКАТОРОМ Рассмотрим пример схемы и управляющей программы, которая демонстрирует пример подключения светодиодных индикаторов к микроконтроллеру. Допустим, мы хотим, чтобы светодиод, подключенный к выводу RB1 микроконтроллера PIC16F627, зажигался примерно раз в секунду. Здесь мы, как и в предыдущем примере, имеем дело с функциями электронного уровня. Схема подключения показана на рис. 4.29, а в табл. 4.2 перечислены использу- емые в ней элементы. Vcc Vcc Vcc Рис. 4.29. Микроконтроллер управляет Таблица 4.2. Перечень элементов, используемых в схеме на рис. 4.29 Обозначение U1 CR1 R1 R2 а Элемент или PICJ6F84 Светодиод 10 0,25 Вт 470 Ом; 0,25 Вт Керамический резонатор на 4 МГц, имеющий встроенный конденсатор Материалы Примечание Микроконтроллер. Можно использовать отечественный светодиод красного свечения номинал резистора R2 при этом необходимо снизить до 300 Ом Любой видимого диапазона Для «подтягивания» напряжения на выводе _MCLR до напряжения положительной шины питания Для ограничения тока через светодиод Для фильтрации напряжения питания микроконтроллера Для генератора тактовых импульсов микроконтроллера Для не Макетная плата, монтажные провода, питания +5 В Подключение к микроконтроллеру периферийных устройств 171 Схема размещения элементов приведена на рис. 4.30. От рис. 4.3 она ся только наличием светодиода CR1 и резистора R2. При монтаже обратите вни- мание на правильную полярность подключения светодиода. Рис. 4.30. Схема размещения элементов В случае применения микроконтроллера PIC16F627 из схемы надо исключить керамический резонатор; в слове конфигурации для этого МК мы указываем, что используется внутренний тактовый генератор. Управляющая программа лишь в нескольких местах отличается от нашего шаблона. Вы можете найти ее в файле // Включение светодиода каждую секунду. // ' • // Используется прерывание от таймера // генерируемое каждую 1 мс. // // 9 апреля 2002 - последняя модификация. // 28 марта 2002 - адаптировано для МК PIC16F627/PIC16F84. // 23 января 2002 - разработано Майклом Предко. // // Используемое аппаратное обеспечение: // микроконтроллер PIC16F84/PIC16F627, // частота тактирования 4 МГц, МК PIC16F627 использует внутренний тактовый генератор, // сигнал сброса // светодиод подключен к выводу RB1. // // Слово «if defined «warning PIC16F84 selected _CONFIG(Ox03FF1); // Для МК PIC16F84: // кварцевый тактовый генератор, // таймер PWRT включен, // сторожевой таймер выключен, // защита кода отключена. «warning PIC16F627 internal oscillator selected CONFIG(Ox03F70); // Для PIC16F627: // внутренний генератор, // RA6/RA7 используются для ввода-вывода, // внешний сигнал сброса, // таймер включен, // сторожевой таймер выключен, // защита кода отключена, // детектор включен. Unsupported selected // Глобальные переменные и константы: volatile unsigned int RTC = 0; // Счетчик реального времени. static bit trisLEO $ (unsigned) // Биты управления светодиодом. static bit LED (unsigned) const int LEDon = 0; const int LEDoff = 1; // Обработчик прерываний: void interrupt // Включить светодиод. // Выключить светодиод. if { // Обработчик прерываний от таймера TOIF = 0; // Сбросить флаг прерывания от таймера TMRO. // Инкремент счетчика реального времени. // Здесь можно разместить дополнительный код // для реализации функций электронного и механического уровней, // которые надо выполнять каждую 1 мс. if ( ( RTC % 512 ) == 0 ) LED = LED " 1; // Переключать состояние светодиода каждые 512 мс. > // Конец обработчика прерываний от таймера TMRO. // Здесь можно разместить другие обработчики прерываний. // Конец обработки прерываний. // Служебная void enableLED(int LEDstate) // Установить состояние вывода LED // в соответствии с LEDstate. LED = LEDoff; // Сначала светодиод if (LEDstate) trisLED = 0; // Вывод МК, управляющий состоянием // светодиода, теперь работает как else trisLED = 1; // Вывод МК, управляющий состоянием // светодиода, теперь работает как входной. I Подключение к микроконтроллеру периферийных устройств 173 // Главная программа: void = 0; OPTION OxOD1; 1; = 1; // Начальный сброс таймера TMRO. // Предделитель будет работать с TMRO, // коэффициент деления равен 4. // Разрешить прерывания от таймера TMRO. // Разрешить обработку всех прерываний. // Здесь можно разместить дополнительный код для управления // периферийными устройствами. // Вначале светодиод должен while (1 == 1) { // Бесконечный цикл. // Здесь можно разместить код, // реализующий функции биологического уровня. } // Конец биологического кода. } // Конец главной программы. По сравнению с описанным в начале главы шаблоном программы, здесь внесе- ны следующие изменения: • добавлены комментарии, относящиеся к управлению состоянием светодиода; • описаны те биты аппаратных регистров, которые используются для управле- ния светодиодом, и объявлены константы, служащие для переключения его состояния; • для определения момента переключения светодиода в противоположное со- стояние используется операция взятия остатка % от деления текущего значе- ния счетчика реального времени на 512. Это приводит к тому, что состояние светодиода изменяется каждые 512 мс. Напомним, что записываемое в выход- ной порт значение защелкивается во внутреннем регистре и изменяет факти- ческое состояние вывода только в том случае, если этот вывод сконфигури- рован для работы в качестве выходного; • для управления состоянием вывода, к которому подключен светодиод, ис- пользуется функция enableLED. Если надо включить светодиод, эта функ- ция должна быть вызвана с ненулевым параметром - тогда вывод, к которо- му подключен светодиод, переводится в режим выходного и состояние светодиода (горит или не горит) устанавливается в зависимости от последне- го записанного в порт значения. Если надо потушить светодиод, данная функ- ция вызывается с нулевым значением тогда вывод, к которому подключен светодиод, переводится в режим входного. В этом случае любая записываемая в порт информация не может включить светодиод; • начальное состояние светодиода задается при старте программы вызовом функции enableLED (1); Эта программа убедительно демонстрирует, как необходимо разделять выпол- нение функций электронного и биологического уровней. Нигде в главной програм- ме, содержащей биологический код, мы не обращаемся к аппаратным регистрам 174 Устройства управления роботами микроконтроллера. Непосредственное управление светодиодом производится в про- цедуре обработки прерываний. Возможно, вам захочется упростить предложенную программу. Для этого нет необходимости изменять обработчик прерываний, а в текст главной программы надо добавить строки: LED = LEDoff; // Сначала выключен. trisLED = 0; // Вывод LED является while (1 == 1) { . if ((RTC % 512) 0) { // Прошло 0,5 с? LED = LED " 1; // Да, переключить светодиод. while ( ( RTC % 512 ) == 0 ) ; // Ждать изменения счетчика реального времени. Этот код проще понять, и он несколько короче. Но представьте, что будет, если мы должны управлять многими внешними устройствами? Мы хотим иметь воз- можность разрабатывать и отлаживать различные интерфейсы независимо друг от друга, поэтому первоначальный вариант лучше подходит для нашей цели. Еще один вопрос, который может возникнуть у внимательного читателя, - почему состояние светодиода изменяется каждые 512, а не 500 мс. Вы можете попробовать изменить это значение и проверить, какой длины машинный код будет сгенерирован компилятором Lite. Он окажется почти в два раза длин- нее! Дело в том, что при включенном режиме оптимизации компилятор PICC Lite использует эффективные алгоритмы для упрощения машинного кода. Без оптимизации результат компиляции фрагмента программы if ( ( RTC % 500 ) == 0 ) LED = LED 1; выглядит примерно так: Вычислить остаток от деления RTC на О О и запомнить результат в служеб- ной переменной temp. 2. Если temp равно нулю, то инвертировать LED. Выполнение первого требует использования библиотечной функции для реализации операции деления. Дело в том, что в системе команд микрокон- троллеров отсутствует машинная команда для выполнения этой опера- ции, поэтому компилятор вынужден заменять ее на вызов заранее подготовлен- ной подпрограммы, которую в таком случае необходимо добавить к машинному коду программы. Это увеличивает объем программы и время ее выполнения. Но если делитель является степенью двойки (как, например, число 512), то можно использовать формулу А % В = А & (В - при В = Тогда приведенный фрагмент программы на языке С может быть представлен в виде if ( ( RTC & 511 ) 0 ) LED = LED 1; Подключение к микроконтроллеру периферийных 175 Другими словами, для проверки того, делится ли заданное число на 512 (или любую другую степень двойки), компилятор при включенной оптимизации мо- жет заменить длинную операцию деления и получения остатка на короткую по- разрядную операцию AND с битовой маской, которая находится вычитанием еди- ницы из константы, задающей значение делителя. Этот вариант при компиляции генерирует более короткий код и к тому же не требует никаких дополнительных подпрограмм. Разумеется, пока рассматривае- мые программы достаточно просты и нет особой необходимости экономить про- граммную память, но разработчик может столкнуться с проблемами, если захочет добавить к данному примеру более сложные функции. Поэтому в любом случае следует выбирать самое эффективное решение. После успешной компиляции нашего приложения вызовите на Рабочий стол интегрированной среды MPLAB окно Stopwatch и загрузите файл кон- фигурации окна просмотра который находится в папке Code\ Procwat. Создайте еще одно окно Watch для просмотра значения счетчика реального времени RTC (при желании произведите необходимые настройки самостоятельно или же воспользуйтесь файлом RTC.WAT). Внешний вид окна MPLAB после всех необходимых приготовле- ний показан на рис. 4.31. // End enableLED // // // Reset the Timer for Start // Assign to // Prescaler is Enable Timer Interrupts // Enable Interrupts - 0; - - 1; - 1: / Put hardware interface initialization code here // start the LED Flashing Address Symbol 200 status 81 fsr option reg intcon flddress Symbol RTC 106 1 Sim Рис. Окно MPLAB перед началом моделирования 176 Устройства управления роботами Теперь надо щелкнуть мышью где-нибудь внутри окна с исходным текстом программы на языке С (чтобы оно получило фокус ввода) и выполнить сброс микроконтроллера. Напомним, что для этого можно использовать команды глав- ного меню Debug Run Reset (Отладка Старт Сброс) или нажать кла- вишу F6. В результате первая выполняемая строка нашей программы подсветит- ся, и все будет готово для начала пошаговой отладки. Один шаг отладки выполняется с помощью команды Debug Run Step (Отладка Старт Шаг) или при нажатии клавиши F7. С каждым выполненным шагом подсветка перемещается на следующую строку программы. Когда выполнение дойдет до вызова функции мы увидим, что подсветка перемещается в начало программы, показывая процесс выполнения всех операторов этой функции, а за- тем снова возвращается в основную программу. В конце концов мы попадем в бесконечный цикл = и единствен- ное, что будет меняться на экране при нажатии F6, - это значение счетчика ко- мандных циклов в окне Stopwatch и значение счетчика таймера в окне просмотра содержимого регистров микроконтроллера. Чтобы продолжить процесс отладки в менее скучном режиме, щелкните правой кнопкой мыши по строке \ TOIF = 0; - в самом начале процедуры обработки прерываний от таймера. На экране появит- ся контекстное меню (рис. 4.32), в котором надо выбрать команду Break Point(s) (Точка (точки) останова). В результате соответствующая строка будет выделена красным цветом. Задав точку останова, можно продолжить выполнение программы в свободном (не пошаговом) режиме. Для этого воспользуйтесь командой меню Debug Run Run (Отладка Выполнить Выполнить) или просто нажмите клавишу F9. Программа продолжит работу в автоматическом режиме, но затем будет останов- лена перед тем, как выполнить строку, подсвеченную красным цветом. Когда я проводил отладку программы, то останов произошел во время 1087-го командного цикла, то есть на 1,09-й миллисекунде. Это чуть больше, чем можно было бы ожидать. Разница объясняется тем, что перед инициализацией контрол- лера прерываний и таймера проходит некоторое время. После того как я снова нажал клавишу F9, останов программы пришелся на команд- ный цикл, что ровно на 1024 циклов больше, чем в первый раз. Это что выполнение прерываний от таймера TMRO моделируется Уберите точку останова, опять же щелкнув правой кнопкой мыши и выбрав команду Break Point(s). Теперь поставьте точку останова в строке, изменяющей состояние светодиода: LED = LED 1; Нажмите клавишу F9 и ждите, пока выполнение не дойдет до контрольной точки. После этого в окне Watch проверьте состояние порта PORTB. Оно будет подсвечено синим цветом. Нажав F7, выполните еще один шаг; только теперь Подключение к микроконтроллеру периферийных устройств 177 interrupt // Interrupt Handler // Reset Interrupt Flag the or 1 interrupt here // Put LED - LED // Toggle LED Bit // Put interrupt handlers for other interface code 200 03 status fsr Address Ualue option_reg intcon MHz On Close I Help I Рис. 4.32. Указание точек останова PORTB выделится красным. Значит, в результате выполнения последнего шага значение регистра изменилось. В данном случае первый его бит (считая с нуля) изменил свое состояние с 1 на 0. Для нашего устройства это значит, что светодиод загорелся. В моих экспериментах загорание светодиода произошло на 524368-м коман- дном цикле. При использовании микроконтроллера PIC16F627, работающего на тактовой частоте 4 МГц, момент срабатывания таймера на самом деле может на ; 5-10% отличаться от заданного в программе значения. Разумеется, если инди- • кация предназначена для человека, то такая погрешность не имеет особого зна- чения. Теперь вам уже известна приблизительно половина тех сведений, которые не- бходимо знать для отладки приложений. Мы обсудили самые необходимые чуть позже, при рассмотрении следующих конструкций, описанных в этой затронем и другие важные вопросы. ' Автору повезло. Приращение счетчика командных циклов между прерываниями обычно на один цикл в ту или другую сторону отличается от точной величины поэтому в наших экспериментах оно никогда не принимало четного значения. - Прим. 178 Устройства управления роботами Убедившись в правильности программы, пора проверить работу схемы. Я со- ветую всегда проводить моделирование программы с помощью встроенного в MPLAB симулятора, прежде чем начинать программирование настоящего мик- роконтроллера. Но еще перед началом проектирования программы желательно со- брать саму схему. Дело в том, что в процессе сборки вы можете для удобства или по необходимости изменить некоторые внешние соединения, например подклю- чить светодиод к другому выводу микроконтроллера. В нашем простом примере для таких изменений нет особого повода, но в сложных случаях, когда к микро- контроллеру подключается большое количество периферийных устройств, всегда лучше иметь возможность маневра. После загрузки программы в микроконтроллер отключите его от программа- тора и вставьте в схему. Включите питание и убедитесь, что светодиод мигает приблизительно один раз в секунду. Если что-то не так, вам придется внимательно проверить правильность всех соединений и наличие необходимых уровней напряжения на выводах микрокон- троллера. Обратите внимание на полярность включения светодиода. Не разбирайте устройство после тестирования, оно потребуется нам для сле- дующего проекта. |