Отправляет email-рассылки с помощью сервиса Sendsay

Статьи по электронике

  Все выпуски  

Статьи по электронике


Информационный Канал Subscribe.Ru

Статьи по электронике


Автор рассылки: Вячеслав Кулаков
Сайт рассылки

16-ти разрядные микроконтроллеры фирмы Fujitsu

продолжение

      В предыдущей статье были рассмотрены основные подходы к работе с микроконтроллерами фирмы Fujitsu. Далее на примере двух таймеров - Reload Timer и PPG будет показано как можно достаточно просто работать с периферией и как использовать прерывания.
      В большинстве случаев, так же как и при написании простых программ, при работе с периферией и прерываниями знать архитектуру контроллера не обязательно, можно использовать готовый шаблон, предлагаемый производителем. Однако для работы с периферией необходимо знать регистры и биты, которые ей управляют, т.е. изучить соответствующую главу в документации все-таки прийдется. Например для использования PPG в микроконтроллере MB90F598G будет необходмо ознакомиться с главой 13 (называется "8/16-bit PPG"), а для использования Reload Timer c главой 12 ("16-BIT RELOAD TIMER(WITH EVENT COUN FUNCTION)") соответствующего руководства.
      Общие принципы работы с периферией можно разобрать на примере программы PPG, находящейся в каталоге примеров предлагаемых производителем. В этой программе используется таймер PPG1 и 16-ти битный перезагружаемый таймер 0 (Reload Timer 0). PPG1 выполняет роль генератора ШИМ с выходом на линию P10, а Reload Timer 0 отсчитывает временные интервалы, через которые в генератор ШИМ загружается новое значение со сдвигом на 1 бит. Загрузка осуществляется по прерыванию Reload Timer 0. Таким образом, на выходе P10 будет виден пилообразный сигнал ШИМ.
      Детально описывать работу таймеров автор смысла не видит, т.к. для понимания принципов работы с периферией и с прерываниями в этом необходимости нет. Поэтому будут отмечены только основные моменты, а более полную информацию желающие могут найти в вышеуказанных разделах документации.
      Всего имеется шесть идентичных генераторов PPG. В документации рассматривается только один генератор PPG0/1, работа остальных аналогична. Каждый генератор состоит из двух 8-ми битных счетчиков, четырех 8-ми битных регистров для перезагрузки этих счетчиков (по два на каждый счетчик) и управляющих регистров. Имеется возможность использовать счетчики в трех разных режимах: в режиме двух независимых 8-ми битных счетчиков, в режиме 8-ми битного счетчика с 8-ми битным предделителем и в режиме одного 16-ти битного счетчика. В рассматриваемом примере используется только один 8-ми битный счетчик в первом из вышеназванных режимов. Этот счетчик считает до нуля, после чего при переходе от 0x00 к 0xff происходит инвертирование уровня на выходе P10 и его перезагрузка по очереди из каждого регистра для перезагрузки. В одном из этих регистров хранится значение для длительности нуля на выходе P10, в другом для длительности единицы. Таким образом меняя значения в этих регитрах можно менять выходной сигнал ШИМ. Ниже приводится функция инициализации PPG1 из примера.

void InitPPG1 (IO_BYTE ClkSel, IO_BYTE LowDuration, IO_BYTE HighDuration)
{
       PPG01_PCS = ClkSel; //выбор источника тактовой частоты счетчика

       PRLL1 = LowDuration; //установка значений длительности нуля
       PRLH1 = HighDuration; //установка значений длительности единицы

       PPGC1 = 0xA1; //задание режима работы PPG

//Ниже приведены примеры использования отдельных бит управляющего регистра PPGC1.
//Закомментированы, т.к. этот регистр уже инициализирован
       // PPGC1_MD = 0; //Двухбитовая переменная. Переключает режим работы PPG
       // PPGC1_PEN1 = 1; //Один бит. Включает/выключает работу PPG
       // PPGC1_PE10 = 1; //Один бит. Подключает/отключает линию выхода к счетчику

       return;
}

      Вызов этой функции в примере производится следующим образом:

      InitPPG1(4, 40, 40); //тактовая частота выбрана 1мкс (при внутренней чатоте 16 мГц),
//длительность нуля и единицы равна 40 мкс

      Далее рассмотрим Reload Timer. Всего перезагружаемых таймеров в MB90F598G имеется два. В документации описан один, другой точно такой же. Работа Reload Timer аналогична работе PPG: 16-ти битный счетчик считает до нуля, а затем перезагружается значением, заданным в регистре TMRLR0. Функция инициализации Reload Timer 0 выглядит так:

void InitReloadTimer(void)
{
       TMRLR0 = 0x1000; //Значение для перезагрузки
       TMCSR0 = 0x81B; //Тактовая частота 2 мкс, прерывания разрешены
}

      При переходе значения счетчика от 0x00 к 0xff помимо его перезагрузки происходит прерывание. Функция обработки прерывания отличается от обычной ключевым словом "__interrupt":

__interrupt void ReloadTimer(void)
{
       Intensity++; //Запись новых значений в регистры перезагрузки PPG1.
       PRLL1 = Intensity; //Intensity - глобальная переменная размером в 1 байт.
       PRLH1 = 0xFF - Intensity; //В ней хранится значение для перезагрузки.

       TMCSR0_UF = 0; //Сброс флага прерывания
       return;
}

      Для того, чтобы эта функция была вызвана в момент прерывания, она должна быть определена в файле vector.c. Этот файл состоит из трех основных частей:

  1. Функция задания приоритеров прерываний InitIrqLevels(). В ней значениями от 0 до 7 задаются приоритеты используемых прерываний. 0 - максимальный приоритет, 7 - прерывание отсутствует. По умолчанию на все прерывания задан уровень приоритета 7, что соответствует запрету прерываний. В рассматриваемом примере Reload Timer 0 соотвествует прерывание IRQ15 и ему задан уровень приоритета 6. Перед использованием прерываний необходмио произвести вызов этой функции.
  2. Прототипы. В этом разделе описываются прототипы используемых обработчиков прерываний. В нем можно увидеть два прототипа: для обработчика, заданного на все прерывания по умолчанию DefaultIRQHandler и для функции ReloadTimer.
  3. Определение векторов прерываний. В этой части расписаны все прерывания контроллера. При задании своего обработчика необходимо в соответствующей строке заменить DefaultIRQHandler на свое название. Например, для Reload Timer 0 в рассматриваемой программе будет стоять название ReloadTimer.
      И последнее, что необходимо сделать перед использованием прерываний - это разрешить все прерывания вызовом функции __EI(). Запрещаются прерывания функцией __DI().
      Для того что бы увидеть как работает прерывание в эмуляторе, необходимо после компиляции запустить ее на исполнение в отладчике, поставить точку останова в обработчике прерывания и остановить исполнение командой "Debug->Abort". Далее через пункт меню "Setup->Debug environment->Interrupt" вызвать диалоговое окно задания симуляции прерывания. В нем необходимо выбрать номер прерывания (в рассматриваемом примере 15), способ его симуляции - один раз или многократно через заданный интервал времени (в машинных циклах) и время (либо интервал) через которое будет произведен вызов. Далее после запуска программы на исполнение, она остановится на точке останова после истечения заданного времени. Если задан мнократный вызов, то программа будет останавливаться регулярно. Временные интервалы можно смотреть через пункт меню "Debug->Time measurement".

      Таким образом, для создания своего обработчика какого-либо прерывания необходимо:

  1. Написать функцию обработчика с ключевым словом __interrupt.
  2. Вставить прототип этой функции во второй раздел файла vector.c.
  3. В третьем разделе определения векторов найти требуемое прерывание и заменить обработчик по умолчанию DefaultIRQHandler на имя своего обработчика. Названия источников прерываний есть в комментариях к каждому прерыванию.
  4. По номеру найденного прерывания из предыдущего пункта задать приоритет своему обработчику в функции InitIrqLevels() .
  5. В основном теле программы произвести вызов функций InitIrqLevels() и __EI(). Обычно эти вызова производятся в начале исполнения функции main().
      В заключении статьи автор хотел бы отметить, что вышеописанные функции для работы со счетчиками можно автоматически размножить на все аналогичные устройства. Например функцию для инициализации Reload Timer 0 можно легко изменить на функцию инициализации Reload Timer 1. Для этого необходимо всего лишь поменять в названиях регистров 0 на 1. Получится такая функция:

void InitReloadTimer1(void)
{
       TMRLR1 = 0x1000; //Значение для перезагрузки
       TMCSR1 = 0x81B; //Тактовая частота 2 мкс, прерывания разрешены
}

      Так же и для PPG. Напрмер, иницилизация PPG3 будет выглядеть так:

void InitPPG3 (IO_BYTE ClkSel, IO_BYTE LowDuration, IO_BYTE HighDuration)
{
       PPG23_PCS = ClkSel; //выбор источника тактовой частоты счетчика

       PRLL3 = LowDuration; //установка значений длительности нуля
       PRLH3 = HighDuration; //установка значений длительности единицы

       PPGC3 = 0xA1; //задание режима работы PPG

//Ниже приведены примеры использования отдельных бит управляющего регистра PPGC1.
//Закомментированы, т.к. этот регистр уже инициализирован
       // PPGC3_MD = 0; //Двухбитовая переменная. Переключает режим работы PPG
       // PPGC3_PEN3 = 1; //Один бит. Включает/выключает работу PPG
       // PPGC3_PE30 = 1; //Один бит. Подключает/отключает линию выхода к счетчику

       return;
}

      А иницилизация PPG0 так:

void InitPPG0 (IO_BYTE ClkSel, IO_BYTE LowDuration, IO_BYTE HighDuration)
{
       PPG01_PCM = ClkSel; //выбор источника тактовой частоты счетчика

       PRLL0 = LowDuration; //установка значений длительности нуля
       PRLH0 = HighDuration; //установка значений длительности единицы

       PPGC0 = 0xA1; //задание режима работы PPG

//Ниже приведены примеры использования отдельных бит управляющего регистра PPGC1.
//Закомментированы, т.к. этот регистр уже инициализирован
       // PPGC1_MD = 0; //Двухбитовая переменная. Переключает режим работы PPG
       // PPGC0_PEN0 = 1; //Один бит. Включает/выключает работу PPG
       // PPGC0_PE00 = 1; //Один бит. Подключает/отключает линию выхода к счетчику

       return;
}
      Так же можно размножать функции, приведенные в других примерах для другой периферии: для UART, CAN и т.д.


НачалоНачало


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное