Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт

Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт

Читать онлайн Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 127 128 129 130 131 132 133 134 135 ... 150
Перейти на страницу:

Сценарий: В нашем примере с роботом у нас было много задач по обеспечению его работы. Теперь мы должны назначить численное значение приоритета для каждой задачи. Мы будем использовать более низкое численное значение для задач с более высоким приоритетом. Например, задаче с самым высоким приоритетом сопоставим значение 1. Мы используем наше понимание сценария работы робота, чтобы назначить приоритеты задач. Так как наш робот дезактивируется, когда приближается к мине, мы присваиваем задаче обнаружения мин приоритет 1. Следующий самый высокий приоритет, равный 2 присвоим операции объезда мины. Задаче ATD-преобразования присвоим приоритет 3, так как она обеспечивает информацию о близости стенок лабиринта. Задаче выбора поворота присвоим следующий приоритет 4, так как она обрабатывает информацию, необходимую, чтобы избежать столкновения со стенками. Наконец, задаче модификации ЖКД назначаем приоритет 5. Это самый низкий приоритет для задач, рассмотренных к настоящему времени; однако, приоритет всех прочих задач еще ниже. Остающиеся задачи имеют еще более низкий приоритет. Они активны на начальных этапах работы нашей операционной системы, а затем входят в состояние бездействия. Мы, следовательно, назначаем им самый низкий приоритет, давая им приоритеты 6 (инициализация ЖКД), 7 (инициализация ATD), и 8 (инициализация ШИМ).

Фрагментация задач. Как мы уже выяснили в этом разделе, желательно разделить программный код задачи на непрерываемые части или фазы, определив удобные точки выхода. Это важно, поскольку в ОСРВ с несколькими задачами с одинаковым приоритетом, задача редко будет способна завершить связанные с ней действия от начала до конца. Чаще всего задача завершит некоторую часть действий и затем будет приостановлена задачей или задачами с более высоким приоритетом. Факт перехода задачи с более высоким приоритетом в состояние готовности еще не означает, что процессорное время немедленно передается ей. Мы должны организовать переход от одной задачи к другой, прервав выполнение кода в заранее определенном удобном для этого месте. Поскольку мы записываем контекст прерываемой задачи, мы должны сохранить его в памяти. Например, мы можем подразделять связанную с задачей функцию на три части. Первый раз, когда задача становится активной, процессор выполняет первую треть кода до удобной отметки прерывания (определенной вами, как программистом). Когда код достигает этой отметки прерывания, контекст сохраняется в TCB, и процессор прерывает управление задачей. Затем выполняется задача с более высоким приоритетом. Когда прерванная задача снова получает для своего выполнения драгоценное процессорное время, она начинается с того места, где была прервана и продолжает обработку второй части своего кода. Этот процесс продолжается, пока задача не завершает все предусмотренные действия.

Проиллюстрируем такую работу примером.

Пример: Предположим, что робот, имеющий пять ИК локаторов (рис. 8.16) выполняет функцию названную process_turn, которая инициализирует систему ATD контроллера 68HC12, начиная последовательность преобразований, необходимую, чтобы записать аналоговые сигналы от пяти датчиков (с номерами от 0 до 4), которые связаны с каналами ATD от 7 до 3, соответственно. Выход датчика Холла, установленного в нижней части робота, чтобы обнаруживать магнитные мины, связан с каналом 2 ATD. Обратите внимание: этот пример придуман, чтобы показать, как следует подразделять код, чтобы обеспечить удобные точки прерывания.

Рис. 8.16. Робот c пятью ИК локаторами и датчиком Холла. ИК-датчик обнаруживает присутствие стенок лабиринта, в то время как датчик Холла обнаруживает присутствие магнитных мин.

Код process_turn, обеспечивающий процесс поворота, приведен ниже.

void process_turn() {

 /*Инициализация системы ATD */

 ATDCTL2 = 0x80; /*установка флага ADPU, чтобы подать питание на систему ATD*/

 ATDCTL3 = 0x00; /*игнорировать «замораживание» системы */

 ATDCTL4 = 0x7F; /*Снижение частоты таймера P до 125 кГц */

                 /*выборка, время преобразования = 32 ATD цикла */

 /* 1 выборка за каждые 256 мкс */

 for (i=0; i<67; i++) { /* ожидание 100 мкс при 8 МГц ECLK*/

  ;

 }

 /*Инициализация ATD-преобразования */

 ATDCTL5 = 0x50; /*Начать многоканальное ATD-преобразование */

 /* для 8 каналов */

 while((ATDSTAT & 0x8000) == 0) { /* проверить окончание преобразования по*/

  /*состоянию флага SCF */

  ;

 }

 /* сохранить результаты ATD-преобразования*/

 /* в глобальном массиве char*/

 sens[0] = ADR7H; /*крайний левый датчик */

 sens[1] = ADR6H; /*средний левый датчик */

 sens[2] = ADR5H; /*центральный датчик */

 sens[3] = ADR4H; /*средний правый датчик */

 sens[4] = ADR3H; /*крайний правый датчик */

 sens[5] = ADR2H; /*Датчик Холла*/

 /*анализ информации датчиков для решения о повороте. Примечание: пороги для*/

 /*датчика Холла(hes_threshold) и для ИК-датчиков (opto_threshold)являются*/

 /* глобальными переменными и определены экспериментально*/

 if (sens[5] < hes_threshold) { /*сигнал с датчика Холла, объезд*/

  pwm_motors(back_up); /* робот дает задний ход*/

  /*действия, следующие после того */

  /* как робот отъехал назад */

  if(sens[0] > opto_threshold) pwm_motors(right_turn);

  else pwm_motors(left_turn);

  for(i=0; i<0xFFFF; i++) { /*задержка перед вращением двигателя */

   for(j=0; j<15; j++){

    ;

   }

  }

 }

 /*если обнаружен тупик - задний ход*/

 else if((sens[2]>opto_threshold) && (sens[0]>opto_threshold) && (sens[4]>opto_threshold)) {

  pwm_motors(back_up);

 }

 /*если стенки спереди и слева, */

 /*поворот робота направо */

 else if((sens[0]>opto_threshold) && (sens[2]>opto_threshold)) {

  pwm_motors(right_turn);

 }

 /*если стенки спереди и справа, */

 /*поворот робота налево */

 else if((sens[2]>opto_threshold) && (sens[4]>opto_threshold)) {

  pwm_motors(left_turn);

 }

 /*если стенка перед средним правым */

 /* датчиком, то полуповорот направо */

 else if (sens[1] > opto_threshold) {

  pwm_motors(half_right);

 }

 /*если стенка перед средним левым */

 /* датчиком, то полуповорот налево */

 else if (sens[3]>opto_threshold) {

  pwm_motors(half_left);

 }

 /*если сигналов от датчиков нет, продолжить движение вперед*/

 else {

  pwm_motors(forward);

 }

}

Если мы хотим подразделить этот код на три части обрабатываемые ОСРВ без прерывания, мы можем вставить точки прерывания после последовательности инициализации ATD и после последовательности записи данных с ATD. Это позволит функции без проблем прерывать и восстанавливать управление процессором. Чтобы выполнять эти изменения, мы должны ввести переменную, которую мы назовем code_section. Эта переменная позволит нам проследить, какая из трех частей кода должна быть выполнена при очередной активности задачи.

int process_turn(int code_section) {

 switch(code_section) {

 case 0:

  /*Инициализация системы ATD */

  ATDCTL2 = 0x80; /*включение ATD */

  ATDCTL3 = 0x00; /*игнорировать доступ при отладке системы */

  ATDCTL4 = 0x7F; /*Снижение частоты таймера P до 125 кГц */

  /*выборка, время преобразования = 32 ATD цикла */

  /* 1 выборка за каждые 256 мкс */

  for (i=0; i<67; i++) {

   /* ожидание 100 мкс при 8 МГц ECLK*/

   ;

  }

  code_section = 1; /*update code_section variable */

  break;

 case 1:

  /*Инициализация ATD-преобразования */

  ATDCTL5 = 0x50; /*Начать многоканальное ATD-преобразование*/

  /* для 8 каналов */

  while ((ATDSTAT & 0x8000) == 0) {

   /* проверить окончание преобразования по*/

   /*состоянию флага SCF */

   ;

  }

  /* сохранить результаты ATD-преобразования*/

  /* в глобальном массиве char */

  sens[0] = ADR7H; /*крайний левый датчик */

  sens[1] = ADR6H; /*средний левый датчик */

  sens[2] = ADR5H; /*центральный датчик */

  sens[3] = ADR4H; /*средний правый датчик */

  sens[4] = ADR3H; /*крайний правый датчик */

  sens[5] = ADR2H; /*Датчик Холла */

  code_section = 2; /*update code_section variable */

  break;

 case 2:

  /*анализ информации датчиков для решения о повороте. Примечание: пороги для*/

1 ... 127 128 129 130 131 132 133 134 135 ... 150
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт.
Комментарии