Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Я только, что обсуждал это с BOB51. Он придерживается Вашего мнения, однако я не согласен. Поясню свою точку зрения.
ARV писал(а):ошибка, когда из-за copy-paste таблицы векторов обработчик оказывался не в той ячейке - одна из самых распространенных.
Если не смог скопировать таблицу из ДШ правильно, то и в другом случае легко допустишь ошибку с таким же успехом, тем более тут уже надо набивать ручками.
ARV писал(а):во-первых, векторы можно описывать в любом порядке - компилятор сам расставит их в нужные ячейки.
Что это дает?
ARV писал(а):во-вторых, мы имеем возможность напихать в неиспользуемые области таблицы векторов какие-то полезные данные или коды - это, раз уж мы говорим об ассемблере, позволит нам выжать максимум из имеющегося минимума.
Это какая-то крайняя необходимость и ее надо избегать.
ARV писал(а):в-третьих, в программе минимум "магических чисел", т.е. она становится более переносима,
В данном случае нет ни одного магического числа. На счет переносимости соглашусь, хотя и абсолютно не трудно поменять таблицу векторов как и инклудники.
ARV писал(а):наконец, в программе нет ничего лишнего,
Текста то явно больше будет, на одно прерывание.

По мне, читабельность как раз выше у ДШвского варианта и добавить новый вектор проще, всего-лишь надо убрать ремарку.

Хотя надо конечно попробовать, очень даже может быть, что я по консервативному не хочу менять точку зрения.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

По мне, нет нужды искать инклудники, вполне достаточно открыть DS, расставить используемые вектора директивой .ORG и дать оным осмысленные названия. Например, ATmega8515
Спойлер

Код: Выделить всё

	.CSEG
	.ORG	$0000
RESET:
	LDI	R16,LOW(RAMEND)
	OUT	SPL,R16
	LDI	R16,HIGH(RAMEND)
	OUT	SPH,R16

	CLR	ZH		; в этой программе всегда 0
	OUT	SPCR,ZH; очистить ячейку признака клавиатуры 

	RJMP    START		; On Reset
;************************************************
	.ORG	$000E ;Timer/Counter0 Compare Match
COMP_50mks:
	RETI
;************************************************
;************************************************
;************************************************
;************************************************
;************************************************
START:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

мне не хочется дискутировать по вопросу, который лично для себя я закрыл много лет назад...

я прихожу к выводу, что многие адепты ассемблера слишком ослеплены его низкоуровневыми возможностями, зачастую продолжая считать его мнемоническим обозначением машинных кодов. не смотря на то, что формально такая точка зрения имеет право на существование, кардинальный прогресс в саморазвитии программиста начинается только с момента, когда ассемблер начинают воспринимать именно как язык программирования, а не эквивалент машинных кодов. осознание этого факта заставляет ужаснуться убогости языковых возможностей "классического" AVR-ассемблера от Atmel и посмотреть в сторону GNU AS... где подобные "таблицы джампов" не то, чтобы порицаются, но крайне не приветствуются... ибо есть ПРАВИЛЬНЫЙ подход в дополнение к ДОПУСТИМОМУ.

отсюда и моё, основанное на достаточно большом опыте работы с ассемблером (и не только AVR - я так же прошел школу 51-го ассемблера, MASM и TASM для х86), твердое убеждение, что надо делать именно так, как я и посоветовал ранее, и не иначе. сиюминутные выгоды от иного подхода меркнут в сравнении с возможностью единообразно работать ВСЕГДА И СО ВСЕМ...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

Следует отметить, что, например, с точки зрения MISRA, ассемблер допустим только в виде вставок в код на C или C++. И дело даже не в том, что разработка на ассемблере дороже и поддерживать ее сложнее. Дело в том, что контролировать безопасность кода на ассемблере не реально, в отличии от C.
Если пишете для себя, то, конечно, можно плевать на все стандарты и рекомендации.
Но если от Вашей программы для микроконтроллера будет зависеть жизнь людей, как у членов MISRA, то стоит десять раз подумать, прежде чем писать ассемблерный код.

Я не в коем случае не утверждаю, что эффективно программировать на МК можно не используя ассемблер. Сам люблю на ассемблере ваять. Но если хотите стать профессионалом, то используйте ассемлер только тогда, когда это действительно необходимо. Обычно, это только незначительная часть bootloader и ассемблерные вставки в C.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб сен 17, 2016 18:56:30

Сообщение dimmer »

ARV, можно подробнее об альтернативе атмелевскому ассм?
ptr128, а с точки зрения тех кто знает только Delphi, ассемблер - происки бабы Яги.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

dimmer, я же писал выше, что сам люблю на ассемблере ваять. Когда-то с удовольствием проекты на несколько тысяч строк кода на ассемблере IBM/370 писал и внедрял (для Сбербанка РФ и для РЖД, например). Тогда это было оправдано. А сейчас, когда ESP8266 или STM32 стоят копейки, а AVR32 уже и виртуальную память поддерживает, стоит ли овчинка выделки?

Я за свою жизнь писал на нескольких десятках языков программирования и на почти десятке ассемблерах. При чем тут Баба Яга?
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

dimmer писал(а):можно подробнее об альтернативе атмелевскому ассм
т.к. в настоящее время ассемблер не является для меня основным средством программирования, о вышеупомянутой альтернативе я не могу рассказать многое... но кое-что могу.

1. avr-as входит в состав WinAVR и любого иного GNU-того компилятора Си/С++ в качестве обязательного средства
2. вызывается автоматически "компилятором" avr-gcc для файлов с расширением .S и .s
3. работает по принципу модульной компиляции, т.е. выдает на выходе объектный файл на каждый файл-исходник, а затем линкер собирает из всех объектников итоговый "загружаемый" файл (coff или elf, например)
4. поддерживает препроцессор Си в полном объеме
5. содержит средства встроенных "макросов" в стиле TASM, например, для повтора команд, "сканирования" списка параметров макроса и т.п., что позволяет создавать очень гибкие программы на ассемблере
6. особенности синтаксиса описаны в соответствующем разделе документации на WinAVR и/или AVR Toolchain, но в целом можно сказать, что синтаксис (директивы) имеет много общего с MASM и препроцессором Си

остальное - в доках...

что могу сказать... я плотно познакомился с avr-as в тот момент, когда пробовал сделать многоголосый синтезатор, как у Чена. и получилось так, что сишный обработчик прерываний тупо был слишком медленным, и альтернативы ассемблеру не было... но для ассемблера приходилось каждый раз сохранять в стеке кучу регистров, а потом восстанавливать их в нужном порядке... сами понимаете, когда на ходу изобретаешь программу, приходится задействовать то один, то другой регистр, а потом выясняется, что лучше вместо этих совсем другие... в итоге много сил уходило на отслеживание того, какие регистры в каком порядке сохранялись и потом извлекались из стека... очень хотелось автоматизировать этот процесс. и avr-as такую возможность предоставил!

я сделал (при помощи советов знатоков, конечно) макрос ENTER и макрос LEAVE. для первого надо было в параметрах перечислить через запятую любое количество любых регистров, и макрос автоматически заталкивал этот список в стек - начало обработчика прерывания. а в конце обработчика надо было поставить LEAVE уже без параметров - и этот макрос автоматически в обратном порядке восстанавливал из стека все регистры, которые передавались в параметрах первого. в итоге разработка обработчика прерывания становилась просто сказочно удобной:

Код: Выделить всё

my_vector:
   ENTER r0,r1,r17,r16
   ; тут делаем все, что надо с перечисленными регистрами
   LEAVE
   reti
если потребуется добавить/убавить/изменить регистры, которые обработчик "портит/использует", надо только скорректировать список ENTER, и все! никогда уже не будет ошибки, связанной с тем, что сначала запихали в стек r0 и r1, а потом извлекли r0 и r1 в том порядке, как и написано!

ну, есть и ряд других плюшек... однако хочу предостеречь: avr-as предназначен (и наиболее удобен) именно как средство расширения проектов Си/С++, а не как средство разработки проектов на ассемблере целиком (хотя можно и это, разумеется).
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

ARV писал(а):много сил уходило на отслеживание того, какие регистры в каком порядке сохранялись и потом извлекались из стека... очень хотелось автоматизировать этот процесс.
Я же про то речь и веду, что если все тело функции на C будет состоять из одного оператора asm, то не только регистры автоматически будут сохранены, но и для нужд функции регистры можно выделить компилятором не задумываясь о том, какие из них использовать оптимальней.

Например:

Код: Выделить всё

static inline void st7735_spi_tft_read_cs_strobe(void)
{
  uint8_t counter, status;

  asm volatile ( ";                 \n\t \
  ldi   %[status],%[TX_Disable]     \n\t \
  sts   %[UCSRnB_addr], %[status]   \n\t \
  sbi   %[cs_port],%[cs_pin]        \n\t \
  ldi   %[counter], %[delay]  ;1    \n   \
WAIT_LOOP%=:                        \n\t \
  dec   %[counter]            ;1    \n\t \
  brne  WAIT_LOOP%=           ;1/2  \n\t \
  cbi   %[cs_port],%[cs_pin]  ;2    \n\t \
  ldi   %[status],%[TX_Enable]      \n\t \
  sts   %[UCSRnB_addr], %[status]   \n   \
  "
  : [counter] "=d" (counter), [status] "=d" (status)
  : [delay] "I" (_ST7735_SPI_RAMRD_DELAY_CYCLES_/3+1),
    [UCSRnB_addr] "M" (_ST7735_SPI_UCSRnB_ADDRESS_),
    [TX_Enable] "M" ((0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(0<<RXEN0)|(1<<TXEN0)),
    [TX_Disable] "M" ((0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(0<<RXEN0)|(0<<TXEN0)),
    [cs_port] "I" (PIN_TO_PORTn_OFFSET(ST7735_CHIPSELECT_PIN)),
    [cs_pin] "I" (PIN_TO_PINn_BIT(ST7735_CHIPSELECT_PIN))
  : "cc" );
}
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ну что я могу сказать, ptr128...
синтаксис ассемблерных вставок GNU я так и не смог осилить, чтобы "от зубов отлетало"...
проще продумать ассемблерный файл с нужными функциями, чем разбираться с загадочным синтаксисом ассемблерной вставки...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

ARV, понимаю. Сам не могу на офисных машинах с АКПП ездить. Особенно по трассе, когда обгоны. Но люди же как то ездят и даже на ручку отказываются пересаживаться? )))
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

люди склонны идти по пути наименьшего сопротивления, точнее, по пути наибольшего комфорта.

стремление лететь впереди всех с возрастом проходит, и на первое место всплывает желание ехать как можно комфортнее. в итоге при выборе машины смортришь не на мощность движка и скоростные характеристики, а чтобы база подлиннее, кондей помощнее, автомат и сиденья помякше :)))

то же самое и с ассемблерными вставками: покуда они являются неизбежным злом, я с ними мирюсь. но как только можно обойтись без них - ни секунды не жду, а тут же отказываюсь от них. равно как и от модулей на ассемблере...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

Возраст - это не количество лет, а состояние души. Я полтинник уже разменял и великолепно себя чуствую на, вроде бы не комфортном, рамном пикапе L200 с ручкой )

А в моем примере надо было строб выдать длительностью в 350нс. Без ассемблера я что-то побоялся такое делать.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

С ума ты сходишь от Берлина,
Мне ж больше нравится Медынь.
Тебе, дружок, и горький хрен - малина,
А мне и бланманже полынь
© К.Прутков

но все это лютый оффтоп...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб сен 17, 2016 18:56:30

Сообщение dimmer »

ptr128, Баба Яга это шутка, но видимо неудачная. У меня нет цели убедить всех, что мой размер обуви самый лучший.
ARV, спасибо за информацию, пойду познакомлюсь поближе...
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Можно-ли посмотреть примеры макросов ENTER и LEAVE?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

trofim2 писал(а):Можно-ли посмотреть примеры макросов ENTER и LEAVE?
можно

Код: Выделить всё

.macro ENTER    arg:vararg // макрос имеет переменное число параметров
.set    selector, 0 // в этой переменной будем отмечать нужные регистры
   push   r0      // всегда сохраняем r0
   in     r0, _SFR_IO_ADDR(SREG) // извлекаем значение SREG
   push   r0      // сохраняем его в стеке
// тут надо перебрать аргументы и отметить их битами в selector
.set    i, 1
.irp    p, r1, r2, r3 ... r30, r31 // надо перечислить все регистры по порядку!!!
   .if p == \reg // если регистр совпадает с аргументом макроса
      .set    selector, selector | (1 << i) // сделаем отметку в нужном бите
   .endif
   .set    i, i+1 // и продолжим счет
.endr
// затем надо перебрать биты selector от МЛАДШЕГО к старшему и сохранить нужные регистры
.set    i, 1
.rept   31
   .ifne selector & (1<< i)
      push    i
   .endif
   .set    i, i+1
.endr
.endm

.macro LEAVE
.set    i, 31
.rept   31
   .ifne   (1<< i)
   // если бит в маске установлен - регистр извлекается из стека
   pop i
   .endif
   // перебор битов ведется в обратном порядке!!!
   .set    i, i - 1
.endr
// всегда восстанавливаем SREG и R0
   pop     r0
   out     _SFR_IO_ADDR(SREG), r0
   pop     r0
.endm
если вас интересует, как именно и почему созданы макросы, а так же желаете немного больше узнать о потенциальных возможностях макростроения GAS (GNU Assembler), могу порекомендовать мою статью, посвященную этому: А у нас в проектах GAS. А у вас?

P.S. давненько не брал я в руки шашек... при внимательном просмотре вышеописанного макроса ENTER я увидел 2 ошибки... так что макрос не сработает, по-моему. но можно исправить: не хватает еще одного irp reg, \arg для перебора передаваемых в аргументах регисторов ну и соответствующего endr тоже не хватает...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Интересненькая вещь.
ARV писал(а):P.S. давненько не брал я в руки шашек...
Вы это сразу дописали? Или я как обычно невнимательно пост прочитал? Тупил, тупил с параметром reg. Хотел вопрос дописать по нему, а Вас тут шашки. Тогда другой вопрос, а если дописать не так как Вы указали, а исправить if p == \reg на .if p == \arg ?

На сайте, что Вы указали .set selector, 0 находится вне макроса, что наверное ограничит макрос однократным применением.

Добавлено after 8 minutes 27 seconds:
А с LEAVE, вообще ничего не понял.
Selector же там должен участвовать и как pop i заменится на pop Rn.

Что-то здесь не так. Надо будет попробовать и добить макрос если что. Так то "индейка" :idea: замечательная.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

Если так хочется развитые макросы и препроцессор, то может проще тогда к Atmel Asm просто m4 прикрутить?
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Первое, что я могу сказать: ARV, Вы негодяй! :))) Вместо того, чтобы сладко спать, я до сего времени пытался запустить Ваш макрос. Запустил я его в нижеследующем тексте.
Спойлер

Код: Выделить всё

#define SREG	0x3f

.macro ENTER    arg:vararg // макрос имеет переменное число параметров
.set    selector, 0 // в этой переменной будем отмечать нужные регистры
   push   r0      // всегда сохраняем r0
   in     r0, SREG//_SFR_IO_ADDR(SREG) // извлекаем значение SREG
   push   r0      // сохраняем его в стеке
// тут надо перебрать аргументы и отметить их битами в selector

.irp    reg,\arg
.set    i, 1
.irp    p, r1, r2, r3,r4, r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31 // надо перечислить все регистры по порядку!!!
   .if (\p == \reg) // если регистр совпадает с аргументом макроса
      .set    selector ,(selector | (1 << i)) // сделаем отметку в нужном бите
   .endif
   .set    i, i+1 // и продолжим счет
.endr
.endr

// затем надо перебрать биты selector от МЛАДШЕГО к старшему и сохранить нужные регистры
.set    i, 1
.irp    p, r1, r2, r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31
   .ifne (selector & (1<< i))
      push    \p
   .endif
   .set    i, i+1
.endr



.endm
//----------------------------------------
.macro LEAVE
.set    i, 31
.irp    p, r31, r30, r29,r28,r27,r26,r25,r24,r23,r22,r21,r20,r19,r18,r17,r16,r15,r14,r13,r12,r11,r10,r9,r8,r7,r6,r5,r4,r3,r2,r1
   .ifne   selector &(1<< i)
   // если бит в маске установлен - регистр извлекается из стека
   pop \p
   .endif
   // перебор битов ведется в обратном порядке!!!
   .set    i, i - 1
.endr
// всегда восстанавливаем SREG и R0
   pop     r0
   out     SREG, r0
   pop     r0
.endm
//****************************************************************************


Следующее что я хочу сказать.
1. Если создать проект в ассемблере, то эти директивы не работают. Именно при написании программы на ассеблере, часто приходится сохранять регистры в стек. Т.е. тут бы это макрос как нужен. Ну или я не знаю как сделать, чтобы заработали. :dont_know:
2. При написании программы на Си. Вряд ли часто нужно будет писать ассемблерные вставки, чтобы так страдать с написанием такого макроса. Не стоит по-моему тут день терять, чтобы за час долететь.
3. Данный макрос коварен. :) Если Вы напишите PUSH Я1, то компилятор выдаст ошибку, а если ENTER Я1, то компилятор это проглотит и регистр не будет сохранен. Так что тут проще вляпаться, чем перечислять ПушиПопы.

------------------------

У меня к Вам есть вопрос, ARV. Наверняка Вы знаете. Ну или к тому, кто знает. Как в проекте на Си, написать обработчик прерывания на ассме? Я имею ввиду не вставить в ISR. А написать полностью самому. Функции на ассме я делал, с передачей параметров через регистры. Т.е. надо написать подобную функцию, но чтобы как-то компилятор догадался установить на нее вектор. Спасибо.

З.Ы. Не очень в удачном месте задал этот вопрос, продублирую в правильной ветке.
Последний раз редактировалось Z_h_e Вт окт 25, 2016 22:51:22, всего редактировалось 2 раза.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

Z_h_e: Компилятор никогда не догадается, что на функцию надо установить какой-то вектор. Это Вы должны явно сделать сами. Либо явно записав указатель на функцию в таблицу векторов прерываний, либо воспользовавшись готовым макросом или функцией для установки этого вектора.
А компилятору достаточно только сообщить, что данная функция будет обработчиком прерывания. Вот так:
https://gcc.gnu.org/onlinedocs/gcc/AVR- ... butes.html
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Ответить

Вернуться в «AVR»