Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сбрасываются Регистры После Обработки Прерываний.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
anton2488
Изучаю авр и столкнулся с непреодолимой для меня проблемой.
Простая программа АЦП>програмный делитель>шим. Регистр, в котором постоянно хранится число сдвигов для деления всё время сбрасывается в 0, при этом при этом установленный бит в порте не сбрасывается(сделал для проверки). Не важно, записан ли регистр в РЕСЕТ или в прерывании через кнопку, всё равно происходит сброс. Как такое может быть?

Это происходит при моделировании в Протеусе, в симуляторе сброса нет, правда я не знаю как там вызывать прерывания, просто переставляю курсор. Сторожевой таймер вроде отключён и програмно и в протеусе.
Что я делаю не так? Помогите новичку.
CODE
.def temp1=r16
.def temp2=r17
.def div1=r18
.def div2=r19


.cseg
.org 0x0000
rjmp RESET
reti//1
rjmp vol//2
reti//3
reti//4
reti//5
reti//6
reti//7
rjmp adcpwm
reti//9
reti//10
reti//11
reti//12
reti//13
reti//14
reti//15

RESET:

ldi r16, (0<<WDRF)// остановка ст. таймера.
out MCUSR, r16
; Write logical one to WDCE and WDE
; Keep old prescaler setting to prevent unintentional Watchdog Reset
in r16, WDTCR
ori r16, (1<<WDCE)|(1<<WDE)
out WDTCR, r16
; Turn off WDT
ldi r16, (0<<WDE)
out WDTCR, r16

ldi temp1,0b00000011
out ddrb,temp1

ldi temp1,0b00011000
out portb,temp1

ldi temp1,0b11000011
out tccr0a,temp1

ldi temp1,0b00000001
out tccr0b,temp1

ldi temp1,0b00100001//УСТАНОВЛЕН СДВИГ ВЛЕВО
out admux,temp1

ldi temp1,0b11101111
out adcsra,temp1

ldi temp1,0b00000000
out adcsrb,temp1

ldi temp1,0b00000000
out mcucr,temp1

ldi temp1,0b00100000
out gimsk,temp1

ldi temp1,0b00011000
out pcmsk,temp1

ldi div1,3// запись коэф деления в постоянный регистр

sei

start:
rjmp start

adcpwm:// прерывание АЦП---------------------------------------------
in temp1,adcl
in temp2,adch

mov div2,div1 // запись коэф. деления из постоянного рег во временный

tst div2//деление
breq zap
l1:
lsr temp2
ror temp1
dec div1
brne l1

zap://запись в шим
out ocr0a,temp2
out ocr0b,temp2
reti

VOL://прерывание кнопки----------------------------------------------------
ldi div1,3// запись коэф деления в постоянный регистр

sbi portb,1//индикатор прерывания


reti


UPD
Прошу прощения, нашлась ошибка, производился декремент постоянного регистра.
Artem_Petrik
У вас нет инициализации стека.
добавте
Код
        LDI    R16, low(RAMEND)
        OUT    SPL, R16
        LDI    R16, high(RAMEND)
        OUT    SPH, R16

в начале программы.
alexeyv
to Artem_Petrik
Я полностью с Вами согласен - необходимо в обязательном порядке проводить инициализацию указателя стека.
Но чисто для информации.
Согласно даташиту начальное значение SP , например, для:
ATmega164P = 0x04FF,
ATmega324P = 0x08FF,
ATmega644P = 0x10FF,
т.е. при сбросе SP УЖЕ лежит на верхней границе SRAM
pavel-pervomaysk
to alexeyv
а попробуйте сделать вызов любой подпрограммы, без инициализации стека.
или неправильно выйти из подпрограммы.
В доке четко описано, можно просто скопировать.

Даже в промышленных МК при дизассемблировании четко видно, что инициализируют там все, даже то, что по даташиту неоспоримо устанавливается после сброса. laughing.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.