FreshMan, прежде всего надо хорошо подумать, как распределяются ваши процессы в программе на фоновые и основные.
фоновые - это те, которые что-то делают через строго определенные промежутки времени, причем постоянно и независимо от всего остального. такими процессами может быть динамическая индикация, генерация программного ШИМ-а (возможно, многоканального), счет времени и т.п. замеры АЦП, кстати, тоже могут быть фоновыми.
основные - это те процессы, к регулярности обращения к которым никаких особых требований не предъявляется. например, это могут быть какие-то вычисления, обработка вводимых ползьзователем данных, ввод-вывод на дисплей и т.п.
деление, конечно, условное - вряд ли кто сумеет вам запретить сделать в основном цикле динамическую индикацию, а диалог с пользователем вести по прерываниям
судя по обрывкам информации, проскакивающей "между строк" ваших сообщений, я делаю такое предположение: у вас есть что-то типа Nixi-индикатора, причем с использованием динамической индикации и ШИМ-регулировки яркости индикаторов. вы теперь хотите что-то там измерить при помощи АЦП и вывести это на индикатор, но при этом так, чтобы не разрушить ранее сделанную индикацию. я угадал?
так вот, могу дать несколько советов, а пользоваться ими или нет - дело ваше. правда, боюсь, что к теме топика это будет иметь мало отношения - да простят меня модераторы!
1. выделите все, что касается индикации, в отдельный файл. общение с этим модулем ведите только через "интерфейсные" функции, и необходимый минимум переменных. отладив индикацию, больше в этот файл не заглядывайте - это почти гарантия, что вы не сломаете то, что уже работает.
2. определитесь с основными процессами в вашей системе. мне кажется (не настаиваю), то обработка АЦП, обработка нажатий кнопок, вычисления - все это основные (не фоновые) задачи. т.е. в общих чертах я бы сделал как-то так:
Код: Выделить всё
while(1){ // основной цикл
key = get_key(); // опрос кнопок
adc = get_adc(); // измерение АЦП
switch(key){
// тут обрабатываем нажатия кнопок
}
// если нужно, обрабатываем результат АЦП
output_to_display(/* всякие выводимые значения */); // вывод на индикатор результатов работы
}
как видите, все исключительно последовательно и без всяких флагов и т.п.
3. если по каким-то причинам слишком частое измерение АЦП вам неприемлемо, то предлагаю рассмотреть такой вариант: по таймеру запускаете АЦП, при этом АЦП вызывет прерывание по окончанию измерения. в обработчике этого прерывания вы переписываете значение из регистров ADC в volatile переменную, значение которой тупо возвращаете функцией get_adc(); чем хорош такой вариант? да хотя бы тем, что основной цикл при этом вообще никак не меняется! единственное, о чем надо помнить, так это о том, что обращение к неоднобайтной переменной с результатом АЦП должно быть атомарным.
вот, как-то так...