|
Atmega8:Выход с прерывания по rjmp, с последующей корректировкой указателя стека и установкой флага глоб.прерывания (sei), слишком ли грубый ход ? |
|
|
|
Jan 26 2011, 09:43
|
Группа: Участник
Сообщений: 12
Регистрация: 24-07-09
Из: Барнаул
Пользователь №: 51 518

|
На данный момент существует самодельное устройство автозавода автомобиля по таймеру, управляющий контроллер ATMEGA8. Задумал добавить кнопку, что бы можно было заводить с кнопки. Получается так: сел в машину, нажал кнопку, и авто завелось, при этом автомобиль мог до этого стоять на «программе прогрева», соответственно «программа прогрева» должна быть прекращена. Появились небольшие вопросы при реализации задуманного в программе. Программа написана на асме, весь текст приводить не буду , напишу «обычным языком» и коротко без деталей и ньансов. Вопрос: Слишком ли будет грубо переходит из прерывания в основную программу, установив указатель стека в начало и установив флаг гл. прерывания («sei») так как он при вызове прерывания сбрасывается? Решил сделать так, потому что команды от кнопок будут обрабатываться мгновенно не дожидаясь выполнения подпрограмм(паузы и т.д.)
Существует ли альтернатива этому механизму ?
Вот алгоритм программы ______________________________ Иницируем таймер опроса кнопок Разрешаем прерывания по IRQ1 для тахометра (считать импульсы, решать завелась или незавелась) Стек в начало;
Основной цикл:
Проверка статуса кнопок: Мигаем диодом, авто ждет команды Rjmp Проверка статуса кнопок
// в основном цикле я разместил оба процесса, прогрев и заводим с кнопки Прогрев: Стек в начало; «Ldi r16,low(RAMEND) out SPL,r16 ldi r16,high(RAMEND) out SPH,r16» установим флаг гл.прерывания «sei» Пауза 1 час Rcall ЗавестиМашину Пауза 5 минут глушим Rjmp Прогрев
ЗаводимСКнопки: Стек в начало; установим флаг гл.прерывания;
//Проверка заведена ли машина Если машина заведена то rjmp Проверка статуса кнопок Иначе rcall ЗавестиМашину rjmp Проверка статуса кнопок Rjmp ЗаводимСКнопки
Rjmp Основной цикл
ЗавестиМашину: Запрещаем прерывание таймера опроса кнопок Заводим включая зажигание и включая стартер по определенному алгоритму Разрешаем прерывание таймера опроса кнопок Ret
Прерывание таймера опроса кнопок: // если нажали кнопку завести то сразу переходим на программу завести с кнопки // тем самым команда ret не будет никогда выполнена // мы заменим её в основной программе возвратом указателя стека и установкой флага // глобального прерывания?! Если нажата кнопку 1 (завести авто) То rjmp ЗаводимСКнопки
Если нажата кнопку 2 (прогрев авто по таймеру) То rjmp Прогрев
Ret
Сообщение отредактировал DmSk - Jan 26 2011, 09:45
|
|
|
|
|
 |
Ответов
|
Jan 26 2011, 10:45
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
А! обычная вещь - прерывание длиной в секунду. Во-первых, нужно оценить все временнЫе параметры события: возможная частота событий, задержка реакции на событие. Например, датчик тахометра: частота может быть большой, время реакции критично не всегда. Датчик положения коленвала для запуска зажигания - тут критично время задержки. Для кнопки время срабатывания самой кнопки несколько миллисекунд, комфортное время реакции на нажатие 0,2-0,5 секунд. Поэтому в прерывании нужно выставить флаг "нажата кнопка", и всё! Дальше основной цикл, зацепившись за этот флаг, выяснит, что за кнопка, что делать и т.д. У Вас "Заводим включая зажигание и включая стартер по определенному алгоритму" может занять секунд 5 легко. И что - всё это время кнопки не работают? А прервать "определённый алгоритм" никак? Поэтому. Алгоритм имеет тактирование от таймера, который (относительно редко, в прерывании?) наращивает регистр состояния алгоритма. В основном цикле (всё время) анализируется состояние алгоритма, состояние кнопок, ещё чего-то и предпринимаются необходимые движняки. Тогда, обнаружив нажатую кнопку, можно прервать или изменить "определённый алгоритм", чтобы остановить зажигание или там перейти на другой режим. Для осознания возможных состояний и движений алгоритма рисуется граф переходов. Вершины - состояния, рёбра - переходы. Рисуем на бумажке, подписываем все вершины (регистр состояния) и рёбра (условие перехода). Всё - программирование закончено, остаётся кодирование на ассемблере.
Сообщение отредактировал Maik-vs - Jan 26 2011, 10:55
|
|
|
|
|
Jan 26 2011, 14:02
|
Группа: Участник
Сообщений: 12
Регистрация: 24-07-09
Из: Барнаул
Пользователь №: 51 518

|
Цитата(Maik-vs @ Jan 26 2011, 13:45)  А! обычная вещь - прерывание длиной в секунду. Во-первых, нужно оценить все временнЫе параметры события: возможная частота событий, задержка реакции на событие. Например, датчик тахометра: частота может быть большой, время реакции критично не всегда. Датчик положения коленвала для запуска зажигания - тут критично время задержки. Для кнопки время срабатывания самой кнопки несколько миллисекунд, комфортное время реакции на нажатие 0,2-0,5 секунд. Поэтому в прерывании нужно выставить флаг "нажата кнопка", и всё! Дальше основной цикл, зацепившись за этот флаг, выяснит, что за кнопка, что делать и т.д. У Вас "Заводим включая зажигание и включая стартер по определенному алгоритму" может занять секунд 5 легко. И что - всё это время кнопки не работают? А прервать "определённый алгоритм" никак? Поэтому. Алгоритм имеет тактирование от таймера, который (относительно редко, в прерывании?) наращивает регистр состояния алгоритма. В основном цикле (всё время) анализируется состояние алгоритма, состояние кнопок, ещё чего-то и предпринимаются необходимые движняки. Тогда, обнаружив нажатую кнопку, можно прервать или изменить "определённый алгоритм", чтобы остановить зажигание или там перейти на другой режим. Для осознания возможных состояний и движений алгоритма рисуется граф переходов. Вершины - состояния, рёбра - переходы. Рисуем на бумажке, подписываем все вершины (регистр состояния) и рёбра (условие перехода). Всё - программирование закончено, остаётся кодирование на ассемблере. спасибо всё понятно, если процессов много то конечно, а у меня 2 + переписывать код полностью неохото потому . всё же хотелось показать свой извратный код, пишу пример находу постараюсь, чтобы было понятно: main: ss: rjmp ss zavodim: // вернем указатель стека ПОСКОЛЬКУ ВЫШЛИ ИЗ ПРЕРЫВАНИЯ ПО RJMP а не RET и возвращаться несобираемся ! ldi r16,Low(RAMEND) out SPL,r16 ldi r16,High(RAMEND) out SPH,r16 sei \\ выставим флаг прерываний ПОСКОЛЬКУ ВЫШЛИ ИЗ ПРЕРЫВАНИЯ ПО RJMP а не RET rcall zavesti //процедура завода авто rjmp main timer_ovr: sbis PINB,3 RCALL zavodim \\ ВЫХОДИМ ИЗ ПРЕРЫВАНИЯ ПО RJMP и невозвращамся ВООБЩЕ поскольку там куда идем  указатель стека правим и гл.флаг прерывания возвращаем! ret таким образом я решилэту задачу без усложния кода..
|
|
|
|
Сообщений в этой теме
DmSk Atmega8:Выход с прерывания по rjmp, с последующей корректировкой указателя стека и установкой флага глоб.прерывания (sei), слишком ли грубый ход ? Jan 26 2011, 09:43 GDI Вместо такого описания, лучше бы нарисовали алгори... Jan 26 2011, 10:13 DmSk Цитата(GDI @ Jan 26 2011, 13:13) И что зн... Jan 26 2011, 10:40  GDI Цитата(DmSk @ Jan 26 2011, 13:40) это нап... Jan 26 2011, 14:12   DmSk Цитата(GDI @ Jan 26 2011, 17:12) Вот пото... Jan 27 2011, 03:01    GDI Цитата(DmSk @ Jan 27 2011, 06:01) пустой ... Jan 27 2011, 08:11  zombi Цитата(DmSk @ Jan 26 2011, 17:02) main:
... Jan 27 2011, 08:50   DmSk Цитата(zombi @ Jan 27 2011, 11:50) 2: Вых... Jan 27 2011, 11:14    zombi Цитата(DmSk @ Jan 27 2011, 14:14) если в ... Jan 27 2011, 12:18     DmSk Цитата(zombi @ Jan 27 2011, 15:18) Ну тог... Jan 27 2011, 14:36      zombi Цитата(DmSk @ Jan 27 2011, 17:28) дребезг... Jan 27 2011, 14:42  Maik-vs Цитата(DmSk @ Jan 26 2011, 17:02) спасибо... Jan 27 2011, 10:20 _Pasha кнопки по прерыванию можно только в одном случае -... Jan 26 2011, 12:36 ILYAUL Цитатаесли нажалии кнопку "прогрев по таймеру... Jan 27 2011, 18:21 DmSk Цитата(ILYAUL @ Jan 27 2011, 21:21) Конеч... Jan 28 2011, 03:22  ILYAUL Цитата(DmSk @ Jan 28 2011, 06:22) Процесс... Jan 30 2011, 15:11 GDI Цитатастатус процесса Это хорошие слова, еще чуть-... Jan 28 2011, 12:36
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|