блин если я отключаю режим совместимости с мега103 то переход к подпраграммам начинает работать зато основная прога ведёт себя не адекватно
вот какие у меня фузы:
^------это галочка
^-SUT0
^-BOOTSZ0
^-BOOTSZ1
^-JTAGEN
если поставлю ^-M103C то прога работает нормально а вот с RCALL начинаются проблемы
кварц использую на 8мГц
что не так помогите
А проблему то решить так никто и не помог...
Ну tych меня не удивил, как всегда отправляет на свой курс Да, давайте все начнем писать на асме методом - компильнул на сях, посмотрел в LST, скормил ассемблеру
ARV дядька толковый, но не учел одного момента, разговор ведь про ATmega32.
А теперь собственно о самой проблеме.
У avr'ok размер памяти программ которых более 8кб, таблица векторов строится не с командами RJMP, а с командами JMP. Соответственно, каждый вектор занимает не одного слово памяти, а два. Если глянуть повнимательнее в даташит в раздел "Interrupts", то это прекрасно видно. Так что надо ни rjmp USART_RXC, а jmp USART_RXC.
По поводу правильности оформления таблицы тоже можно поспорить. Для меня удобнее открыть даташит на кокретный контроллер, перейти в соответствующий раздел, скопировать список(пример), за ним идут пустышки-метки ведущие на команду RETI. В любой момент понадобившееся прерывание выбираем в пару легких движений. К тому же еще и безопаснее кое в чем. Пример в аттаче.
Вложения:
Комментарий к файлу: Пример оформления таблицы векторов ATtiny2313 examp.asm [1.61 KiB]
Скачиваний: 1129
большое спасибо, теперь сам буду так же делать.
кстати я из примера в даташите копировал векторы прерываний...
там один из векторов называется ADC и я только сейчас заметил, что "ADC" подсвечивается синим цветом в AVR Studio ! обьясняли что надо писать jmp вместо rjmp, а примерчик дали с rjmp
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
большое спасибо, теперь сам буду так же делать. кстати я из примера в даташите копировал векторы прерываний... там один из векторов называется ADC и я только сейчас заметил, что "ADC" подсвечивается синим цветом в AVR Studio !
Я рад, что помогло
А что касается ADC, то да, это ведь команда, асм будет ругаться если как метку попытаться заюзать. Лучше сразу написать Int_ADC.
Я так вообще все метки относящиеся к прерываниям(кроме Reset) начинаю с Int_ , чтоб сразу было видно, что это обработчик прерывания.
все ваши проблемы именно в том, что вы, начитавшись непонятно каких книжек, используете неверный подход. если бы вы использовали рекомендованный мной способ с директивами ORG - минимум половины проблем у вас не возникло, а может и вообще ни одной (с векторами). поясню, в чем суть.
от модели к модели количество используемых векторов прерываний, их размер и т.п. могут меняться, как вы справедливо заметили. поэтому если вы будете считать команды rjmp или jmp в таблице векторов, надеясь попасть на нужное место - вам не избежать проблем при портировании кода с одной модели МК на другую. выход в принципиально ином системном подходе: надо максимально абстрагироваться от конкретной аппаратной платформы и работать с символьными константами. Эти константы определяют адреса каждого вектора, описаны они в соответствующем inc-файле. главное: значения констант могут быть разные, но символьные имена остаются прежними. т.е. вектор прерывания по переполнению таймера 0 будет иметь название TMR0_OV_VECT (я привожу абстрактный пример, т.к. не помню точное название константы) для любого МК. если вы напишите в программе
Код:
.org TMR_OV_VECT rjmp Vect_Func
то компилятор разместит команду перехода на подпрограмму-обработчик прерывания Vect_Func именно по тому адресу, который соответствует вектору - для одного МК это будет ячейка, предположим, 2, для другого - 4, для третьего - 8. вы знать не будете, какая именно ячейка соответствует вектору, но программа будет работать верно! если какие-то векторы вам не нужны - просто не описывайте их - никаких nop-ов в таблице векторов не надо! если вы будете использовать "короткие" переходы rjmp - вы никогда не ошибетесь!
есть такое простое правило, которым пренебрегают программисты-любители: чем меньше конкретных чисел в вашей программе - тем лучше. т.е. вместо чисел используйте заранее описанные символьные константы (если вы задумаетесь, то все "названия" регистров не более, чем четкое следование этому подходу).
подумайте над сказанным и не ошибайтесь впредь!
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Ну tych меня не удивил, как всегда отправляет на свой курс .
Я там еще пример в VMLAB рекомендовал: C:\VMLAB\AVR_demo\UART.ASM
ARV писал(а):
значения констант могут быть разные, но символьные имена остаются прежними. т.е. вектор прерывания по переполнению таймера 0 будет иметь название TMR0_OV_VECT (я привожу абстрактный пример, т.к. не помню точное название константы) для любого МК. если вы напишите в программе
Код:
.org TMR_OV_VECT rjmp Vect_Func
то компилятор разместит команду перехода на подпрограмму-обработчик прерывания Vect_Func именно по тому адресу, который соответствует вектору
В примере C:\VMLAB\AVR_demo\UART.ASM который я рекомендовал на прошлой страницы примерно так и сделано !
tych, не надо кричать: правильный подход - даже в вашем курсе остается правильным
в примерах, предлагаемых разработчиками компиляторов или производителями МК, как правило, всегда показан наиболее правильный подход - остается только его воспринять и следовать ему!
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
все ваши проблемы именно в том, что вы, начитавшись непонятно каких книжек, используете неверный подход.
я ту книжку не читал, просто просмотрев и обнаружив море ошибок не стал дальше читать...я интуиктивно пытаюсь сам разобраться. достаточно даже списка асм команд с кратким пояснением...темболее я несовсем новичек в МК, просто впервые вижу асм.
Цитата:
я привожу абстрактный пример
спасибо, с примером все понятно. можно и так и так безразници. смысл понятен, но я даже не знаю что такое .org так что пока так для меня так грубовато как-то.
Цитата:
... подумайте над сказанным и не ошибайтесь впредь!
По поводу максимального юзания символьных имен - согласен.
А вот такого от вас ARV, я не ожидал:
ARV писал(а):
если вы будете использовать "короткие" переходы rjmp - вы никогда не ошибетесь!
Интересно вот только, а зачем же тогда каждый вектор занимает два слова в памяти, а не одно как у кристаллов с флэшиной не более 8кб ?
Наверно потому, что rjmp не вовсюда может прыгнуть... Эх, а всё так категорично было заявлено...
если вы будете использовать "короткие" переходы rjmp - вы никогда не ошибетесь!
Интересно вот только, а зачем же тогда каждый вектор занимает два слова в памяти, а не одно как у кристаллов с флэшиной не более 8кб ? Наверно потому, что rjmp не вовсюда может прыгнуть... Эх, а всё так категорично было заявлено...
уважаемый Brutaller! в моем "категоричном" заявлении нет никакой ошибки! можете - не означает должны, не так ли? если вам действительно необходимо использовать далекие переходы - даже в "больших" мегах вы можете использовать короткие: сначала прыгнуть недалеко, а уже оттуда - длинным джампом куда угодно - всего-то 2 такта лишних...
кроме того, используя только короткие джампы вы не будете иметь проблем до тех пор, пока не окажется, что их не хватает для перехода к обработчику - компилятор при этом выдаст ошбику. Вот тогда вы, исправляя ее, измените короткий джамп на длинный. при этом проблем с "непопаданием вектора в требуемый адрес" у вас все равно не будет
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
По поводу максимального юзания символьных имен - согласен.
А вот такого от вас ARV, я не ожидал:
ARV писал(а):
если вы будете использовать "короткие" переходы rjmp - вы никогда не ошибетесь!
Интересно вот только, а зачем же тогда каждый вектор занимает два слова в памяти, а не одно как у кристаллов с флэшиной не более 8кб ? Наверно потому, что rjmp не вовсюда может прыгнуть... Эх, а всё так категорично было заявлено...
Мда, с асмом работоть и работать. Какя разница что 8кб что 256кб? Если rjmp адресует - то туда и прыгнет. Если выше - то сам компилятор даст ошибку.
А мой совет - что rjmp, что jmp рано или поздно заканчиваются.
И тогда на помощь приходит CALL и RCALL.
А никто не задумывался, зачем многие, кто пишет на асме забивают векторы не используемых прерываний инструкцией RETI ?
Кстати IAR это тоже делает. Про GCC не знаю - не смотрел что он там творит.
__Alexander писал(а):
Мда, с асмом работоть и работать.
Я то вполне комфортно себя в асме чувствую и понимаю - что делаю.
Кстати, видел интересную тему на одном форуме. Там еще более хитрый прием применяется с использованием специальных заглушек, как раз для отлова таких ситуаций с непреднамеренным входом в прерывание и вытекающих из этого проблем.
Уважаемые Коты, будут идеи по поводу сложения чисел в доп. коде в 24 разрядный регистр(8x3) ???
Ситуация такая. перемножаю числа со знаками командой muls, получаю результат в доп коде в регистрах r1:r0 и после нужно прибавить результат, допустим в регистры r17:r16. Перемножение и сложение в цикле несколько раз с новыми значениями. Нужно определить переполнение r17:r16 и правильно прикрутить ещё один регистр r18. Важен максимально быстрый метод!
голова уже не варит, ничего в голову не приходит(
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения