ANALOG, оформление прерываний у Mika сделано нормально и даже лучше чем у вас. И вот почему. Та причина, что вы указали должна привести к ошибке при компиляции. Так как директива .org второго вектора прерывания "воткнётся" в середину предыдущей команды.
Соответственно, "не рабочесть" кода может быть вызвана именно подобными обстоятельствами.
Уже обсуждалось http://radiokot.ru/forum/viewtopic.php?f=57&t=72364
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Привет! Метка reset находится ниже в коде программы. Я тут сделал для себя такое откртие, как симуляция программы в студии (Раньше думал, что так можно делать только при условии подключенного контроллера по JTAG ) Поэтому эксперименты начинаются Кстати, щас переделаю все jmp на rjmp, посмотрим как получится...
Пошаговое прощёлкивание показало, что программа всё время висит на строчке jmp reset. А если заменить jmp на rjmp то после первого щелчка по кнопке следующего действия, в окне флеш памяти появляется надпись Unavailable when debuggee is running....
UPD: Я не ту кнопку жал, rjmp сработал...
Последний раз редактировалось Мikа Ср апр 16, 2014 10:41:08, всего редактировалось 2 раза.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Kavka писал(а):ANALOG, оформление прерываний у Mika сделано нормально и даже лучше чем у вас.
очень верно сказано!
при этом вполне можно вообще не писать строки для тех векторов, которые в программе не используются: в комплекте с директивами ORG все будет скомпилировано максимально компактно и безошибочно.
а вот в методе ANALOG-а убирать из середины таблицы "лишние" вектора недопустимо вообще, а с учетом того, что "размер" команд reti, rjmp и jmp разный, и для разных МК надо использовать разные джампы, этот метод будет источником больших проблем.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Я бы на вашем месте не увлекался сильно симуляторами. Они частенько эмулируют совсем не то, что должно быть. Но в простеньких программках помогают найти ошибки.
У меня сейчас цель осознать, именно осознать азы. Чтобы нормально понимать, что происходит. Вчера я обчитался DI HALTa, вот сегодня смотрю, что куда.
Коты, можете подсказать, что именно искать в даташите на тему "разного размера команд" в разных МК?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Не надо ничего искать. команды rjmp и reti по 2 байта, а команда jmp - 4 байта.
rjmp прыгает на адрес PC+1+k, где k=-2048...+2048. jmp прыгает дальше и непосредственно в адрес, указанный в команде. Есть еще ijmp и ejmp для особо дальних прыжков.
А "размер" векторов контроллера напрямую зависит от размера его ОЗУ. Если ОЗУ <= 2кБайт - то вектора по 2 байт (команды прыжка на вектор rjmp). А если ОЗУ больше - то rjmp уже может не допрыгнуть, поэтому нужно использовать jmp, а под него нужно резервировать 4 байта (jmp по размеру равен 2 командам rjmp или reti). Вот здесь уже лучше использовать директивы .org при описании таблицы векторов.
Последний раз редактировалось ИС-пытатель Ср апр 16, 2014 11:01:12, всего редактировалось 1 раз.
т.е. Флеша, прошу прощения. ) Обшибся. ) Как всегда в голове каша. Тогда лучше команды измерять не в байтах, а в словах (по 2 байта). rjmp - 1 слово, а jmp - 2 слова
ARV писал(а):при этом вполне можно вообще не писать строки для тех векторов, которые в программе не используются: в комплекте с директивами ORG все будет скомпилировано максимально компактно и безошибочно.
При этом если накосячить в программе (включено не то прерывание, или задействован неправильный вектор обработчика) будут 2 разных глюка. Если писать во всех векторах заглушки с RETI или RJMP на адрес с RETI, то будете чесать репу, почему нужное прерывание не срабатывает, а если пропускать векторы, то будете удивляться почему контроллер сбрасывается (пустой адрес = 0xFF -> неправильный опкод -> сброс). Но правда это все симулятором/отладчиком ловится сразу.
Мikа писал(а):что именно искать в даташите на тему "разного размера команд" в разных МК?
Просто RETI и RJMP размером с 2 байта, а JMP 4 байта. т.к. адресует 4 ляма адресов (RJMP только 4к). Поэтому в контроллерах с более чем 8кб флеша векторы прерывания 4 байтные, т.е. в них помещается либо один JMP, либо пара 2 байтных команд. И при переносе кода между контроллерами у которых 8кб и более 8кб, таблицу векторов, где подряд идут команды перехода придется всю переписывать. А если использовать директиву ORG и имена векторов из def-файла, то все становится просто, понятно и легко редактируемо. Вот как-то так...
Впрочем, об этом уже сказали
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Ага. )) Флеш же словами адресуется. Тогда 4 кБайт. )) Потому что таблица векторов в начале (конечно, не всегда ), а не в середине. Блин, менеджера хитрецы.. Размер флеши в байтах указывают, а то, что команды мин по 2 байта идут и то, что запхнуть их туда можно в два раза меньше, чем количество байт, не пишут.. )))
Последний раз редактировалось ИС-пытатель Ср апр 16, 2014 11:19:50, всего редактировалось 1 раз.
ИС-пытатель писал(а):Потому что таблица векторов в начале, а не в середине.
Ну так одна фигня, если переход с отрицательным адресом, то он с конца флеша в 8к будет считаться. т.е. все что с положительным адресом перескакивает в нижнюю половину флеша, все что с отрицательным - в верхнюю. Ну да, можно запутаться по началу, но на то он и ассемблер
ИС-пытатель писал(а):Блин, менеджера хитрецы.. Размер флеши в байтах указывают, а то, что команды мин по 2 байта идут и в нее не запхнешь команд больше, чем половина ее памяти не пишут... )))
А это уже вопрос к разработчикам системы команд
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Engineer_Keen писал(а):Ну так одна фигня, если переход с отрицательным адресом, то он с конца флеша в 8к будет считаться. т.е. все что с положительным адресом перескакивает в нижнюю половину флеша, все что с отрицательным - в верхнюю.
Думаете, прокатит? Мне кажется, компилятор будет пытаться допрыгнуть дотудова правильно, т.е. прибавляя больше чем 2к слов. Хотя извратиться, возможно, удастся.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Ну так одна фигня, если переход с отрицательным адресом, то он с конца флеша в 8к будет считаться. т.е. все что с положительным адресом перескакивает в нижнюю половину флеша, все что с отрицательным - в верхнюю. Ну да, можно запутаться по началу, но на то он и ассемблер
Да что Вы говорите? ))) А старшие биты в PC кто будет формировать? ))) У Вас команда-то с отрицательным значением сформирует только младшие 12 бит, а старшие в PC останутся нулями.
P.S. Если там только не используется что-то типа расширения знака... (Коты, кто хочет проверить? ) )))))))))))))))
Последний раз редактировалось ИС-пытатель Ср апр 16, 2014 11:45:18, всего редактировалось 1 раз.
Для тех кто путается: 0x0FFF - это последние 2 байта 8 килобайтного флеша (последнее слово из 4096 слов).
Конечно я не собирался аргументом RJMP-у задавать отрицательный адрес, это задача компилятора, если я правильно понял ваше непонимание
Последний раз редактировалось Engineer_Keen Ср апр 16, 2014 11:44:44, всего редактировалось 1 раз.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
.cseg
rjmp 0x800 ; k=-2048 (12 бит) почему-то команда напрямую не воспринимает отрицательные числа
main: rjmp main
.org 262144/2-2048 ; размер флеши в байтах переведенный в слова и за вычетом k
ldi r16, 0xFF
ldi r17, 0x00
out DDRA, r16 ; порт на выход
out PORTA, r17 ; зажечь светодиоды (обратная полярность)
main2: rjmp main2
Вот, на 2560 на железе проверял. Все робит. Значит, с расширением знака идет.
;Прерывания для кнопок
ldi Temp, 0b00000011 ; Разрешение прерывания на INT1 и INT0
STS EIMSK, Temp
ldi Temp, 0b00001010 ; Прерывание по спадающему фронту INT1 и INT0
STS EICRA, Temp
Второй по аналогии.
Начинаю смотреть пошагово. И в момент, когда в EIMSK записывается 0b00000011, в регистре EIFR, который содержит в себе флаги этих прерываний,
Внезапно появляется (его адрес .equ EIFR = 0x1c)
Но, простите, откуда? На ноги прерываний приходит VCC, через резисторы, конечно, кнопочки не нажаты.
Но не смотря на то, что флаги подняты, в обработчик программа не уходит. Если смотреть на реальном контроллере, то он просто не реагирует на нажатия кнопок. SEI я не забыл. И программа на СИ, на этой же платке, работает нормально с прерываниями. Опять я что-то не знаю про AMtega48...?
UPD:
ldi Temp, 0b00000000
STS EIFR, Temp
не сбрасывают в 0 значения в 0x1c. Что-то я с чем-то путаю, походу.
Последний раз редактировалось Мikа Ср апр 16, 2014 12:38:13, всего редактировалось 1 раз.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.