реклама на сайте
подробности

 
 
> ATmega 16 и прерывания, переход по прерыванию не в ту степь
mishara777
сообщение Apr 18 2011, 09:49
Сообщение #1





Группа: Новичок
Сообщений: 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] !!!
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
Сергей Борщ
сообщение Apr 18 2011, 10:06
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
mishara777
сообщение Apr 18 2011, 10:23
Сообщение #3





Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769



Прошу прощения за оформление первого топа,сказывается нечастое обращение к форумам!Спасибо ,что быстро ответили ,но вначале (на 2313) я так и поступал.И в этот раз стек переносил из угла в угол,писал и rjmp и jmp - итог один "jmp init"
Go to the top of the page
 
+Quote Post
нечитатель
сообщение Apr 18 2011, 10:29
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 18 2011, 10:37
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
ae_
сообщение Apr 18 2011, 10:41
Сообщение #6


Участник
***

Группа: Свой
Сообщений: 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


да, уже подсказали...
Go to the top of the page
 
+Quote Post
mishara777
сообщение Apr 18 2011, 11:12
Сообщение #7





Группа: Новичок
Сообщений: 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] !!!
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 18 2011, 11:21
Сообщение #8


Профессионал
*****

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



Код
Init:
cli
  ldi  temp,LOW(RAMEND)
  out  SPL,temp
  ldi  temp,HIGH(RAMEND)
  out  SPH,temp
отключить компаратор
далее по тесту


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
mishara777
сообщение Apr 18 2011, 11:32
Сообщение #9





Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769



Спасибо за терпение! Сделал все ,как написали. Но.... опять "jmp init ;RESET"
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 18 2011, 12:24
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 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
Здесь разрешаются два(!) прерывания. Обработчика одного из них - нет!
Go to the top of the page
 
+Quote Post
mishara777
сообщение Apr 18 2011, 13:43
Сообщение #11





Группа: Новичок
Сообщений: 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

раз десять читал,понять не смог.Поэтому менял наугад и пробовал "завести " проц.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 18 2011, 13:52
Сообщение #12


Гуру
******

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



Цитата(mishara777 @ Apr 18 2011, 17:43) *
Это просто часть программы, которую написал с год назад для 2313.
Если прерывания разрешить, а обработчик его не сделать, то результат работы - непредсказуем... От этого следует немедленно избавиться.


Цитата(mishara777 @ Apr 18 2011, 17:43) *
раз десять читал,понять не смог.Поэтому менял наугад и пробовал "завести " проц.
Эти биты для поддержки прерываний в BootLoader'e. В Application их менять не нужно.
Go to the top of the page
 
+Quote Post
mishara777
сообщение Apr 18 2011, 14:02
Сообщение #13





Группа: Новичок
Сообщений: 7
Регистрация: 28-09-06
Пользователь №: 20 769



Спасибо за совет. Сейчас буду исправлять
Go to the top of the page
 
+Quote Post
alag57
сообщение Apr 18 2011, 14:55
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355



Цитата
с аглицким проблема (учили французскому)

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

это не дело, надо понимать, что делаешь.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Apr 18 2011, 15:03
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 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;+ По спадающему фронту

Так понятнее , чем каждый регистр проверять , что Вы там назначили.


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 19:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01508 секунд с 7
ELECTRONIX ©2004-2016