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

  • 4.13. УПРАВЛЕНИЕ ЯРКОСТЬЮ СВЕТОДИОДНОГО ИНДИКАТОРА

  • Рис. 4.34.

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


    Скачать 6.79 Mb.
    НазваниеУстройствауправления роботамисхемотехника и микроконтроллеров picmicro
    АнкорУстройства управления роботами, схемотехника и программирование (М. Предко, 2004).pdf
    Дата29.08.2017
    Размер6.79 Mb.
    Формат файлаpdf
    Имя файлаУстройства управления роботами, схемотехника и программирование .pdf
    ТипРеферат
    #8441
    КатегорияПромышленность. Энергетика
    страница15 из 33
    1   ...   11   12   13   14   15   16   17   18   ...   33
    4.12. ИСПОЛЬЗОВАНИЕ
    МОДУЛЯЦИИ ДЛЯ УПРАВЛЕНИЯ
    АНАЛОГОВЫМИ УСТРОЙСТВАМИ
    Микроконтроллеры как и большинство других цифровых микросхем,
    не слишком-то приспособлены для непосредственного управления аналоговыми устройствами. Особые трудности возникают, если выходное устройство потреб- ляет слишком большой ток. Самый простой способ решения проблемы заключа- ется в использовании последовательности импульсов одинаковой амплитуды и частоты, но изменяющейся длительности (ширины), то есть так называемой ши-
    модуляции (ШИМ, Pulse Width Modulation - PWM). Обычно именно этот способ применяется для управления двигателями постоянного тока или для вывода аналоговых сигналов нужной величины.
    Ширина импульса
    Период
    Г
    Рис. 4.33.

    Подключение к микроконтроллеру периферийных устройств
    Пример сигнала, подвергнутого широтно-импульсной модуляции, представлен на рис. 4.33.
    Для генерации можно использовать следующий код:
    Period PWMPeriod;
    On
    // Параметры выходного сигнала: длительность
    // периода и длительность while ( 1 == 1 ) {
    = ON;
    for
    ( i = 0; i < On; i++ );
    PWM OFF;
    // Бесконечный цикл.
    // Подать очередной импульс.
    // Держать высокий уровень в течение
    // времени, заданного значением On.
    // Закончить импульс.
    for ( ; i < PWMPeriod; i++ ); // Ждать до конца периода.
    >
    Здесь
    - имя вывода (то есть бита выходного порта), с которого должен сниматься
    Это простая программа, но ее трудно совместить с ка- кими-либо другими задачами, которые, возможно, должен выполнять робот. По- этому, как обычно, нам придется вынести функцию электронного уровня в проце- дуру обработки прерываний от таймера:
    void interrupt
    (void) // Обработчик прерываний.
    if
    ( PWM
    ON
    ) {
    PWM OFF;
    TMRO PWMPeriod - PWMOn;
    else {
    PWM = ON; // в противном случае сделать уровень высоким
    TMRO = PWMOn; // и установить таймер.
    // Если сейчас высокий уровень, то
    // сделать его низким
    // и установить таймер,
    ) // Конец обработчика прерываний.
    Здесь мы изменяем значение счетчика таймера, чтобы следующий запрос на прерывание возник в тот момент, когда надо будет переключить уровень выход- ного сигнала на противоположный. Выглядит все очень неплохо, но этот код ни- куда не годится! Мы монополизировали аппаратный ресурс (таймер TMRO), ис- ключив для других задач возможность работы с ним.
    Программа, приведенная в следующем разделе, будет построена немного по- другому, и тогда мы покажем, как лучше работать с таймером для решения нашей задачи.
    Если ШИМ-сигнал используется для управления двигателем, то при выборе его частоты следует убедиться, что она лежит за пределами слышимого диапазо- на, то есть превышает 20 кГц, иначе при работе робот будет издавать не слишком приятные звуки (с другой стороны, следует иметь в виду, что не воспринимаемые человеком ультразвуковые колебания могут оказывать неблагоприятное воздей- ствие на животных, например на собак).

    180 Устройства управления роботами
    Если выбрать очень высокую частоту, то некоторые устройства (да и сам мик- роконтроллер) могут оказаться не в состоянии реагировать на слишком частые переключения.
    Для всех рассмотренных в книге примеров есть возможность уменьшить период срабатывания таймера TMRO, чтобы можно было генерировать более высокочастот- ный сигнал, но при этом могут возникнуть проблемы с другими периферийными
    В итоге вы даже можете решить, что разумнее было бы разработать какую-либо специальную схему, работой которой можно было бы управлять с помо- щью микроконтроллера и которая позволяла бы формировать высокочастотный
    Но лучше всего использовать для этих целей специальный модуль
    ШИМ, имеющийся во многих микроконтроллерах PICmicro среднего семейства.
    Другое очевидное решение задачи заключается в том, чтобы работать на часто- тах, которые лежат ниже слышимого диапазона. Многие производители исполь- зуют частоты 30-60 Гц. Однако в таком режиме допустимо управлять только дви- гателями малой мощности, рабочий ток которых не превышает 500 мА, иначе могут возникнуть проблемы с вибрацией, вызываемой из-за низкой частоты вклю- чения-выключения двигателей. Низкочастотные может генериро- вать даже PIC16F84, не для этого специальных аппаратных средств.
    4.13. УПРАВЛЕНИЕ ЯРКОСТЬЮ
    СВЕТОДИОДНОГО ИНДИКАТОРА
    На основе нашего предыдущего проекта в этой главе мы продемонстрируем, как мик- роконтроллер может управлять аналоговыми устройствами. Допустим, имеются три светодиода, и мы хотим независимо задавать яркость свечения каждого из них.
    Схема устройства показана на рис. 4.34, схема размещения элементов на ма- кетной плате - на рис. 4.35, а перечень использованных элементов приведен в табл. 4.3.
    Рис. 4.34. Принципиальная схема
    яркостью свечения индикаторов

    Подключение к микроконтроллеру периферийных устройств 181
    Рис. 4.35. Схема размещения элементов устройства управления
    яркостью свечения индикаторов
    4.3. Перечень использованных
    - CR3
    а
    Элемент
    470 Ом;
    0,25 Вт
    Керамический резонатор
    на 4 МГц, имеющий
    встроенный конденсатор
    Материалы
    Примечание
    Микроконтроллер
    Любые видимого диапазона
    Для «подтягивания»
    на выводе _MCLR
    до напряжения положительной шины питания
    Для ограничения тока через
    Для фильтрации напряжения питания
    микроконтроллера
    Для генератора тактовых импульсов микроконтроллера
    PIC16F84. Для PIC16F627 не требуется
    Макетная плата, монтажные провода, источник питания +5 В
    Для подключения трех светодиодов мы отвели выводы
    - RB3. Надеюсь,
    вы еще не макет предыдущего устройства, так как наш новый проект отличается от него всего лишь двумя новыми светодиодами. Для управления яр- костью их свечения мы будем использовать сигнал частотой 32 Гц. Это очень низкая частота, особенно если учесть, что микрокон- троллер PIC16F627 имеет встроенные аппаратные средства для генерации сигна- лов достаточно высокой частоты. Но способы их применения мы рассмотрим в наших следующих проектах.
    Заметим, что возможность независимой генерации сразу нескольких ШИМ-сиг- важна для управления скоростью вращения разных электродвигателей. В этом случае можно управлять направлением движения и избежать проскальзывания колес. К сожалению, микроконтроллер PIC16F627 имеет всего один модуль
    ШИМ и не может генерировать несколько независимых сигналов. Поэтому такую функцию приходится реализовывать программно. Зато

    182 Устройства управления роботами при этом остается возможность использовать модуль ШИМ для других целей,
    например для инфракрасного детектора столкновений.
    Но вернемся к нашему проекту. Сначала я реализовал управление только одним светодиодом CR1, подключенным к выводу RB1 микроконтроллера. Как и в пре- дыдущих наших программах, функция электронного уровня реализована в проце- дуре обработки прерываний от таймера.
    Приведенную ниже программу вы найдете в электронном приложении к этой книге в файле
    // Управление яркостью свечения светодиодного индикатора,
    // подключенного к выводу RB1, с помощью
    //
    // Используется прерывание от таймера генерируемое каждую 1 мс.
    // Частота ШИМ-сигнала 32 Гц.
    //
    // 28 марта 2002 - адаптировано для PIC16F627/PIC16F84.
    // 23 января 2002 - разработано Майком Предко.
    //
    // Используемое аппаратное обеспечение:
    // микроконтроллер PIC16F84/PIC16F627,
    // тактовая частота 4 МГц,
    // МК PIC16F627 использует внутренний тактовый генератор,
    // внешний сигнал сброса
    // светодиод подключен к выводу RB1.
    // Слово конфигурации:
    defined
    PIC16F84
    _CONFIG(Ox03FF1);
    flelif
    PIC16F627
    CONFIG(Ox03F70);
    «else
    Unsupported selected
    // Для МК PIC16F84:
    // Кварцевый тактовый генератор,
    // таймер включен,
    // сторожевой таймер выключен,
    // защита кода отключена.
    with internal oscillator selected
    // Для МК PIC16F627:
    // внутренний тактовый генератор,
    // RA6/RA7 используются для ввода-вывода,
    // внешний сигнал сброса,
    // таймер включен,
    // сторожевой таймер выключен,
    // защита кода отключена,
    // детектор BODEN включен.
    selected
    // Глобальные переменные и константы:
    volatile int RTC = 0; // Счетчик реального времени.
    char
    // Счетчик циклов (от 0 до 29).

    Подключение к микроконтроллеру устройств 183
    char volatile int
    // Длительность импульса.
    // Счетчик периодов static bit trisLED
    (unsigned) &TRISB*8+1;
    // Биты управления выводом RB1,
    static bit LED
    (unsigned)
    const int LEDon = 0;
    const int
    = 1;
    // Обработчик прерываний:
    void interrupt
    // Включить
    // Выключить светодиод.
    if
    { // Обработчик прерываний от таймера
    TOIF = 0; // Сбросить флаг прерывания.
    // Инкремент счетчика реального времени.
    // Здесь можно разместить дополнительный код
    // для обработки прерываний от таймера.
    { // Проверить на крайние значения.
    case 0: // Если задана нулевая ширина импульсов,
    LED = LEDoff; // то держать низкий break;
    case 29: // Если ширина импульсов равна периоду,
    LED = LEDon; // то держать высокий break;
    default:
    противном случае:
    // если значение счетчика циклов
    // меньше заданной ширины импульса,
    if
    <= PWMDuty)
    LED = LEDon;
    // то держать высокий уровень,
    else // в противном случае уровень низкий.
    LED = LEDoff;
    // Конец оператора switch.
    }
    if
    == 30) {
    PWMCycle = 0;
    PWMLoop++;
    // Конец текущего периода?
    // Да, сброс счетчика циклов
    // и инкремент счетчика периодов.
    // Здесь можно разместить код для обработки других прерываний.
    // Конец обработки прерываний.
    // Служебная void enableLED(int LEDstate)
    // Установить состояние светодиода
    // в соответствии со значением LEDstate.
    // Сначала светодиод не горит.
    LED = LEDoff;
    if (LEDstate) {
    PWMCycle = 0; // Обнулить счетчик циклов.
    PWMDuty = 29; // Сначала ширина импульсов равна периоду.
    PWMLoop = 0; // Счетчик периодов равен 0.

    184 Устройства управления роботами trisLED = 0; //
    управления светодиодом
    // переведен в режим выходного.
    > else trisLED = 1; // Вывод управления светодиодом
    // переведен в режим входного,
    //
    потушен.
    } // Конец служебной подпрограммы.
    // Главная программа:
    void
    OPTION = OxOD1; //
    работает с таймером
    // коэффициент деления равен 4.
    = 0; // Начальный сброс таймера
    TOIE = 1; // Разрешить прерывания от таймера.
    GIE = 1; // Разрешить обработку прерываний.
    // Здесь можно разместить код для инициализации
    // других периферийных устройств.
    // Включить светодиод
    // и выполнить инициализацию параметров.
    while (1 == 1) ( // Бесконечный цикл (биологический код).
    // Здесь можно разместить код для реализации
    // функций биологического уровня.
    // Алгоритм изменения ширины импульсов во времени:
    if
    == 2) { // Каждые две if
    == 0)
    = 29; //
    ширина else
    // Уменьшить ширину импульсов.
    PWMLoop
    II Сбросить счетчик периодов.
    } // Конец главной программы.
    В этой программе один период выходного сигнала делится на 30 подынтерва- лов. Длительность периода выбрана равной 32 Гц,
    дли- тельность одного подынтервала - около 1 мс, то есть в точности равна промежут- ку между срабатываниями таймера TMRO.
    Ширина импульсов задается значением переменной PWMDuty, оно может быть от 0 (все время низкий уровень сигнала, импульсы отсутствуют, светодиод поту- шен) до 29 (ширина импульсов равна периоду, все время высокий уровень управ- ляющего сигнала, светодиод горит с максимальной яркостью).
    Каждый раз при срабатывании таймера производится инкремент счетчика циклов его текущее значение сравнивается с величиной PWMDuty и по результатам сравнения формируется низкий или высокий уровень управляюще- го сигнала. Как только счетчик циклов становится больше 29, он обнуляется, и на- чинается новый период.

    Подключение к микроконтроллеру периферийных устройств 185
    Для изменения яркости свечения светодиодного индикатора с течением вре- мени используется счетчик периодов
    При запуске программы уста- навливается максимальная яркость
    29), затем она постепенно уменьшается пока не достигнет нулевой отметки. После этого счет- чик периодов обнуляется, и все повторяется с самого начала.
    После выполнения моделирования работы этой программы с помощью симу- лятора MPLAB и загрузки ее в микроконтроллер можно проверить, что светоди- од чуть уменьшает яркость свечения каждые 2 с, пока не погаснет совсем, после чего вспыхивает с максимальной яркостью. Благодаря инерционности челове- ческого глаза мы не замечаем мигания светодиода, которое происходит с частотой
    32 Гц. При уменьшении той доли в течение которого ток протекает через светодиод, нам кажется, что он горит менее ярко.
    Испытав описанный проект в работе, я добавил к микроконтроллеру еще два светодиода и, разумеется, внес необходимые изменения в управляющую програм- му. Можно предложить по крайней мере четыре способа добавления новых неза- висимых выходов для генерации и я испытал все четыре.
    Первый светодиод, подключенный к выводу микроконтроллера, как и преж- де, должен был уменьшать яркость свечения каждые 2 с. Второй светодиод, под- ключенный к выводу RB2, должен был делать то же самое, но с периодом 5 с.
    Наконец, третий светодиод, подключенный к выводу RB3, должен был увеличи- вать свою яркость каждые 7 с.
    Первый (экстенсивный) способ добавления новых независимых выходов к наше- му устройству заключается в том, что в процедуре обработки прерываний от таймера дописывается код, относящийся к новому ШИМ-генератору, который в точности дублирует тот, что уже имеется для реализации предыдущего. Соответствующим образом измененный текст программы для управления двумя светодиодами вы най- дете в файле Code\Ledpwm\ledpwm2.c, а для управления тремя светодиодами - в файле
    Но это не слишком изящное решение. Гораздо привычнее в этом случае было бы использование массивов. Как известно, индексы элементов массивов в языке С
    нумеруются с 0, поэтому, чтобы не менять нумерацию светодиодов и избежать лишних вычислений, в программе проще указать размер массивов на 1 больше требуемого и не использовать нулевой элемент.
    В этом случае текст обработчика прерываний от таймера выглядит следующим образом:
    for
    1 < 4; i++) {
    case 0:
    writeLED(i break;
    case 29:
    break; ,
    default:
    // Повторять для трех светодиодов.
    // Проверка на крайние значения.
    // Нулевая ширина импульсов.
    LEDoff);
    // Ширина импульсов равна периоду.
    // В противном случае:
    if
    <=
    LEDon);

    186 Устройства управления роботами else
    LEDoff);
    } // Конец оператора switch.
    if
    30) { // Конец периода?
    = 0; // Да.
    // Инкремент счетчика периодов.
    }
    } // Конец цикла.
    Как видим, здесь первоначальный текст лишь немного изменен, чтобы можно было работать с элементами массивов. Но еще здесь фигурирует вызов некоей функции
    На самом деле это не функция, а макрос:
    value)
    ( (PORTB) = (PORTB &
    | (value * (1
    )
    Параметрами макроса являются номер разряда регистра и флаг, который ука- зывает, надо ли этот разряд сбросить в 0 или установить в Сначала нужный бит сбрасывается с помощью поразрядной операции AND, а затем в результате выпол- нения поразрядной операции OR с подготовленной битовой маской принимает нужное значение.
    Аналогичные макросы можно использовать и для чтения отдельных разрядов регистра:
    readLED(bit) (PORTB & (1
    Описанный способ наращивания количества выходов будем называть про-
    граммным циклом.
    Если вы выполните моделирование измененной программы с помощью симу- лятора, то, вероятно, удивитесь тому, какого количества командных циклов по- требует изменение состояния разрядов порта PORTB. Возможно, это из-за неэф- фективной реализации нашего макроса? Чтобы решить эту проблему, придется манипулировать битами явно:
    void writeLED(int LEDbit, int value) // Запись указанного бита.
    ,
    {
    case
    LED1 = value;
    break;
    case 2:
    LED2 = value;
    break;
    case 3:
    LED3 = value;
    break;
    Назовем этот способ циклом с переключателем. Соответствующим образом измененный код программы можно найти в файлах и

    Подключение к микроконтроллеру периферийных устройств 187
    Еще один способ заключается в том, чтобы не отказываться от макросов, но изменить способ доступа к отдельному биту регистра. Возможно, компилятор
    Lite не слишком эффективно реализует операцию умножения на (1
    которая была указана в нашем предыдущем макросе, поэтому можно попы- таться использовать условный оператор:
    value)
    if (value == 0) PORTB
    "(1
    bit); else
    (1
    bit);
    Здесь мы сначала проверяем значение параметра value, а затем либо сбрасы- ваем, либо устанавливаем нужный бит. Полный текст программы вы найдете в файле
    Для работы с двумя светодиодами достаточ- но только уменьшить на единицу количество повторений цикла заменив 4 на 3.
    Назовем этот способ модифицированным программным циклом.
    В табл. 4.4 проведено сравнение всех четырех способов наращивания числа независимых по четырем показателям: размеру обработчика пре- рываний, размеру главной программы, размеру всего приложения и количеству циклов, требуемых для обработки каждого запроса на прерывание.
    Таблица 4.4. Сравнительная характеристика различных способов
    наращивания количества программных модулей ШИМ
    Имя Количество Метод Размер Размер
    программы
    обработчика главной всего
    прерывания программы приложения
    I
    I
    I,
    }
    2
    3
    2
    3
    2
    3
    2
    3
    Базовый код
    Копирование кода
    Копирование кода
    Программный цикл
    Программный цикл
    Цикл
    с переключателем
    Цикл
    с переключателем
    Модифицированный
    программный цикл
    Модифицированный
    цикл
    63
    86
    109
    179
    116
    116
    133
    44
    80
    116
    140
    152
    210
    256
    166
    225
    319
    326
    372
    235
    Количество
    требуемых для
    обработки
    прерываний
    36
    50
    64
    151
    214
    157
    223
    147
    210
    При использовании экстенсивного способа (копирование кода) размер обра- прерываний увеличивается на 23 машинных команды при каждом добав- одного выхода, а количество командных циклов, требуемых на обработку увеличивается на 14. Как и следовало ожидать, размер обработчика при использовании программного цикла не зависит от количества выходов, но его выполнения увеличивается на 63 командных цикла на каждый добавля- выход. Цикл с переключателем также не увеличивает размер обработчика при

    188 Устройства управления роботами добавлении новых светодиодов, но требует 66 циклов на каждый новый выход.
    Как видим, наш первый вариант макроса не слишком-то плох: явное обращение к отдельным разрядом регистра менее эффективно. Наконец, при использовании программного цикла с модифицированным макросом размер обработчика снова не зависит от количества светодиодов, а время его выполнения увеличивается на
    63 для каждого нового светодиода.
    Модификация макроса почти не повлияла на время выполнения обработчика прерываний, но позволила заметно уменьшить размер кода.
    На рис. 4.36 показано, как растет размер обработчика прерываний при увели- чении числа программно реализованных модулей ШИМ. Как видим, простое ко- пирование кода при не слишком большом количестве выходов эффективнее всех остальных методов. Поскольку немногие роботы имеют количество двигателей,
    большее то для управления ими можно рекомендовать наш самый первый метод. Только если количество независимых превышает шесть, копирование становится менее эффективным, чем программный цикл,
    с точки зрения размера обработчика прерываний.
    1   ...   11   12   13   14   15   16   17   18   ...   33


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