Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ASM + Xmega128A3
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Pavel_Bor
Добрый день. Решил написать какой-нить простенький код на асме под хмегу - и сходу попал на грабли: Программа из основного цикла все время вываливается на ресет. + вызов функции (rcall letterd) после сравнения битов.

CODE

.include "ATxmega128A3def.inc"

.equ fmin=5
.equ grflag2=GPIO_GPIOR2


.cseg
;**************************** INTERRUPT VECTORS*****************************************
.org 0
jmp reset
.org 0x0100;+++++++++++++++++++++++++++++++++++++++++++++++++++++

main:
wdr
ldi rtmp,0xD8
out CPU_ccp,rtmp
clr rtmp
sts WDT_CTRL,rtmp ; WDT OFF
cli // думал причина в прерываниях..отключил.. не в них

m1:
in r18,grflag2 // r18 все время равен 0, следовательно флаг grflag2.5 = 0
sbic grflag2,fmin // пропускаю и попадаю на nop-> rjmp

rjmp letterd
// даже при пустом m1: nop nop rjmp m1 вываливаюсь на ресет
rjmp m1;*******************************
nop
ret

letterd: // как ни странно но в эту функцию я тоже попадаю
nop // хотя из условия выше я долже ее обходить
ret

;************** RESET ******* // стандартный набор для инициализации

RESET:
cli
ldi r16,low(RAMEND)
out CPU_SPL,r16
ldi r16,high(RAMEND)
out CPU_sph,r16
clr r16
clr xh
ldi xl,0xff

res1: st x+,r16
cpi xh,high(ramend)
brmi res1
ldi rtmp,0b01000111
sts OSC_XOSCCTRL,rtmp
ldi rtmp,0b00001001
sts OSC_CTRL,rtmp
ser rtmp
sts kzad,rtmp
call gzad16

lds rtmp,OSC_STATUS
sbrs rtmp,3;XOSCRDY
rjmp res2

ldi rtmp,0xD8
out CPU_ccp,rtmp

res2:
ldi rtmp,0b011
sts clk_ctrl,rtmp ;extern. CLK

jmp main
kolobok0
Цитата(Pavel_Bor @ Oct 5 2011, 17:11) *
...основного цикла все время вываливается на ресет. + вызов функции (rcall letterd) после сравнения битов....



1) не совсем понятно где вызываемый код ( call gzad16) - вызов подпрограммы
2) не видно где вы зовёте "letterd" как подпрограмму. есть только (rjmp letterd) - без условный переход

удачи вам
(круглый)
Pavel_Bor
Цитата(kolobok0 @ Oct 5 2011, 16:45) *
1) не совсем понятно где вызываемый код ( call gzad16) - вызов подпрограммы

это пропустил сорри
gzad16:
lds rzad,kzad
gzad160:
lds r16,kzad
gzad161:
dec r16
brne gzad161
dec rzad
brne gzad160
ret ;*****************************************************************
Цитата
2) не видно где вы зовёте "letterd" как подпрограмму. есть только (rjmp letterd) - без условный переход
это есть в коде

letterd: // как ни странно но в эту функцию я тоже попадаю
nop // хотя из условия выше я долже ее обходить
ret
ILYAUL
Вам пытались объяснить, что переход по Rjmp не сохраняет адрес возврата , поэтому ret - это в никуда - и возврат на RESET
zombi
Цитата(Pavel_Bor @ Oct 5 2011, 16:11) *
Добрый день. Решил написать какой-нить простенький код на асме под хмегу - и сходу попал на грабли:

Не асилил весь код, дошел то до EXTRNclock.
Что должен делать этот код Вашей программы?
Код
    ldi    rtmp,0b00001001
    sts    OSC_CTRL,rtmp
    ser    rtmp
    sts    kzad,rtmp
    call    gzad16

    lds    rtmp,OSC_STATUS
    sbrs    rtmp,3;XOSCRDY
    rjmp    res2

    ldi    rtmp,0xD8
    out    CPU_ccp,rtmp

res2:
    ldi    rtmp,0b011
    sts    clk_ctrl,rtmp;extern. CLK
Navovvol
замените Rjmp на Rcall
Pavel_Bor
Цитата(ILYAUL @ Oct 5 2011, 17:27) *
Вам пытались объяснить, что переход по Rjmp не сохраняет адрес возврата , поэтому ret - это в никуда - и возврат на RESET


Похоже что именно это и просходит.

Цитата
Не асилил весь код, дошел то до EXTRNclock.
Что должен делать этот код Вашей программы?

Здесь происходит инициализация кварца. установка задержек.

Цитата
замените Rjmp на Rcall

я на этот rjmp(rcall) letterd сейчас попадать не должен так как gpio.gpior2=0;
Navovvol
CODE
.include "ATxmega128A3def.inc"

.equ fmin=5
.equ grflag2=GPIO_GPIOR2


.cseg
;**************************** INTERRUPT VECTORS*****************************************
.org 0
jmp reset
.org 0x0100;+++++++++++++++++++++++++++++++++++++++++++++++++++++

main:
wdr
ldi rtmp,0xD8
out CPU_ccp,rtmp
clr rtmp
sts WDT_CTRL,rtmp; WDT OFF
cli // думал причина в прерываниях..отключил.. не в них

m1:
in r18,grflag2 // r18 все время равен 0, следовательно флаг grflag2.5 = 0 //////// вот тут не понятно чего вы добивались.
sbic grflag2,fmin // пропускаю и попадаю на nop-> rjmp

RCALL letterd ////////////////////////////ОШИБКА исправлена
// даже при пустом m1: nop nop rjmp m1 вываливаюсь на ресет
rjmp m1;*******************************
nop
ret /////////////////////////////////////// ОШИБКА ???

letterd: // как ни странно но в эту функцию я тоже попадаю
nop // хотя из условия выше я долже ее обходить
ret

;************** RESET ******* // стандартный набор для инициализации

RESET:
cli
ldi r16,low(RAMEND)
out CPU_SPL,r16
ldi r16,high(RAMEND)
out CPU_sph,r16
clr r16
clr xh
ldi xl,0xff

res1: st x+,r16
cpi xh,high(ramend)
brmi res1
ldi rtmp,0b01000111
sts OSC_XOSCCTRL,rtmp
ldi rtmp,0b00001001
sts OSC_CTRL,rtmp
ser rtmp
sts kzad,rtmp
call gzad16

lds rtmp,OSC_STATUS
sbrs rtmp,3;XOSCRDY
rjmp res2

ldi rtmp,0xD8
out CPU_ccp,rtmp

res2:
ldi rtmp,0b011
sts clk_ctrl,rtmp;extern. CLK

rjmp main

И если честно, то переходы мутные, код не читабелен. Все вызываемые CALL'ом подпрограммы в отдельный файл .asm и в конце главного файла инклуд.
И структуру надо переделать: сначала RESET потом main, а в конце jmp main. никаких ret посреди кода не надо.
И проверьте сторожевой таймер:

Код
clr rtmp
sts WDT_CTRL,rtmp; WDT OFF

Из даташита:
Бит 1 - ENABLE: разрешение работы сторожевого таймера

С помощью данного бита можно активизировать работу сторожевого таймера WDT.

Попытка изменения данного бита будет эффективной только при условии одновременной записи лог. 1 в бит CEN этого же регистра. Бит ENABLE защищен механизмом защиты от изменения конфигурации (см. 3.12 "Защита от изменения конфигурации").
Pavel_Bor
Цитата(Navovvol @ Oct 6 2011, 08:52) *
Код
clr rtmp
sts WDT_CTRL,rtmp; WDT OFF

Из даташита:
Бит 1 - ENABLE: разрешение работы сторожевого таймера

С помощью данного бита можно активизировать работу сторожевого таймера WDT.

Попытка изменения данного бита будет эффективной только при условии одновременной записи лог. 1 в бит CEN этого же регистра. Бит ENABLE защищен механизмом защиты от изменения конфигурации (см. 3.12 "Защита от изменения конфигурации").


Строки ниже дают доступ на несколько секунд к изменению конфигурации.
ldi rtmp,0xD8
out CPU_ccp,rtmp

К тому же собака мне не нужна(должна быть выкл.), и в даташите написано, что она выдаст ресет только один раз или этот ресет надо дать вручную.


Меня интересует как отладчик подхватывает строку
rcall letterd, при gpior=0.
Navovvol
Цитата(Pavel_Bor @ Oct 6 2011, 14:01) *
Строки ниже дают доступ на несколько секунд к изменению конфигурации.
ldi rtmp,0xD8
out CPU_ccp,rtmp

К тому же собака мне не нужна(должна быть выкл.), и в даташите написано, что она выдаст ресет только один раз или этот ресет надо дать вручную.


Меня интересует как отладчик подхватывает строку
rcall letterd, при gpior=0.

значит grflag2 не равен 0 .
Командой IN записывается значение grflag2 в R18 // при этом grflag2 не очищается
zombi
Цитата(Pavel_Bor @ Oct 6 2011, 13:01) *
Меня интересует как отладчик подхватывает строку
rcall letterd, при gpior=0.

Строки rcall letterd в Вашем тексте нетууууу!

Цитата(Pavel_Bor @ Oct 6 2011, 13:01) *
Меня интересует как отладчик подхватывает строку

Так мы отладчик обсуждаем или чип???


Цитата(Pavel_Bor @ Oct 6 2011, 08:37) *
Здесь происходит инициализация кварца. установка задержек.

Оченно похоже на тестирование отладчика.
Какой кстати отладчик?

Чему равен RAMEND? и зачем c 0х00ff до RAMEND записывать нули?
kolobok0
Цитата(Navovvol @ Oct 6 2011, 14:38) *
значит grflag2 не равен 0 ..


да какие нафик флаги то, господа?
В маин как Вы попадаете? так же через джамп? и если всё пучком (флаг там или не флаг - рояли не играет) что вызываете то? ретурн!!! офигительная логика... возврат куда????

уже два или три раза ткнули носом что делать...

или по другому.
ВЫКИНЬТЕ ВСЁ нафик, кроме коллов, ретурнов, джампов. в том числе и команды образующие повторы выполнения. Только путь выполнения МК. и всё станет понятно...


(круглый)
ЗЫ
ваш код так же бажный...помимо вызова то, что вы подправили - надо вызвать main как подпрограмму либо убрать ретурн после метки main
ЗЫ ЗЫ
ТС рекомендую поставить студию AVR и под отладчиком ОДИН РАЗ понять что он видит. Делоф то на 10 минут...всё по умолчанию же, без бубноффф.
Navovvol
Цитата(kolobok0 @ Oct 6 2011, 16:41) *
да какие нафик флаги то, господа?
В маин как Вы попадаете? так же через джамп? и если всё пучком (флаг там или не флаг - рояли не играет) что вызываете то? ретурн!!! офигительная логика... возврат куда????

в маин попадаем через джамп, в маине / в m1 зацикливание rjmp m1 /// nop и ret после него (rjmp m1)- похоже на мусор, который остался при редактировании кода, похоже, что код выложен не полностью.
И я с вами согласен, надо всё переделать. (вызовы и переходы)
ЗЫ вообще это не мой код, я просто указал на ошибки в коде
Pavel_Bor
Цитата
значит grflag2 не равен 0 .
Командой IN записывается значение grflag2 в R18 // при этом grflag2 не очищается
Думаете? почему же тогда после
in r18, grflag2
r18 = 0 ???

Цитата
Строки rcall letterd в Вашем тексте нетууууу!

уже есть после замечаний
Код
m1:
in r18,grflag2 // r18 все время равен 0, следовательно флаг grflag2.5 = 0 /////////////////// вот тут не понятно чего вы добивались.
sbic grflag2,fmin // пропускаю и попадаю на nop-> rjmp

RCALL letterd /////////////////////////////////////////////////////////////////ОШИБКА исправлена
// даже при пустом m1: nop nop rjmp m1 вываливаюсь на ресет
rjmp m1;*******************************
nop
ret  ////////////////// ОШИБКА ??? Теоретически да. Но программа никогда не должна сюда попасть. Так что эти строки не важны


Цитата
Оченно похоже на тестирование отладчика.
Какой кстати отладчик?

Чему равен RAMEND? и зачем c 0х00ff до RAMEND записывать нули?

1. jtagiceII.
2. очистка памяти


Цитата
В маин как Вы попадаете? так же через джамп? и если всё пучком (флаг там или не флаг - рояли не играет) что вызываете то? ретурн!!! офигительная логика... возврат куда????


Еще раз говорю что этот ретурн не должен никогда происходить. он после мэйна никому не мешает, а без него программа вываливается на след строки.
Pavel_Bor
Цитата
значит grflag2 не равен 0 .
Командой IN записывается значение grflag2 в R18 // при этом grflag2 не очищается
Думаете? почему же тогда после
in r18, grflag2
r18 = 0 ???

Цитата
Строки rcall letterd в Вашем тексте нетууууу!

уже есть после замечаний
Код
m1:
in r18,grflag2 // r18 все время равен 0, следовательно флаг grflag2.5 = 0 /////////////////// вот тут не понятно чего вы добивались.
sbic grflag2,fmin // пропускаю и попадаю на nop-> rjmp

RCALL letterd //////////////////////////////////////////////////////////////////////ОШИБКА исправлена
// даже при пустом m1: nop nop rjmp m1 вываливаюсь на ресет
rjmp m1;*******************************
nop
ret  ///////////////////// ОШИБКА ??? Теоретически да. Но программа никогда не должна сюда попасть. Так что эти строки не важны


Цитата
Оченно похоже на тестирование отладчика.
Какой кстати отладчик?

Чему равен RAMEND? и зачем c 0х00ff до RAMEND записывать нули?

1. jtagiceII.
2. очистка памяти


Цитата
В маин как Вы попадаете? так же через джамп? и если всё пучком (флаг там или не флаг - рояли не играет) что вызываете то? ретурн!!! офигительная логика... возврат куда????


Еще раз говорю что этот ретурн не должен никогда происходить. он после мэйна никому не мешает, а без него программа вываливается из основного цикла main.
zombi
Цитата(Pavel_Bor @ Oct 6 2011, 16:30) *
2. очистка памяти

Только памяти? или ещё и периферии и почему именно с 0x00FF а не с 0?


Цитата(Pavel_Bor @ Oct 6 2011, 16:30) *
Еще раз говорю что этот ретурн не должен никогда происходить. он после мэйна никому не мешает

100% если R18 всегда =0 должен быть вечный цикл

m1:
.
.
.
rjmp m1

Цитата(Pavel_Bor @ Oct 6 2011, 16:30) *
а без него программа вываливается из основного цикла main.

Вот это вообще не понятно laughing.gif
что значит без RET вываливается?

Цитата(Pavel_Bor @ Oct 6 2011, 13:01) *
Строки ниже дают доступ на несколько секунд к изменению конфигурации.
ldi rtmp,0xD8
out CPU_ccp,rtmp

Т.е. несколько секунд полного беспредела biggrin.gif
Вы случаем нечё не путаете? wacko.gif
Где про это можно в DS прочитать??? rolleyes.gif
pavel-pervomaysk
CODE

.cseg
.org 0

jmp RESET ; Reset Handler

// тут пишем вектора всех прерываний

// здесь я обычно размещаю данные, которые нужны, чтоб не париться с указателем адреса внизу
// и во время отладки проц пишется быстрее.

RESET:
// STACK
ldi tmp,low(ramend) //
out SPL,tmp //
ldi tmp,high(ramend) //
out SPH,tmp //
cli

// инициализация периферии, настройка портов

Чистка DSEG у меня так :

// Initialization

ldi xl,low (1024) // загружаем размер DSEG
ldi xh,high(1024) //
ldi yl,low (0x60) // начальный адрес DSEG
ldi yh,high(0x60) //
ldi data,0x00 // загружаем нужную константу
clear_c: //
st Y+,data //
sbiw xl,1 //
brne clear_c //

main:
// здесь делаем все что хотим, или работаем по прерываниям

rjmp main






Navovvol
Цитата(Pavel_Bor @ Oct 6 2011, 17:30) *
Думаете? почему же тогда после
in r18, grflag2
r18 = 0 ???

При чем тут вообще R18, если в условии проверяется bit 5 регистра GPIOR2?
вы проверяете R18 на ноль ? нет. И что вам мешает переделать:
Код
m1:
in r18,grflag2 // r18 все время равен 0, следовательно флаг grflag2.5 = 0 /////////////////// вот тут не понятно чего вы добивались.
SBRC R18,fmin // пропускаю и попадаю на nop-> rjmp

И еще раз про сторожевой таймер:
3.12.1. Последовательность записи защищенных регистров ввода-вывода
Кодом программы выполняется запись сигнатуры в регистр CCP, что разрешает изменение защищенных регистров ввода-вывода.
В течение 4 последующих циклов инструкций кодом программы необходимо записать требуемые данные в защищенный регистр. У большинства защищенных регистров предусмотрен свой бит разрешения записи/разрешения изменения. В данный бит необходимо записать единицу вместе с записью данных. Возможность защищенного изменения блокируется сразу после выполнения ЦПУ операции записи в регистр ввода-вывода или памяти данных, а также, после выполнения инструкции SPM, LPM или SLEEP.

И программа никогда не попадет на строки:
Код
........
rjmp m1
nop   //****** вот сюда
ret    /////////// и сюда никогда и ни при каких условиях не попадет. Удалите их.
........

Скорее всего программа, которую вы сюда выложили сильно отличается от той, которую вы сейчас "мучаете".
Pavel_Bor
Цитата(Navovvol @ Oct 7 2011, 09:47) *
При чем тут вообще R18, если в условии проверяется bit 5 регистра GPIOR2?
вы проверяете R18 на ноль ? нет. И что вам мешает переделать:

я думал что значение регистра GPIOR2 каким то чудом меняется и для этого решил сохранить его в r18.

Код
........
rjmp m1
nop   //****** Эти строки как мусор, я же уже согласился с этим.
ret    ///////////
........


[quote] Только памяти? или ещё и периферии и почему именно с 0x00FF а не с 0? [/qoute]
Хорошо подметили. Я здесь только RAM хотел почистить и чистил много лишнего.
правильный адреса:
Стартовый(RAMSTART) 0x2000 конечной(RAMEND) 0x3fff

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