|
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 таким образом я решилэту задачу без усложния кода..
|
|
|
|
|
Jan 27 2011, 08:50
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Цитата(DmSk @ Jan 26 2011, 17:02)  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 таким образом я решилэту задачу без усложния кода.. 1: Я бы sei и инициализацию стека сделал сразу после метки main а в процедуре zavodim вообще стек не трогал. 2: Выход из прерывания timer_ovr может всетаки reti? Цитата Atmega8:Выход с прерывания по rjmp, с последующей корректировкой указателя стека и установкой флага глоб.прерывания (sei), слишком ли грубый ход ? Как по мне это абсолютно нормальный ход если это действительно необходимо.
|
|
|
|
|
Jan 27 2011, 11:14
|
Группа: Участник
Сообщений: 12
Регистрация: 24-07-09
Из: Барнаул
Пользователь №: 51 518

|
Цитата(zombi @ Jan 27 2011, 11:50)  2: Выход из прерывания timer_ovr может всетаки reti? Как по мне это абсолютно нормальный ход если это действительно необходимо. Опечатался, конечно reti, так как прерывание а не процедура Цитата(zombi @ Jan 27 2011, 11:50)  1: Я бы sei и инициализацию стека сделал сразу после метки main а в процедуре zavodim вообще стек не трогал. если в процедуре флаг по sei не поднять то, прерывания не будут вообще работать, так как я из прерывания сразу шагаю по rjmp в "Заводим", а этот флаг назад выставляется по "reti", а поскольку у меня его не будут, то приходится его руками выставлять. Со стеком такая же беда, нет rety, нет возврата указателя, таким образаом вызывая прерывания и не возвращаясь на место у нас стек переполнится Цитата(Maik-vs @ Jan 27 2011, 13:20)  Если всё понято, то надо так и делать. Не "процессов много" а событий больше одного. У вас: несколько кнопок, датчик спидометра, датчик нейтральной передачи, много состояний (стадий выполнения) этих двух процессов. Прерывания нужны для отслеживания неотложных событий или очень редких, чтобы не тратить время на постоянный опрос (для контроллеров не очень актуально). Нарисуйте граф своих процессов (гуглить картинки "граф состояний", "граф переходов") - увидите, что вершин не меньше 4-6-ти. И не я один вам это говорю. Кроме того, получите заготовку программы для следующих проектов.
Хотя, если "неохото"... ну, купите готовое Спасибо, можете дать ссылку в инете на какойнить шаблон/пример программы, чтобы не совсем с нуля писать ?
|
|
|
|
Сообщений в этой теме
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 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
|
|
|