Чтение онлайн

ЖАНРЫ

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

Пак Дэниэл Дж.

Шрифт:

Если мы хотим подразделить этот код на три части обрабатываемые ОСРВ без прерывания, мы можем вставить точки прерывания после последовательности инициализации 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:

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

/*датчика Холла(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);

}

code_section = 0; /* изменить переменную code_section */

break;

 }/*конец switch*/

 return code_section;

}

Когда задача, связанная с функцией

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

В этом примере мы использовали глобальные переменные, чтобы сохранять информацию между последовательными обращениями к функции

process_turn
. Использование глобальных переменных может быть не самое лучшее использование дефицитных ресурсов памяти RAM. Далее в этой главе мы рассмотрим альтернативные методы движения информации между задачами.

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

Поделиться с друзьями: