Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода » Программирование устройств на PIC микроконтроллерах


Логин:
Пароль:
О сайте:

Pic.Rkniga.ru - Сайт как для начинающих, так и для опытных радиолюбителей, разрабатывающих свои устройства на популярных PIC микроконтроллерах.
Здесь можно обмениваться сообщениями на форуме, а также добавлять на сайт статьи и схемы своих устройств.

Меню сайта
Главная Форум по PIC микроконтроллерам Форум Статьи по PIC микроконтроллерам Статьи Справочная информаци по PIC микроконтроллерам Справочник Литература по PIC микроконтроллерам Литература Схемотехника Схемотехника устройств на PIC микроконтроллерах Микроконтроллеры Программаторы Все по программированию PIC микроконтроллеров Программы, Софт Программы Ссылки
Опрос

Сколько лет вы занимаетесь программированием PIC микроконтроллеров?


от 0-1 года
1-3 года
3-5 лет
5-10 лет
более 10


Последние материалы
  • Тестовая плата для отладки программ на микроконтроллере PIC18F4550
  • Кнопка On/OFF на PIC12F629.
  • Часы с синхронизацией от китайского будильника
  • ШИМ регулятор на PIC16F628A.
  • Счетчики прямого и обратного счета на PIC16F628A.
  • Таймер отключения питания для мультиметра и не только.
  • Измеритель напряжения и тока
  • Маршрутный компьютер для электровелосипеда
  • Простой двухканальный термометр на PIC16F690 и датчиках DS18B20
  • Электронная "Незабудка" для забывчивых
  • Популярные материалы
    Случайная книга
    Программирование устройств на PIC микроконтроллерах » Справочник » Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Автор публикации: alex Просмотров: 28251 Добавлен: 27-09-2012, 14:07 Комментарии: 0

    Содержание
    1. Обзор 16-битных PIC-микроконтроллеров
    2. Архитектура микроконтроллеров PIC24F
    3. Система команд и основы программирования микроконтроллеров PIC24F
       3.1 Программная модель микроконтроллеров PIC24F
       3.2 Режимы адресации и система команд
    4. Программирование портов ввода-вывода
       4.1 Аппаратно-программная архитектура портов ввода/вывода
       4.2 Программирование портов ввода/вывода
       4.3 Модуль регистрации событий
    5. Программирование прерываний
    6. Программирование таймеров
       6.1 Практическое использование 16-битных таймеров
       6.2 Работа таймеров в 32-битном режиме
    7. Интерфейс SPI микроконтроллеров PIC24F
       7.1 Аппаратно-программная реализация SPI в микроконтроллерах PIC24F
       7.2 Практическое программирование обмена данными по SPI
    8. Интерфейс I2C микроконтроллеров PIC24F
       8.1 Принципы функционирования интерфейса I2C
       8.2 Модуль интерфейса I2C микроконтроллеров PIC24F
       8.3 Практическое использование интерфейса I2C
    9.Программирование интерфейса PMP
       9.1 Режимы работы PMP
       9.2 Практические примеры программирования интерфейса PMP
    10. Последовательный интерфейс микроконтроллеров PIC24F
       10.1 Аппаратно$программная архитектура UART
       10.2 Практическое использование последовательного порта
    11. Обработка аналоговых сигналов в микроконтроллере PIC24F
       11.1 Программная модель интегрированного АЦП
       11.2 Практическое использование модуля АЦП
       11.3 Использование внешнего АЦП
    12. Генерация аналоговых и цифровых сигналов
       12.1 Модуль генерации цифровых сигналов
       12.2 Аналоговые компараторы в микроконтроллерах PIC24F

         Практически ни один проект с микроконтроллерами не обходится без операций ввода/вывода через цифровые порты. Микроконтроллеры семейства PIC24F предоставляют разработчику широкие возможности по работе с дискретными сигналами благодаря наличию достаточного количества портов ввода/вывода и некоторым функциям, расширяющим функциональность самих портов.

    4.1. Аппаратно-программная архитектура портов ввода/вывода

         Порты ввода/вывода общего назначения — это простейшие периферийные устройства, с помощью которых PIC-микроконтроллер может получать цифровые данные и управлять другими устройствами. Дополнительную гибкость при работе с портами ввода/вывода обеспечивает и то, что их можно настроить для выполнения альтернативных функций.
         В общем виде функциональную схему стандартного порта ввода/вывода, который не используется периферийными модулями, можно представить так, как показано на Рис. 4.1.
         Эта схема довольно точно отображает функционирование стандартного порта ввода/вывода. Порт может быть настроен на ввод или вывод цифрового сигнала с помощью защелки TRIS, которая представляет собой D-триггер.
         Если порт должен работать как выход, то на вход D защелки TRIS подается сигнал лог. 0, который по тактовому импульсу записывается в триггер. В этом случае инверсный выход TRIS-защелки разрешает работу схемы «И» и открывает тристабильный буфер, через который сигнал с выхода защелки данных (см. Рис. 4.1) проходит на вывод порта.
         Если на вход D защелки TRIS подать сигнал лог. 1, то на инверсном выходе триггера появится 0, который запрещает прохождение сигнала с защелки данных на выход порта. В этом случае данные с вывода порта можно будет только читать. Здесь не следует смешивать чтение выходных данных порта и чтение вывода порта. Для чтения бита данных, записанного в порт, нужно прочитать содержимое защелки данных.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.1. Схема порта ввода/вывода

         Каждый порт ввода/вывода управляется с помощью четырех регистров:
    • TRISx — установка режима работы (чтение или запись) для порта PORTx (здесь x = A, B, C и т. д. и обозначает конкретный порт);
    • PORTx — регистр ввода/вывода порта;
    • LATx — регистр-защелка данных порта PORTx;
    • ODCx — регистр режима работы с открытым стоком.
         Каждому выводу порта ввода/вывода соответствует отдельный бит в регистрах TRISx, PORTx, LATx и ODCx.
         Общее количество портов ввода/вывода и количество выводов зависит от конкретной модели микроконтроллера. Вполне возможно и то, что отдельные биты портов ввода/вывода в конкретном устройстве задействованы не будут.
         В любом случае лучше обратиться к технической документации на микроконтроллер. Рассмотрим назначение каждого из регистров порта ввода/вывода.
         Регистр TRISx позволяет сконфигурировать направление обмена данными для каждого вывода порта. Если для какого-либо вывода порта в регистре TRIS на соответствующей позиции установлен 0, то вывод будет работать на передачу данных. Если же соответствующий бит в регистре TRIS установлен в 1, то вывод порта будет работать на прием (чтение).
         Доступ к данным порта осуществляется посредством регистра PORTx. При чтении этого регистра считываются значения сигналов, присутствующих на выводах порта, а при записи этого регистра данные заносятся в защелку данных порта.
         Многие команды микроконтроллера, такие, например, как BSET и BCLR, выполняют операции, известные как «чтение–модификация–запись». При этом содержимое регистра-операнда (в данном случае регистра порта) вначале считывается, полученное значение модифицируется и затем обратно записывается в регистр. Если вывод порта сконфигурирован как выход (на запись), то никаких проблем не возникает. Однако если выводы порта сконфигурированы как входы, то здесь нужно соблюдать осторожность и записывать данные в порт до того, как направление обмена данными изменится с чтения на запись.
         У каждого порта имеется регистр LATx, использование которого позволяет исключить проблемы, связанные с выполнением операций типа «чтение–модификация–запись». При чтении этого регистра возвращается значение бита, записанного в защелку порта, а не значение на выводе порта. Операции типа «чтение–модификация–запись», выполненные над регистрами LAT, дают правильный результат. Вкратце все вышеизложенное можно резюмировать следующим образом:
    • при записи в регистр PORTx данные записываются в защелку порта;
    • при записи в регистр LATx данные записываются в защелку порта;
    • при чтении регистра PORTx данные читаются с вывода порта;
    • при чтении регистра LATx данные читаются с защелки порта.
         Каждый вывод порта может работать как в обычном режиме, так и в режиме с «открытым стоком». Для переключения выводов в этот режим используются регистры ODCx (Open Drain Control). Если соответствующий бит регистра ODCx установлен в 1, то вывод порта работает как выход с открытым стоком.
         Если же данный бит сброшен в 0, то вывод работает как обычный цифровой выход. При сбросе микроконтроллера все биты регистра ODCx сбрасываются в 0. Конфигурация с «открытым стоком» применяется в случаях, когда к выводу порта требуется подключить нагрузку, которая должна питаться от напряжения, большего или меньшего напряжения питания микроконтроллера.
         Следует соблюдать осторожность при подключении устройств к «открытому стоку» с повышенным напряжением питания, поскольку это может повредить кристалл микроконтроллера. В таких случаях следует обращаться к документации на микроконтроллер.
         Выводы портов микроконтроллеров семейства PIC24F можно сконфигурировать для работы как с цифровыми, так и с аналоговыми сигналами. При использовании порта для ввода цифровых данных входной сигнал поступает на TTL-буфер или триггер Шмита. При настройке порта на выход для передачи выходного сигнала используется буферный усилитель или же применяется конфигурация с «открытым стоком».
         Один и тот же вывод порта ввода/вывода может использоваться и при работе периферийных модулей микроконтроллера, при этом он не может работать как обычный вывод порта. При этом в большинстве случаев вывод должен конфигурироваться как обычный вывод порта ввода/вывода, хотя некоторые периферийные устройства могут переопределять содержимое регистра TRIS. На Рис. 4.2 показана функциональная схема такого «разделяемого» порта ввода/вывода, который используется периферийными модулями.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.2. Схема разделяемого порта ввода/вывода

         При чтении разделяемого порта ввода/вывода нужно помнить несколько правил. Во-первых, если порт управляется периферийным модулем (Рис. 4.2), то состояние его вывода можно определить, прочитав регистр PORTx. Во-вторых, периферийный модуль может прочитать состояние вывода независимо от цифрового модуля ввода/вывода.
         При разделении порта ввода/вывода, настроенного на передачу (запись) сигнала, между разными модулями следует помнить, что:
    • если выход управляется периферийным устройством, то запись данных в регистр PORTx не возымеет никакого эффекта;
    • данные можно прочитать из порта при помощи регистра PORTX;
    • параметры выходного сигнала порта (токи нагрузки, скорость нарастания выходного сигнала и т. д.) определяются настройками периферийного модуля, который использует этот порт;
    • для конфигурирования вывода порта в качестве выхода необходимо сбрасывать соответствующий бит в регистре TRISx;
    • если выход порта может устанавливаться в тристабильное состояние, то это осуществляет сам периферийный модуль.
         При работе порта ввода/вывода c модулем аналого-цифрового преобразования установки регистра TRIS не влияют на состояние порта. Для того чтобы использовать порт, используемый аналого-цифровым преобразователем, в качестве стандартного цифрового порта ввода/вывода, соответствующий бит в регистре AD1PCFG должен быть установлен в 1, независимо от того, включен модуль АЦП или выключен.
         Следует сказать, что некоторые дополнительные функции, присвоенные портам ввода/вывода, не требуют перехвата управления выводом порта, как, например, в случае с модулем аналого-цифрового преобразователя. Если порт ввода/вывода должен работать как вход прерывания, вход синхронизации таймера или вход регистрации события, то достаточно установить соответствующий бит в регистре TRISx. При этом модули прерывания, таймера и регистрации событий не берут управление портом на себя.
         Другие периферийные модули (SPI, I2C и UART) при функционировании полностью перехватывают управление портом ввода/вывода, так что конфигурирование такого порта посредством регистров PORTx и TRISx не требуется.

    4.2. Программирование портов ввода/вывода

         В этом разделе мы рассмотрим несколько проектов, в которых будут продемонстрированы характерные особенности программирования портов ввода/вывода, работающих в стандартном режиме обмена цифровыми данными.
         Аппаратная часть первого проекта показана на Рис. 4.3.
         В этой схеме к выводу RA0 (бит 0 порта PORTA) подключен светодиод, который должен включаться/отключаться при ВЫСОКОМ уровне напряжения на выводе RA7 (бит 7 порта PORTA). В исходном состоянии порт RA0 настроен как вход.
         Программная часть проекта разработана в среде MPLAB IDE с помощью мастера проектов. Для большей наглядности при разработке мы будем использовать язык ассемблера, поэтому в окне выбора инструментальных средств мастера проектов следует выбрать ассемблер MPLAB ASM30 (Рис. 4.4).
         В пустой проект следует добавить файл с расширением .s (стандартное расширение для ASM-файла), поместив в него следующий исходный текст:
    .include "p24fj128ga010.inc"
    .bss
    cnt : .space 2
    cnt1: .space 2
    .text
    .global __ reset
    __reset:
       mov #0xffff,w0
       mov w0,cnt
       mov #0xffff,w0
       mov w0,TRISA
       bclr.b PORTA,#0
    wait:
       btss PORTA,#7
       goto wait
       btsc TRISA,#0
       bclr TRISA,#0
       mov #2,0
       mov w0,cnt1
       Main_Loop:
       mov #0xffff,w0
       mov w0,cnt
    Loop:
       dec cnt
       bra NZ,Loop
       dec cnt1
       bra NZ,Main_Loop
       btg.b PORTA,#0
       goto wait
    .end
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.3. Аппаратная часть проекта

    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.4. Окно выбора компилятора

         В этой программе переменные cnt и cnt1 используются для формирования небольшой задержки переключения светодиода при удержании на входе RA7
         ВЫСОКОГО уровня сигнала. Обе переменные имеют размер в одно слово (2 байта) и при запуске программы получают максимальные значения 0xffff.
         Впоследствии эти переменные декрементируются в циклах Loop и Main_Loop, формируя тем самым определенный интервал времени задержки. Микроконтроллер работает на частоте 8 МГц, так что задержка получается достаточно ощутимой, чтобы увидеть результат работы программы.
         В начале программы все выводы порта А конфигурируются как входы:
    mov #0xffff,w0
    mov w0,TRISA

         В этом случае запись в бит 0 любого значения не изменит состояния выхода, поскольку инверсный выход защелки TRIS (см. Рис. 4.1) сброшен в 0 и блокирует выходной буфер. Таким образом, команда
    bclr.b PORTA,#0

         хоть и сбрасывает бит 0 защелки данных порта А, но на выход эти данные не попадают. По этой причине светодиод на выходе RA0 не включается, поскольку падение напряжения на нем практически равно 0.
         Далее в цикле wait программа ожидает поступления сигнала ВЫСОКОГО уровня на вывод RA7 (бит 7 порта А):
    wait:
    btss PORTA,#7
    goto wait
    . . .

         При поступлении сигнала ВЫСОКОГО уровня на этот вывод бит 0 регистра TRISA сбрасывается:
    bclr TRISA,#0

         Это означает, что выходной буфер бита 0 порта А разблокируется, и на выход поступает сигнал с выхода защелки данных (LAT) (Рис. 4.1), который был ранее установлен в 0 командой bclr.b PORTA, #0. Это вызывает включение светодиода D1. Далее, с определенной задержкой, выход RA0 периодически переключается, до тех пор, пока на входе RA7 присутствует ВЫСОКИЙ уровень.
         Эта программа демонстрирует, как работает порт ввода/вывода в режиме передачи цифровых данных при изменении конфигурации.
         Многие функции микроконтроллера, такие, как вызов прерывания, синхронизация таймера и т. д., работают со стандартными настройками портов ввода/вывода. Это означает, например, что если вывод INT3 настроен как вход, то сигнал, поступающий на этот вход, будет вызывать соответствующее прерывание (если это прерывание разрешено).
         В следующем проекте демонстрируется работа с прерыванием INT3, вход которого использует вывод RA14 (бит 14 порта А). Светодиод D1 переключается каждый раз при вызове обработчика прерывания. Аппаратная часть проекта показана на Рис. 4.5.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.5. Схема прерывания INT3 на порту ввода-вывода

         Напомню, что порты ввода/вывода во многих случаях можно задействовать и для реализации альтернативных функций микроконтроллера. На Рис. 4.5 как раз и показано использование вывода 14 порта A для приема сигнала прерывания. В такой конфигурации вывод порта должен быть настроен для чтения входного сигнала с помощью установки соответствующего бита в регистре TRISA. При желании или необходимости можно создать и такую аппаратнопрограммную конфигурацию, в которой, допустим, в определенные моменты времени бит 14 будет принимать сигнал прерывания, а остальную часть времени работать как выходной для управления какой-либо нагрузкой.
         Программная часть проекта реализована с помощью мастера проектов MPLAB IDE, но исходный текст написан уже на Си:
    #include <p24fj128ga010.h≶
    _CONFIG2(FCKSM_CSDCMD&OSCIOFNC_ON&POSCMOD_HS&FNOSC_PRI)
    void __attribute__ ((interrupt)) _INT3Interrupt(void)
    {
       _INT3IF = 0;
       _RA0 = ~_RA0;
    }
    void main(void)
    {
       TRISAbits.TRISA0 = 0x0;

       _RA0 = 0x1;
       _INT3IF = 0;
       _INT3IE = 1;
       while(1);
    }

         Это очень простой пример. Обработчик прерывания _INT3Interrupt сбрасывает флаг прерывания _INT3IF, а затем инвертирует бит 0 порта А. Поскольку при инициализации микроконтроллер настраивает порты на чтение, то нам нужно переключить бит 0 порта А на запись:
    TRISAbits.TRISA0 = 0x0;

         Кроме того, нужно разрешить внешнее прерывание INT3:
    _INT3IF = 0;
    _INT3IE = 1;

         В данном примере мы работаем с портом А, который не используется периферийными модулями. Если, например, светодиод был бы подключен к порту В, который используется модулем аналого-цифрового преобразователя, то ситуация была бы иной. При инициализации микроконтроллера порт В сразу настраивается для использования модулем АЦП, поэтому, чтобы задействовать все или отдельные выводы порта для ввода/вывода цифровых сигналов, в основной программе пришлось бы вначале выполнить оператор
    AD1PCFG = 0xffff;

         В любом случае перед использованием в проекте того или иного порта следует ознакомиться с документацией на конкретный микроконтроллер.

    4.3. Модуль регистрации событий

         В микроконтроллерах PIC24F предусмотрена еще одна полезная функция, которая позволяет программе реагировать определенным образом на изменения уровней сигналов на входах портов. Эта функция основана на использовании механизма «захвата» или регистрации событий. В данном контексте под событием понимают любое изменение сигнала на входе порта ввода/вывода.
         Этот механизм используется при работе с выводами портов, для которых предусмотрен специальный вариант обработки событий при изменении состояния сигнала на входе порта. Такие выводы микроконтроллера имеют дополнительное обозначение CNx (Change Notification) и реализованы посредством отдельного аппаратного модуля в микроконтроллере. При возникновении события задействуется механизм прерываний, при этом обработчик прерывания позволяет оперативно обработать событие. Количество таких выводов зависит от конкретной модели микроконтроллера, поэтому за более подробной информацией следует обращаться к технической документации на устройство.
         С CN-модулем связаны три группы регистров управления:
    • регистр CNENn — содержит биты разрешения прерывания от соответствующих выводов, которые обозначаются как CNxIE, где x обозначает номер CN-вывода;
    • регистры CNPUn/CNPDn — содержат биты управления CNxPUE/CNxPDE. Эти биты разрешают/запрещают подтяжку выводов к питанию (CNPUn) и общему проводу (CNPDn). Это позволяет отказаться от использования внешних подтягивающих резисторов при подключении таких узлов, как кнопки (клавиатура).
         Функциональная схема одного из каналов CN-модуля показана на Рис. 4.6.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.6. Схема CN-модуля

         На этом рисунке изображена функциональная схема канала 0 CN-модуля.
         При любом изменении сигнала на выводе CN0 схема исключающего ИЛИ будет формировать сигнал ВЫСОКОГО уровня, который, попадая на один из входов оконечного элемента ИЛИ, приведет к генерации прерывания. Точно так же работают и другие входы CN1…CNx.
         Программирование обработчиков событий на входах CNx включает несколько шагов:
    1. Требуемый вывод CNx переключается в режим цифрового входа посредством установки соответствующего бита в регистре TRISx.
    2. Разрешается при необходимости подключение внутренней подтяжки путем установки соответствующих битов регистров CNPUx.
    3. Сбрасывается флаг прерывания CNxIF.
    4. Устанавливается требуемый уровень приоритета от CN-модуля путем установки CNxIP.
    5. Разрешаются прерывания от CN-входов путем установки соответствующих битов CNxIE.
         Программа пользователя при необходимости должна сама определить, какое событие произошло (перепад 0—1 или 1—0), и выполнить требуемые действия.
         Рассмотрим пример проекта, в котором показаны основные принципы обработки событий на цифровых входах микроконтроллера. Аппаратная часть проекта показана на Рис. 4.7.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.7. Аппаратная часть проекта

         В этой схеме контролируемые сигналы поступают на входы CN7 и CN20 микроконтроллера PIC24FJ128GA010. Программная часть проекта обеспечивает синхронное переключение светодиодов при одновременном присутствии сигналов ВЫСОКОГО уровня на входах CN7 и CN20. Например, переключение светодиодов будет осуществляться при ВЫСОКОМ уровне сигнала на входе CN7 и изменении уровня с НИЗКОГО на ВЫСОКИЙ на входе CN20. Тактовая частота схемы равна 8МГц.
         Программная часть проекта разработана в среде MPLAB IDE с помощью мастера проектов. Исходный текст программы на языке Си приведен далее:

    #include <p24fj128ga010.h>
    _CONFIG2(FCKSM_CSDCMD&OSCIOFNC_ON&POSCMOD_HS&FNOSC_PRI)
    #define TRISB_5 TRISBbits.TRISB5
    #define TRISD_14 TRISDbits.TRISD14
    #define TRISB_0 TRISBbits.TRISB0
    #define TRISB_1 TRISBbits.TRISB1
    #define CN7 CNEN1bits.CN7IE
    #define CN20 CNEN2bits.CN20IE
    #define SYSCLK 8000000
    void __attribute__ ((interrupt)) _CNInterrupt(void)
    {
       _CNIF = 0;
    if (_RB5 == 1 && _RD14 == 1)
    {
       _RB0 = ~_RB0;
       _RB1 = ~_RB1;
    }
    }
    void main(void)
    {
       TRISB_0 = 0;
       TRISB_1 = 0;
       TRISB_5 = 1;
       TRISD_14 = 1;
       _CNIF = 0;
       _CNIP = 0x4;
       CN7 = 1;
       CN20 = 1;
       _CNIE = 1;
       while(1);
    }

         Переключение светодиодов, подключенных к выводам 0 и 1 порта B, выполняется в обработчике прерывания _CNInterrupt. Для инициализации выводов прерывания CN7 и CN20 в основной программе устанавливаются соответствующие биты в регистрах CNEN1 и CNEN2:
    CN7 = 1;
    CN20 = 1;

         Кроме того, необходимо, как и в случае других источников прерываний, разрешить прерывания от CN-модуля:
    _CNIE = 1;

         Программный код должен настроить также выводы RB5(CN7) и RD14(CN20) на ввод цифровых сигналов, что выполняется операторами:
    TRISB_5 = 1;
    TRISD_14 = 1;

         В остальном программный код, думаю, понятен.
         Возможность регистрации событий позволяет создавать системы сигнализации и оповещения различной степени сложности. В нашем следующем проекте мы рассмотрим простейшую систему регистрации нескольких событий и индикации источника события. Мы проанализируем взаимосвязь аппаратной и программной частей, а также возможные модификации этого проекта. Разработчики встраиваемых устройств часто сталкиваются с дилеммой: решить задачу с максимальным использованием аппаратных средств или использовать большей частью программный вариант решения. На этом примере мы проанализируем преимущества и недостатки обоих подходов.
         Аппаратная часть проекта представлена схемой на Рис. 4.8.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.8. Аппаратная часть устройства

         В данном проекте используется микроконтроллер PIC24FJ128GA010 с тактовой частотой 8 МГц. На входы 1…4 RS-триггера 74HC279 (DD1) могут подключаться источники сигналов (дискретные датчики, переключатели и т. д.), НИЗКИЙ уровень напряжения которых приводит к появлению сигнала лог. 1 на одном из входов логического элемента ИЛИ-НЕ (микросхема DD3). Логический элемент DD3 переключается из состояния НИЗКОГО уровня в состояние ВЫСОКОГО уровня при наличии напряжения логической единицы на любом из 4 входов, изменяя тем самым состояние входа CN7, что приводит к генерации прерывания.
         Далее программа считывает состояние выходов Q1…Q4 триггера DD1 и выводит его в биты 0…3 порта B, к которым подключены светодиоды D1…D4.
         Триггеры Шмита (микросхема DD2) выполняют функцию автоматического сброса состояния входов через определенное время задержки, определяемое RC-цепочкой R5C1. Эта задержка нужна для того, чтобы функция-обработчик прерывания успевала считать состояние выходов Q1…Q4.
         В программную часть проекта, разработанную в MPLAB IDE, нужно включить Си-файл со следующим исходным текстом:

    #include <p24fj128ga010.h>
    _CONFIG2(FCKSM_CSDCMD&OSCIOFNC_ON&POSCMOD_HS&FNOSC_PRI)
    char c1;
    void __attribute__ ((interrupt)) _CNInterrupt(void)
    {
       _CNIF = 0;
       c1 = PORTA & 0xf;
       PORTB = c1;
    }
    void main(void)
    {
       AD1PCFG = 0xffff;
       TRISB = 0xfff0;
       TRISA = 0x7fff;
       _CNIF = 0;
       _CNIP = 0x4;
       _CN7IE = 1;
       _CNIE = 1;
       while(1);
    }

         Программа очень проста. Обработка входных сигналов осуществляется в функции-обработчике прерывания _CNInterrupt. Здесь в переменную c1 считываются 4 бита порта А, которые тут же передаются в младшие биты порта В.
         В основной программе выполняется инициализация портов А и В, а также настройка прерывания обработки событий.
         Обработка одних и тех же внешних сигналов может осуществляться и с помощью других аппаратно-программных решений. В каждом конкретном случае нужно определить оптимальную конфигурацию. Если в системе необходимо добиться использования минимального количества внешних компонентов, то основной упор должен делаться на программную часть микроконтроллера (firmware). Однако здесь могут возникнуть ограничения, связанные с быстродействием системы. Если сравнивать один и тот же алгоритм, реализованный оптимальным образом внешними элементами и аппаратно-программными средствами микроконтроллера, то вариант с внешними элементами будет работать быстрее. Тем не менее, для многих систем с невысоким или средним быстродействием упор на программную реализацию алгоритмов вполне оправдан. Например, наш предыдущий проект почти целиком можно реализовать с помощью одного микроконтроллера, оставив в системе минимум внешних компонентов.
         Модифицированная аппаратная часть предыдущего проекта представлена на Рис. 4.9.
    Микроконтроллеры PIC. Архитектура и программирование. Часть 4. Программирование портов ввода-вывода
    Рис. 4.9. Аппаратная часть модифицированного проекта

         В этой схеме для считывания данных мы оставили одну внешнюю микросхему DD1. Выходы Q1…Q4 триггера в этой схеме соединены со входами регистрации событий CN2…CN5 микроконтроллера. Такое упрощение схемы требует модификации программной части проекта, поскольку нужно разрешить обработку событий по входам CN2…CN5. Вот исходный текст основной программы для данной аппаратной конфигурации:

    #include <p24fj128ga010.h>
    _CONFIG2(FCKSM_CSDCMD&OSCIOFNC_ON&POSCMOD_HS&FNOSC_PRI)
    char c1;
    void __attribute__ ((interrupt)) _CNInterrupt(void)
    {
       _CNIF = 0;
       c1 = PORTB & 0xf;
       PORTA = c1;
    } void main(void)
    {
       AD1PCFG = 0xffff;
       TRISB = 0xffff;
       TRISA = 0x0;
       _CNIF = 0;
       _CNIP = 0x4;
       _CN2IE = 1;
       _CN3IE = 1;
       _CN4IE = 1;
       _CN5IE = 1;
       _CNIE = 1;
       while(1);
    }

         Здесь нужно установить выводы порта В для работы в качестве цифровых портов, что выполняется двумя операторами:
    AD1PCFG = 0xffff;
    TRISB = 0xffff;

         Кроме того, нужно установить разрешение прерывания при возникновении изменений сигналов на входах CN2…CN5:
    _CN2IE = 1;
    _CN3IE = 1;
    _CN4IE = 1;
    _CN5IE = 1;

         В принципе, если нет жестких ограничений по количеству задействованных сигнальных выводов, то удобно реализовать большую часть проекта (если это не какой-то специальный случай) программным способом. Если необходима повышенная производительность, то в этом случае можно взять более быстродействующий микроконтроллер, например, семейства PIC24H.

    Комментарии