|
ATmega 16 и прерывания, переход по прерыванию не в ту степь |
|
|
|
Apr 18 2011, 09:49
|
Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769

|
Добрый день! Нужна помощь в поиске ошибки,скорее всего в голове. Программировал до этого 2313. Решил перейти на Мегу 16 и сразу грабли.Вот: CODE .device Atmega16 .nolist .include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m16def.inc" .list ;====== Объявления =========================================== .def temp =r16 ;=======Начало программы======================================== jmp init ;RESET jmp Impuls1 ;внешнее прерывание от INT0 jmp Impuls2 ;внешнее прерывание от INT1 reti reti reti reti reti reti jmp Display ;таймер/счётчик №0 переполнение reti reti reti reti reti reti reti reti reti reti reti
;========= СТЕК ================================================= ldi temp,LOW(RAMEND) out SPL,temp ldi temp,HIGH(RAMEND) out SPH,temp
;=========================================================================== Init: ser temp ;все выхода PB1-PB7_индикаторы out DDRB,temp ldi temp,0b11100111 ; PD3@PD4 вход счета импульсов out DDRD,temp ; PD0-PD2_номер индикатора
ldi temp,0b00000010 ;частота TCNT0 равна CK/8 out TCCR0,temp ldi temp,0b00001100 ;частота TCNT1 равна CK/256 out TCCR1B,temp ;сбрасывать TC1 при совпадении ldi temp,0b10110111 out OCR1AH,temp ldi temp,0b00011011 out OCR1AL,temp
ldi temp,0b11000011 out GICR,temp ldi temp,0b00001010 ;прерывание INT1 - низкий уровень out MCUCR,temp
ldi temp,0b00001001 ;разреш.прерывания по переполнению TC0 out TIMSK,temp sei ;================================================= CHK: ldi temp,0b00000001 ;устанавливаем 0 нулевого разряда out PortD,temp mov temp,r0 out PortB,temp sei ;========================================================== Start: rjmp Start Impuls1: nop reti
Impuls2: nop reti
Display: nop reti
При возникновении прерывания переходит на строчку " jmp init ;RESET". Шаманский бубен и ночные пляски у костра не помогли! Программа AVR Studio.
Сообщение отредактировал IgorKossak - Apr 18 2011, 11:45
Причина редактирования: [codebox] !!!
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Apr 18 2011, 10:06
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (mishara777 @ Apr 18 2011, 12:49)  Шаманский бубен и ночные пляски у костра не помогли! Ночью лучше спать. Ваша метка Init находится после кода инициализации указателя стека. Значит указатель стека показывает куда угодно, а не на RAMEND. И первый же reti посылает программу в произвольное место. P.S. И в следующий раз при публикации кода используйте кнопку  на форме ввода сообщения.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 18 2011, 10:23
|
Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769

|
Прошу прощения за оформление первого топа,сказывается нечастое обращение к форумам!Спасибо ,что быстро ответили ,но вначале (на 2313) я так и поступал.И в этот раз стек переносил из угла в угол,писал и rjmp и jmp - итог один "jmp init"
|
|
|
|
|
Apr 18 2011, 10:29
|
Местный
  
Группа: Участник
Сообщений: 235
Регистрация: 20-11-10
Пользователь №: 61 032

|
Цитата(mishara777 @ Apr 18 2011, 13:49)  Решил перейти , но сэкономил время на чтении 45 страницы. Код .org INT0addr ; это не магическая волшебная команда, а точное число. адрес. reti
.org INT1addr ; и это reti
.org ... Экономить метки орги можно, но нельзя... когда не уверен.
Сообщение отредактировал нечитатель - Apr 18 2011, 10:33
|
|
|
|
|
Apr 18 2011, 10:37
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (mishara777 @ Apr 18 2011, 13:23)  И в этот раз стек переносил из угла в угол Недопонял. Из какого угла? В какой угол? Ваша программа после включения питания попадает на команду CODE jmp init;RESET Выполнив ее попадает в строки CODE Init: ser temp;все выхода PB1-PB7_индикаторы А строки CODE ldi temp,LOW(RAMEND) out SPL,temp ldi temp,HIGH(RAMEND) out SPH,temp остаются неохваченными. Перенесите метку Init: в строку перед ldi temp,LOW(RAMEND). И таки да, для векторов очень желательно явно (.org) указывать адрес. Считать команды - велика вероятность ошибиться.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 18 2011, 10:41
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Плюс к тому, что установка стека не выполняется, ошибка в том, что в mega16 вектора прерываний занимают по 2 адреса, а в tiny2313 - один. а неиспользуемые прерывания заглушены reti - один адрес, надо добавить до двух - nop, reti или reti, reti или так: CODE ;... .org 0 jmp init ;RESET
.org INT0addr jmp Impuls1 ;внешнее прерывание от INT0
.org INT1addr jmp Impuls2 ;внешнее прерывание от INT1
.org OVF0addr jmp Display ;таймер/счётчик №0 переполнение
.org INT_VECTORS_SIZE init: ;========= СТЕК ================================================= ldi temp,LOW(RAMEND) out SPL,temp ldi temp,HIGH(RAMEND) out SPH,temp
да, уже подсказали...
|
|
|
|
|
Apr 18 2011, 11:12
|
Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769

|
Если я правильно понял , то кусочек программы должен выглядеть так: CODE ;=======Начало программы======================================== .org 0 jmp init;RESET
.org INT0addr jmp Impuls1;внешнее прерывание от INT0
.org INT1addr jmp Impuls2;внешнее прерывание от INT1
.org OVF0addr jmp Display;таймер/счётчик №0 переполнение
.org INT_VECTORS_SIZE ;Store Program Memory Ready Handler
;=========================================================================== Init:
ser temp ;все выхода PB1-PB7_индикаторы out DDRB,temp ; ldi temp,0b11100111 ; PD3@PD4 вход счета импульсов out DDRD,temp ; PD0-PD2_номер индикатора ldi temp,0b00000010 ;частота TCNT0 равна CK/8 out TCCR0,temp ldi temp,0b00001100 ;частота TCNT1 равна CK/256 out TCCR1B,temp ;сбрасывать TC1 при совпадении ldi temp,0b10110111 out OCR1AH,temp ldi temp,0b00011011 out OCR1AL,temp
ldi temp,0b11000011 out GICR,temp ldi temp,0b11111010 ;прерывание INT1 - низкий уровень out MCUCR,temp
ldi temp,0b00001001 ;разреш.прерывания по переполнению TC0 out TIMSK,temp
ldi DisplayCounter,25 clr ZH
ldi temp,LOW(RAMEND) out SPL,temp ldi temp,HIGH(RAMEND) out SPH,temp sei ;================================================= CHK: ldi temp,0b00000001 ;устанавливаем 0 нулевого разряда out PortD,temp mov temp,r0 out PortB,temp sei ;========================================================== Честно сказать датащит до дыр стер и 45 страницу тоже,но с аглицким проблема (учили французскому),поэтому и недопонимание прочитанного.Хочется ведь не останавливаться на2313!
Сообщение отредактировал IgorKossak - Apr 18 2011, 11:46
Причина редактирования: [codebox] !!!
|
|
|
|
|
Apr 18 2011, 11:32
|
Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769

|
Спасибо за терпение! Сделал все ,как написали. Но.... опять "jmp init ;RESET"
|
|
|
|
|
Apr 18 2011, 12:24
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(mishara777 @ Apr 18 2011, 15:12)  Код ......... ldi temp,0b11000011 out GICR,temp Вот тут я, наверное, недопонял... Вы, наверное, не в области BootLoader'a свою программу располагаете? Зачем вектора "двигаете"? Цитата IVSEL: Interrupt Vector Select When the IVSEL bit is cleared (zero), the Interrupt Vectors are placed at the start of the Flash memory... IVCE: Interrupt Vector Change Enable Т.е. IVSEL должен быть нулем (он и так нулевой по сбросу), и IVCE то же (раз IVSEL менять нам не нужно) Цитата(mishara777 @ Apr 18 2011, 15:12)  Код ldi temp,0b00001001;разреш.прерывания по переполнению TC0 out TIMSK,temp Здесь разрешаются два(!) прерывания. Обработчика одного из них - нет!
|
|
|
|
|
Apr 18 2011, 13:43
|
Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769

|
Уважаемый ,Палыч! Это Цитата Обработчика одного из них - нет просто часть программы, которую написал с год назад для 2313. Хотел добавить некоторые возможности ,не хватило пинов. Вот и пытаюсь перейти на Мегу16. Вот это Цитата IVSEL: Interrupt Vector Select When the IVSEL bit is cleared (zero), the Interrupt Vectors are placed at the start of the Flash memory... IVCE: Interrupt Vector Change Enable раз десять читал,понять не смог.Поэтому менял наугад и пробовал "завести " проц.
|
|
|
|
|
Apr 18 2011, 14:02
|
Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769

|
Спасибо за совет. Сейчас буду исправлять
|
|
|
|
|
Apr 18 2011, 14:55
|
Частый гость
 
Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355

|
Цитата с аглицким проблема (учили французскому) Евстифеев А. В. - Микроконтроллеры AVR семейств Tiny и Mega фирмы Atmel скормить гуглю все на русском, а так как у вас Цитата раз десять читал,понять не смог.Поэтому менял наугад и пробовал "завести " проц это не дело, надо понимать, что делаешь.
|
|
|
|
|
Apr 18 2011, 15:03
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
И пишите вместо 0b01010111 (для примера и от балды) приблизительно так Код ;************************************************** ;*;;/Initialization ExtInterrupr;;* * ;************************************************** ldi temp,1<<INTF2 out EIFR,temp ldi temp,1<<INT2; Разрешаем прерывание INT2 out EIMSK,temp ldi temp,1<<ISC21|0<<ISC20 sts EICRA,temp;+ По спадающему фронту Так понятнее , чем каждый регистр проверять , что Вы там назначили.
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|