Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как бы подправить код генерируемый AVRGCC для обработчика прерывания
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
RodionGork
Уважаемые товарищи!

В начало обработчика прерывания компилятор GCC вставляет мне примерно следующее:

380: 1f 92 push r1
382: 0f 92 push r0
384: 0f b6 in r0, 0x3f ; 63
386: 0f 92 push r0
388: 11 24 eor r1, r1

Ну в R0 как помню в мануале где-то видел, он всегда использует для SREG или что-то в этом духе, а в R1 хранит 0. Все неплохо.

Однако в данном случае, прерывание коротенькое и очень часто вызывается (ну примерно 500000 раз в секунду)... Контроллер на 8Мгц работает, кварц ему впаивать мне не хочется.

В связи с этим я б лучше обработчик хотел подправить... Дайте ссылку где почитать, как это для цомпилятора оформить... директивку и т.п. или примерчик. А то я GCC в первый раз в жизни (второй) решил для этих целей воспользоваться. и вот. ;-)

с уважением,
Родион
Rst7
Цитата
Однако в данном случае, прерывание коротенькое


Ключевое слово wink.gif

Напишите его целиком на асме.
RodionGork
м-м-м... а ключевое слово чтоб вектор прерывания на это дело установить... или вообще доку как слинковать вместе... сорри за клюпость. ;-)
_Pasha
Код
ADC_vect:
.global ADC_vect
                push r0
                pop  r0
                reti

Например
singlskv
Цитата(RodionGork @ Apr 9 2009, 14:55) *
В связи с этим я б лучше обработчик хотел подправить... Дайте ссылку где почитать, как это для цомпилятора оформить... директивку и т.п. или примерчик. А то я GCC в первый раз в жизни (второй) решил для этих целей воспользоваться. и вот. ;-)

Код
void TIMER1_COMPA_vect(void) __attribute__((signal)) __attribute__((naked));
void TIMER1_COMPA_vect()
{
}
Но с этим нужно очень аккуратно тк SREG не сохраняется и нет даже RETI в конце,
вобщем нет ничего...
SysRq
Код
ISR(TIMER1_COMPA_vect, ISR_NAKED)
{
}

красивше smile.gif
RodionGork
Всем привет и большое спасибо!

По высказанным наводкам я достаточно быстро нашел и собственно подходящие доки в каталоге с GCC... Даже вспомнил, что когда-то неделю назад туда уже заглядывал... ;-)))

В общем, все хорошо стало, сейчас занят тем что усиленно думаю над уменьшением количества циклов, требуемых на выполнение несложных действий... (изменение состояния одной из двух линий инкрементного датчика с вытекающими отсюда последствиями в виде изменения координаты на единицу... сижу и "впихиваю" в 16 тактов... ;-)))

Конечно надо гну внимательнее изучать... в смысле нюансов. Ну да с вашей всехной помощью все одолеем... Спасибо! ;-)
_Pasha
Цитата(RodionGork @ Apr 9 2009, 21:14) *
изменение состояния одной из двух линий инкрементного датчика с вытекающими отсюда последствиями в виде изменения координаты на единицу... сижу и "впихиваю" в 16 тактов...

Тут кой-чего думалось:
http://electronix.ru/forum/index.php?showt...=60502&st=0
http://electronix.ru/forum/index.php?s=&am...st&p=565167

...но для 16-ти тактов - неплохо подумать бы о том, что очень многое зависит от цоколевки. Например повесить на линии на биты 0 и 4 порта, или 1 и 5, чтобы командой swap решать обозначенные в темах проблемы. Надеюсь, я тут развел полезный оффтоп.
RodionGork
Уважаемый Паша, привет!

Да, точно такая же самая задача... Правда скорость чуть больше... ;-)))

И еще я не знал что это зовется "квадратурным энкодером" - ну, умнее стал...

Конкретные данные:
- время между фронтами по линиям A и B одного датчика до 1мкС - т.е. в идеале прерывание должно за это время отрабатываться;
- а датчиков-то два. бу-га-га надо мною ;-)))

Обработчик втиснул в 20 тактов, хотя надо еще учитывать что прерывание вызывается, как я понял, примерно через 5-10 тактов после наступления события, его спровоцировавшего.

План такой:
- поскольку это лабораторная поделка, поставлю кварц 20 МГц или даже 24МГц и посмотрю, будет ли работать - сейчас работает от внутреннего 8МГц генератора;
- ждем массового наступления XMega с частотой 32 (а спасет ли?);
- можно бы сэкономить такты зарезервировав скажем r16 или r23 чтоб не сохранять его на стеке, но не знаю, что мне на это компилятор скажет, пока зарезервировал r2,r3 для младших байтов счетчиков, r4 для sreg, r5 в качестве вспомогательного;
- еще можно экономить байтики поставив двухвходовой и-не на один из входов, чтобы преобразовать обычную последовательность 00, 01, 11, 10, 00... в 00, 01, 10, 11, 00...

Сейчас текст такой (поиграем в Hugi Compo ;-) - что еще улучшить в голову не приходит (впрочем, радикально тут ничего не изменится):

CODE
volatile short coordA1,coordB1;
volatile register byte coordA0 asm("r2");
volatile register byte coordB0 asm("r3");
volatile register byte sregSave asm("r4");
volatile register byte temp2 asm("r5");
//по замыслу coordA=(coordA1<<8)|(coordA0^0x80)
//т.е. седьмой бит младшего (нулевого) байта инвертирован
//а первый и второй байты живут отдельно в SRAM

ISR(INT0_vect,ISR_NAKED){
//ветка для прямого направления движения
asm volatile(
"cli \n\t"
"in r4,0x3F \n\t push r16 \n\t"
"in r16,0x10 \n\t mov r5,r16 \n\t lsl r5 \n\t"
"eor r16,r5 \n\t andi r16,0x08 \n\t breq int0neg \n\t"
"inc r2 \n\t brvs int0ovr \n\t"
"pop r16 \n\t out 0x3F,r4 \n\t"
"sei \n\t reti \n\t"
);//asm
//ветка для overflow младшего байта (в прямом направлении)
asm volatile(
"int0ovr: \n\t"
"lds r16,coordA1 \n\t inc r16 \n\t sts coordA1,r16 \n\t"
"brne int0sk1 \n\t"
"lds r16,coordA1+1 \n\t inc r16 \n\t sts coordA1+1,r16 \n\t"
"int0sk1: \n\t"
"pop r16 \n\t out 0x3F,r4 \n\t"
"sei \n\t reti \n\t"
);//asm
//ветка для обратного направления
asm volatile(
"int0neg: \n\t"
"dec r2 \n\t brvs int0und \n\t"
"pop r16 \n\t out 0x3F,r4 \n\t"
"sei \n\t reti \n\t"
);//asm
//ветка для underflow младшего байта (в обратном направлении)
asm volatile(
"int0und: \n\t"
"lds r16,coordA1 \n\t subi r16,1 \n\t sts coordA1,r16 \n\t"
"brcs int0sk2 \n\t"
"lds r16,coordA1+1 \n\t dec r16 \n\t sts coordA1+1,r16 \n\t"
"int0sk2: \n\t"
"pop r16 \n\t out 0x3F,r4 \n\t"
"sei \n\t reti \n\t"
);//asm
}//ISR(INT0_vect)


ну и так далее... для INT1, INT2 и еще аналоговый компаратор задействовал в качестве INT3 несуществующего...
galjoen
Цитата(RodionGork @ Apr 11 2009, 07:04) *
...
- еще можно экономить байтики поставив двухвходовой и-не на один из входов, чтобы преобразовать обычную последовательность 00, 01, 11, 10, 00... в 00, 01, 10, 11, 00...

Сейчас текст такой (поиграем в Hugi Compo ;-) - что еще улучшить в голову не приходит (впрочем, радикально тут ничего не изменится):
...

Радикально (в 8 раз) изменить можно...
Раз уж у вас дошло до добавления логических элементов - добавьте исключительное или (2 элемента на датчик). По моему так называется. На первый - завести выходы с датчика. Тогда на его выходе при изменении одного сигнала с датчика будет фронт (передний или задний). Одновременно оба сигнала ведь изменится не могут. А на второй элемент на одну ногу выход первого, а на вторую его-же с задержкой. Тогда на его выходе будут импульсы при каждом изменении входных сигналов (фронте с 1-го элемента). Тогда можно будет завести сигнал с него на тактовый вход SPI (в режиме славянина), а один из выходов датчика на его (SPI) вход данных. Тогда в SPI будут приниматься данные зависящие от датчика. 1 байт на 8 изменений положения датчика. Только потом их придётся расшифровать. Например по таблице (256 элементов).
_Pasha
Цитата(RodionGork @ Apr 11 2009, 06:04) *
Уважаемый Паша, привет!

Привет через сто лет, точнее 3 дня smile.gif
Цитата
Конкретные данные:

Не успеет. Для таких частот лучше плисину помучать.
RodionGork
Цитата(_Pasha @ Apr 14 2009, 10:37) *
Привет через сто лет, точнее 3 дня smile.gif
Не успеет. Для таких частот лучше плисину помучать.


Ну да, я когда начал бормотать про прицепление каких-нить логических элементов на вход то же самое подумал... Приделать плисину которая хотя бы 4-разрядный счетчик по каждому из двух датчиков организует... Вот жизнь тогда настанет... Правда как я путем наводящих вопросов где-то тут рядом выяснил, я в этом деле ничегошеньки не понимаю, но это еще не повод, чтоб не попробовать... ;-)))

Правда закашшык клянется и божится что у него частота меньше будет... типа скорость только 2м/с вместо 5 на которых возникают упомянутые 1мкс ширины импульсов... если так (да и кварц 24 МГц отлично завелся), конечно, несколько легче... сейчас жду результатов экспериментирования... а хорошо б конечно за чужие деньги тут и с плисами поиграть научиться... ;-)))
_Pasha
Цитата(RodionGork @ Apr 14 2009, 09:48) *
а хорошо б конечно за чужие деньги тут и с плисами поиграть научиться... ;-)))

+1 Правильные мысли, имхо. Возможный сценарий - сделать на совесть компромиссный вариант и подтолкнуть заказчика, что довести до правильных цифр перфоманса все-же надо. Когда будет успех от первого этапа - авторитет начнет зашкаливать - и давите, давите ... smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.