AndreiVV Спасибо. Буду разбираться.
У меня еще тема. О подходе к программированию. У меня есть опыт на asm и на си для uC.
Пришел к такому заключению.
Программа делиться на:
1. Init – Инициализацию
2. Executive – Исполнитель
3. Uninstall – Деинсталляцию
Вид:
__C_task void main (void)
{
unsigned char _Main_Sequence=0;
for (;
![Прикольно](images/smilies/icon_wink3.gif)
{
switch (_Main_Sequence)
{
case 0:
{// Инициализация
Init_System_Timer;
Init_Buzzer;
Init_SPI;
Init_EEPROM();
Init_KEYS();
Init_LCD();
Init_WAKE_M();
__SEI;
_Main_Sequence++;
//----------------------------------------------
// Предварительная установка параметров
//----------------------------------------------
}
break;
case 1:
{// Основной исполнитель
Executive_System_Timer;
Executive_Buzzer();
Executive_EEPROM();
Executive_KEYS ();
Executive_LCD ();
if (System_Error)_Main_Sequence++;
}
break;
case 2:
{// Uninstall
// Для правильной остановки узла машины
}
break;
*/
}
}
}
Что касается Executive_######();
void Executive_EEPROM (void)
{
if (Executive_EEPROM_Enable)
{
.......
}
}
Если они небольшие, то использовать через #define, а если нет, тогда как функция.
Эти Executive_######(); построены по при принципу switch - case и бывают двух типов:
- ведомые (управляются другими Executive_######());
1. с автоматическим завершением. Например, запись байта в память - этот исполнитель записал байт, а потом сам себя заблокировал, что бы не занимать процессорное время - Executive_EEPROM_Enable = 0.
2. без автоматического завершения - полностью управляется другими функциями - ведущими.
- ведущие - основной исполнитель
Основной исполнитель. Например в моих проектах - с LCD и клавиатурой это был Executive_MENU (). Который отслеживает текущий пункт меню и разрешает выполнение того или иного процесса - сохранить параметры, активировать узел A, B или С? ну и запустить или остановить машину.
Представим себе машину из трех конвейеров, который транспортирует - еще горячие котлеты
![Валяюсь от смеха](images/smilies/icon_biggrin.gif)
. Машина имеет два режима Режим ожидания и Режим работы. В режиме ОЖИДАНИЯ можно запускать и останавливать отдельно каждый конвейер. А в режиме Работы - они все работают одновременно, но если попалась холодная котлета (по датчику), то ее необходимо отбраковать. Так вот, в режиме ОЖИДАНИЯ Основной исполнитель использует ВЕДОМЫЕ исполнители без автозавершения, а в режиме РАБОТЫ использует ВЕДОМЫЕ исполнители с автозавершением.
Еще пример.
Необходимо упаковать 70 грамм семечек в пакетик и выполнить его контрольную проверку на выходе.
1. Выполнение дозирования дозатором в бункер, который взвешивается.
2. Подготовка упаковочной пленки и ТЭНов для спайки - ТЭНы вывести в исходное положение.
3. Из бункера высыпать в сформированный пакетик (только одна сторона не запаяна).
4. Прижать ТЭНы: спаять незапаяную сторону и отрезать пакетик.
5. Пропустить пакетик через машину динамического взвешивания - вращается конвейер на тензодатчике, через который пропускается пакетик, и пока пакетик находиться на нем происходит анализ его веса, и если плохой (значительно больше или меньше 70 г.) - отбраковать.
Так вот ОСНОВНОЙ ИСПОЛНИТЕЛЬ выполняет функцию слежения за всем процессом и поочередного включения (отключения) ведомого исполнителя на каждом этапе.
Просто и удобно, быстро понимаешь работу машины, если это чужой исходник. Быстро можешь изменить тот или иной исполнитель, т.к. он имеет минимальную завязку (общие переменные, параметры и т.д) с другими исполнителями.
Почему я пишу об этом, просто смотришь на исходники, которые даются в книгах по микроконтроллерах, то просто голову срывает, как оно работает, или где находиться то или другое. Целая куча комментов, все сбросано в одну функцию или наоборот все в разных и т.д. Если сразу научить начинающего к какой-то структуре, то все становиться на много проще.
Что вы можете сказать и какой Ваш подход, хотя бы в общем???