|
Общая структура программы? |
|
|
|
May 30 2011, 12:58
|
Местный
  
Группа: Свой
Сообщений: 281
Регистрация: 29-04-08
Из: Москва
Пользователь №: 37 149

|
Это мой первый опыт общёния с контроллерами на старости лет, так что прошу сильно не пинать. Итак, делается управляющая часть для НЧ-генератора 5Гц-1МГц. Она должна выполнять следующие функции: 1) Опрос состояния органов управления - кнопки, энкодер, переключатели. 2) Выдачу команд по SPI на ЦАП, управляющий частотой и релюшки переключения диапазонов. 3) Измерение частоты генератора , алгоритм приведён здесь: алгоритм4) Отображение частоты и другой информации на LCD 16x2 Вполне возможно, потребуется дописывать функционал в дальнейшем, например, измерение напряжения с помощью встроенного АЦП и статистическую обработку частотомера. Сейчас написаны пункты №1, №2, №4, и приступаю к №3. Вот тут-то и встал вопрос об общей структуре программы. Фактически параллельно должны выполняться несколько задачь №1 требует периодического выполнения по таймеру с точностью ,скажем, +-20% от номинала. Сейчас написана по прерыванию одного из таймеров. №2 требует значительного времени на исполнение команды (рэле-медленное устройство) №3 требует максимально быстрой и всегда одинаковой по кол-ву циклов реакции на прерывание ICx, в противном случае возникают ошибки счёта. Где можно посмотреть - почитать общие подходы к построению таких программ? Единственная книга по теме, котораю попалась в руки - embedded multitasking Но методика, изложенная там, показалась мне малореальной в практическом смысле в условиях постоянного дописывания функционала. Да, пишется всё под pic24h
Сообщение отредактировал shkal - May 30 2011, 13:03
|
|
|
|
|
May 30 2011, 13:27
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(shkal @ May 30 2011, 15:58)  Это мой первый опыт общёния с контроллерами на старости лет, так что прошу сильно не пинать. Итак, делается управляющая часть для НЧ-генератора 5Гц-1МГц. Она должна выполнять следующие функции: 1) Опрос состояния органов управления - кнопки, энкодер, переключатели. 2) Выдачу команд по SPI на ЦАП, управляющий частотой и релюшки переключения диапазонов. 3) Измерение частоты генератора , алгоритм приведён здесь: алгоритм4) Отображение частоты и другой информации на LCD 16x2 Вполне возможно, потребуется дописывать функционал в дальнейшем, например, измерение напряжения с помощью встроенного АЦП и статистическую обработку частотомера. Сейчас написаны пункты №1, №2, №4, и приступаю к №3. Вот тут-то и встал вопрос об общей структуре программы. Фактически параллельно должны выполняться несколько задачь №1 требует периодического выполнения по таймеру с точностью ,скажем, +-20% от номинала. Сейчас написана по прерыванию одного из таймеров. №2 требует значительного времени на исполнение команды (рэле-медленное устройство) №3 требует максимально быстрой и всегда одинаковой по кол-ву циклов реакции на прерывание ICx, в противном случае возникают ошибки счёта. Где можно посмотреть - почитать общие подходы к построению таких программ? Единственная книга по теме, котораю попалась в руки - embedded multitasking Но методика, изложенная там, показалась мне малореальной в практическом смысле в условиях постоянного дописывания функционала. Да, пишется всё под pic24h А хватит ли вам ресурсов pic24H? Какая частота? У pic24h только 40 MIPS при 80MHZ. На мой взгляд, тут аппаратный вход таймер/счетчик можно задействовать. Также в pic24H имеется DMA, который поможет Вам сэкономить ресурсы процессора.
--------------------
Magic Friend
|
|
|
|
|
May 30 2011, 16:56
|
Профессионал
    
Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347

|
медленные и некритичные по времени задачи (кнопки,индикация,работа с ЦАПом/реле) можно выполнять в основном цикле (на каждую задачу - state machine с программным счетчиком/флагом состояния), задачи требующие точного отсчета - в прерываниях таймеров с высоким приоритетом, энкодеры - на внешние прерывания с меньшим приоритетом Цитата №3 требует максимально быстрой и всегда одинаковой по кол-ву циклов реакции на прерывание ICx, в противном случае возникают ошибки счёта. регистры ICx буферизированы или нет ? Цитата Поставьте еще один маленький контроллер только для измерения частоты не нужно, один pic24h потянет с десяток таких приборов
Сообщение отредактировал ukpyr - May 30 2011, 16:57
|
|
|
|
|
May 31 2011, 08:54
|
Участник

Группа: Участник
Сообщений: 57
Регистрация: 8-12-04
Пользователь №: 1 403

|
Цитата(shkal @ May 30 2011, 16:58)  №3 требует максимально быстрой и всегда одинаковой по кол-ву циклов реакции на прерывание ICx, в противном случае возникают ошибки счёта. Воспользуйтесь функцией Capture и тогда от задержки по обработке прерывания ничего зависеть не будет. Частотомер будет практически аппаратный. Алгоритм определения частоты у вас уж очень чудной. Два таймера для начала и окончания интервала замера... Все названные 4 пункта представляют достаточно простой набор задач. Загрузка МК не превысит несколько процентов. Единственная критичная вещь - максимальная измеряемая частота. Помнится старинный частотомер на PIC16F84 легко мерил до 50Мгц. На 24h я думаю этот показатель будет выше 100Мгц . А вообще полагается ставить аппаратный прескалер.
|
|
|
|
|
May 31 2011, 12:23
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(ukpyr @ May 30 2011, 20:56)  медленные и некритичные по времени задачи (кнопки,индикация,работа с ЦАПом/реле) можно выполнять в основном цикле (на каждую задачу - state machine с программным счетчиком/флагом состояния), задачи требующие точного отсчета - в прерываниях таймеров с высоким приоритетом, энкодеры - на внешние прерывания с меньшим приоритетом +1. Сам так делаю. Это и есть ответ на вопрос о подходе к построению системы. При таком подходе ф-ция main() в общих чертах выглядит так: Код int main(void) { module_a_init(); module_b_init(); ... for (;;) { module_a_poll(); module_b_poll(); ... } } Соответственно, ф-ции module_x_poll() возвращаются быстро, чтобы обеспечить гарантированное максимальное время выполнения одного цикла. В такую конструкцию у меня помещаются кнопки, энкодер, GUI (480x272 LCD), HTTP, SNMP, SNTP, управление собственно устройством и т.д.
|
|
|
|
|
Jun 1 2011, 09:24
|
Местный
  
Группа: Свой
Сообщений: 281
Регистрация: 29-04-08
Из: Москва
Пользователь №: 37 149

|
ukpyr, спасибо, ответ максимально по делу. Пойду читать литературу по state machine. Вот ещё какой вопрос возник: каким образом реализуются неблокирующие функции задержки в такой среде? Если, допустим, использовать один из таймеров и по его прерыванию устанавливать флаг, то этот флаг должен в цикле читаться функцией, которой нужна эта задержка. Но при этом чем точнее нужно отсчитать интервал, тем чаще нужно проверять флаг, т.е. в пределе опять получаем блокирующую функцию. Или же управление из прерывания таймера нужно возвращать не в ту задачу, в которая исполнялась во время вызова прерывания, а в ту, которая использовала функцию задержки, но это как-то очень по-хакерски выглядит.
|
|
|
|
|
Jun 1 2011, 12:36
|
Профессионал
    
Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347

|
Цитата Если, допустим, использовать один из таймеров и по его прерыванию устанавливать флаг, то этот флаг должен в цикле читаться функцией, которой нужна эта задержка. флаг читается, только в основном цикле. Когда установлен - вызываются функции, привязанные к данному периоду опроса, в функции обрабатывается свой таймер и текущее состояние. При переходе к следующему состоянию таймер функции заряжается новым значением. Код ... if (flag_10ms) { flag_10ms = 0; module_a_poll(); module_b_poll(); ... } ...
// функция вызывается с периодом 10мс void module_a_poll(void) { static unsigned int module_a_tmr; // таймер задачи static char module_a_state; // текущее состояние задачи if (module_a_tmr) module_a_tmr--; // таймер текущего состояния не закончился else { // таймер закончился - обработка текущего состояния, переход к следующим и т.д. if (module_a_state == 0) { ... // выполнили действия для состояния 0 module_a_state = 1; // загрузили новое состояние и таймер задержки на 1 сек module_a_tmr = 100; else if (module_a_state == 1) { } ... } }
Сообщение отредактировал ukpyr - Jun 1 2011, 12:38
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|