Очередь задач - один из вариантов структуры программы на МК. Среди множества велосипедов остановимся на таком:
Спойлер
Код: Выделить всё
// Добавить задачу в очередь
void qtTask(qtTaskPtr ptr, qtDelay tick);
// Вызывается при каждом "tick", проводит отсчет задержки
void qtDecrementDelay(void);
// Пытается выполнить одну задачу из очереди
void qtDispatch(void);Код: Выделить всё
volatile uint8_t f;
ISR(TIMER0_OVF_vect){
TCNT0 = TCNT_TICK; // 125Hz
f |= 1;
}
void tBlink(){
PORTB ^= 0x01;
qtTask(tBlink, 64);
}
int main(void)
{
init();
tBlink();
while (1)
{
if(f & 0x01){
f &= ~1;
qtDecrementDelay();
}
qtDispatch();
}
}Добавляю клавиатуру с тремя кнопками +/-/Set. Нажимая Set, заходим в настройки, +/- меняем значение параметра и повторным нажатием Set сохраняем значение.
Задача qtButton молотит с нужной периодичностью, всё отлавливает и на гора выдает в глобальной переменной битовую маску "кнопка нажата".
Код: Выделить всё
unit8_t btState; // Битовая маска. Единичка поднимается задачей qtButton при нажатии кнопки либо срабатывании автоповтораВидел в сети описание структуры программы, где в главном цикле прокручиваются по очереди все к.автоматы и там все возникшие события откладываются на следующий такт. В конце такта все необработанные события очищались. Но в нашем случае этот вариант не подходит - у нас нет явного цикла, в котором выполнятся по разу все задачи и не понятно, когда же очищать события.
В конкретном примере с кнопками можно очищать btState вместе с активацией задачи или внутри задачи контролировать первый запуск и очищать буфер - аналог выполнения действия на дуге конечного автомата. Но выглядит это какось корявенько. Сдается мне, что я упустил одну из главных фишек очереди заданий и просто неправильно её готовлю.
Вторая часть про разделяемый ресурс чуть позже. После осознания ошибок первой.


