Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
21.02.2009, 00:27
|
|
Вид на жительство
Регистрация: 11.12.2006
Сообщений: 317
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
CVAVR , или колупаем С
Привет.
Сижу програмлю.
Возникла проблема.
Есть задача.
По прерыванию от таймера идет выполнение некоторого куска кода (читаем с АЦП, пишем в порты).
В основной проге просто висит замкнутый цикл.
Надо сделать таким образом чтобы можна было "выпрыгивать" с прерывания, по выполнению некоторого условия, в совсем другой кусок проги, а потом возврат в данный цикл.
Другими словами опишу код так:
Выполнить некоторое действие по условию, потом перейти в замкнутый цикл.
Замкнутый цикл.
Прерывание - читаем значение АЦП, если оно больше некоторого значения - прыгнуть на "Выполнить некоторое действие по условию, потом перейти в замкнутый цикл."
На асме я делал так:
Просто прыгал с прерывания на необходимую точку, дальше обнулял стекпоинтер и сбрасывал флаг прерывания. Другими словами - порга наглухо переходила на необходимый кусок кода, при чем прерывание было "завершено", а возращатся с него просто некуда - в стеке нету точки возврата. Другими словами я ребутил выполнение програми без перезагрузки МК.
Как сделать данное чудо на Сишке?
Проще описать можно так - как прыгнуть в процедуру не завершив при этом прерывание, и не возвращаться в обработчик прерывания до наступления следующего прерывания.
Код:
|
;***********************************
OVF3addr_prog:
ldi TEMP_A, 4
cp Programm_group,TEMP_A
brne Programm_group_not_4
;-----------------------------------
clr TEMP_A
mov Global_Error_ID, TEMP_A
mov Global_Alarm_group_ID, TEMP_A
mov Programm_group_ID, TEMP_A
;-----------------------------------
; Занулим все флаги прерываний по таймерах
clr TEMP_A
out TIFR0, TEMP_A
out TIFR1, TEMP_A
out TIFR2, TEMP_A
out TIFR3, TEMP_A
out TIFR4, TEMP_A
out TIFR5, TEMP_A
;-----------------------------------
out SREG, TEMP_A
;-----------------------------------
ldi TEMP_A,low(RAMEND)
out SPL,TEMP_A
ldi TEMP_A,high(RAMEND)
out SPH,TEMP_A
;-----------------------------------
jmp Programm_Stop ; пригаем куда хочем, т.е. в замкнутый цикл основной проги
Programm_group_not_4:
reti
;***********************************
;===================================
Programm_Stop:
nop
nop
jmp Programm_Stop |
|
|
|
|
21.02.2009, 00:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Просто прерывание сделайте котротким. А процедура подождет чуток.
Увеличение частоты такта еще более сократит ожидание.
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
21.02.2009, 00:54
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Re: CVAVR , или колупаем С
Сообщение от ua_gruzin
|
Замкнутый цикл.
Прерывание - читаем значение АЦП, если оно больше некоторого значения - прыгнуть на "Выполнить некоторое действие по условию, потом перейти в замкнутый цикл."
|
Наверно так:
Замкнутый цикл.
Прерывание - читаем значение АЦП, если оно больше некоторого значения - ставим флаг и выходим из прерывания в цикл. Иначе 0 не ставим флаг но из прерывания все равно выходим.
В цикле - если флаг есть, то прыгнуть на "Выполнить некоторое действие по условию", и очистить флаг.
потом перейти обратно в замкнутый цикл.
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
21.02.2009, 02:30
|
|
Вид на жительство
Регистрация: 11.12.2006
Сообщений: 317
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
... что можете сказать о:
longjmp
setjmp
goto
На счёт первых двух не въехал вообще....
На счёт последнего - компилятор пишет (если перепригывать с одной процедуры в дгугую) типо не знает куда пригнуть, хотя точка выхода описана.
loop:
/*
*/
в другой процедуре
goto loop;
Так не работает. В приделах одной процедуры - все путём.
На счёт короткого прерывания - оно и так коротко. Просто в нем осуществляется ветвение программы.
Цитата:
|
В цикле - если флаг есть, то прыгнуть на "Выполнить некоторое действие по условию", и очистить флаг.
|
Я не могу постоянно мониторить флаг. Там исполняется другая программа. Я ее разрываю прерываниями, чтобы не нарушать ее целостность и не беспокоится о ее правльном и всоевременном выполении.
Просто возникает необходимость когда нада экстренно завершить текущую программу и переключится на другю, с дальнейшим переключением на первую (после обработки ошибки).
|
|
|
|
21.02.2009, 02:41
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Тогда вместо флага "дерните" ножку МК которая вызовет реальное прерывание в которое вы попадете по окончании прерывания по АЦП.
Прерывания в AVR - http://avr123.nm.ru/03.htm
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
21.02.2009, 06:22
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: CVAVR , или колупаем С
Сообщение от ua_gruzin
|
Код:
|
;***********************************
OVF3addr_prog:
ldi TEMP_A, 4
cp Programm_group,TEMP_A
brne Programm_group_not_4
;-----------------------------------
.......
;-----------------------------------
jmp Programm_Stop ; пригаем куда хочем, т.е. в замкнутый цикл основной проги
Programm_group_not_4:
reti
;***********************************
;===================================
Programm_Stop:
nop
nop
jmp Programm_Stop |
|
Обалденный обработчик! Второй командой изменили SREG и... вернулись в основной цикл, если Programm_group не равно 4. Вот в основном цикле радость то будет...
По теме - если в программе встречается безусловный переход ( он же go to), то значит что то неладно в алгоритме. И в обработчике SREG и используемые регистры идут в стек, выход без их восстановления приведет к непредсказуемым последствиям. Хотя одно очевидно - стек будет расти заполняемый мусором.
И еще по примеру - Вы прыгаете на Programm_Stop ДО выхода из обработчика. Т.е. на самом деле этот цикл является частью обработчика, ведь reti не выполнена. Ровно с таким же успехом можно никуда не прыгать, а вставить этот цикл внутрь обработчика, все равно прерывания запрещены.
|
|
|
|
21.02.2009, 12:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Re: CVAVR , или колупаем С
Сообщение от kison
|
в обработчике SREG и используемые регистры идут в стек, выход без их восстановления приведет к непредсказуемым последствиям. Хотя одно очевидно - стек будет расти заполняемый мусором.
|
Поэтому начинающим советую писать на Си в CVAVR - компилятор сам "думает" как правильный АСМ сделать, а из него и прошивку правильную.
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
21.02.2009, 17:28
|
|
Вид на жительство
Регистрация: 11.12.2006
Сообщений: 317
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
Цитата:
|
Хотя одно очевидно - стек будет расти заполняемый мусором.
|
Куда он будет расти после команды?!
Код:
|
ldi TEMP_A,low(RAMEND)
out SPL,TEMP_A
ldi TEMP_A,high(RAMEND)
out SPH,TEMP_A |
Я принудительно:
1. "убиваю" все что имеет отношение к стеку (обнуляю стек),
2. обнуляю программный счётчик и записываю в РС адрес с какого места начать дальше выполнять прогу (jmp .....) по завершению прерывания (мк при следующей команде не будет знать куда прыгать кроме адреса ....),
3. отключаю флаги прерывания (тем самым завершаю прерывание), что убирает возможность повторного вызова прерывания когда МК еще не прыгнул на ....,
4. с прерывания МК прыгает по том адресу, который записан в стеке (при вызове РС записывается автоматом в стек), а поскольку его там нету - ему прыгать некуда, прога идет в низ на автомате (еще не завершено прерывание и РС дальше увеличивается) до тех пор, пока не впишу другое значение РС (....) командой jmp .....,
Вот и все.
Другими словами - обнулил стек - убрал точку возврата прерывания, обнулил флаги - "завершил" прерывания, записал адрес куда нада прыгнуть для дальнейшего выполнения проги (все остальные переходы в проге, т.е. алгоритмы что раньше выполнялись просто будут стёрты с стека, т.е. просто будут удалены как таковы, и начнет прога заново выполняться только с места ....)
Вернемся все же к С.
Опишите что делают на примере
longjmp
setjmp
В мануале там нету толкового описания.... потому и не понял как их юзать.
|
|
|
|
21.02.2009, 17:40
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
Сообщение от ua_gruzin
|
Вернемся все же к С.
Опишите что делают на примере
longjmp
setjmp
В мануале там нету толкового описания.... потому и не понял как их юзать.
|
Это Си разве ???
Если AVR ASM по-русски - то там посмотрите
http://asmHelpAVR.narod.ru
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
21.02.2009, 18:16
|
|
Вид на жительство
Регистрация: 11.12.2006
Сообщений: 317
Сказал спасибо: 0
Сказали Спасибо 12 раз(а) в 11 сообщении(ях)
|
..........
Non-local Jump Functions Previous Top Next
--------------------------------------------------------------------------------
These functions can execute a non-local goto.
They are usually used to pass control to an error recovery routine.
The prototypes for the non-local jump functions are placed in the file setjmp.h, located in the .INC subdirectory. This file must be #include -ed before using the functions.
int setjmp(char *env)
This function saves the current CPU state (Y, SP, SREG registers and the current instruction address) in the env variable.
The CPU state can then be restored by subsequently calling the longjmp function.
Execution is then resumed immediately after the setjmp function call.
The setjmp function will return 0 when the current CPU state is saved in the env variable.
If the function returns a value different from 0, it signals that a longjmp function was executed.
In this situation the returned value is the one that was passed as the retval argument to the longjmp function.
In order to preserve the local variables in the function where setjmp is used, these must be declared with the volatile attribute.
Из мануала CVAVR
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
Структуры в CVAVR
|
ua_gruzin |
Микроконтроллеры, АЦП, память и т.д |
9 |
04.02.2009 12:58 |
CVAVR while и таймер
|
kr11507 |
Микроконтроллеры, АЦП, память и т.д |
10 |
13.12.2008 21:29 |
WinAVR или CVAVR
|
melkij |
Микроконтроллеры, АЦП, память и т.д |
0 |
07.08.2008 13:59 |
Програмирование CVAVR
|
buka_2004 |
Микроконтроллеры, АЦП, память и т.д |
54 |
02.12.2007 20:31 |
Нужна помощь новичку. Или я глючу, или Протеус или КодеВизио
|
sns13 |
Микроконтроллеры, АЦП, память и т.д |
25 |
12.11.2006 10:24 |
Часовой пояс GMT +4, время: 04:25.
|
|