реклама на сайте
подробности

 
 
> Как бы подправить код генерируемый AVRGCC для обработчика прерывания
RodionGork
сообщение Apr 9 2009, 10:55
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 239
Регистрация: 30-10-07
Из: Санкт-Петербург
Пользователь №: 31 866



Уважаемые товарищи!

В начало обработчика прерывания компилятор 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 в первый раз в жизни (второй) решил для этих целей воспользоваться. и вот. ;-)

с уважением,
Родион
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
RodionGork
сообщение Apr 11 2009, 03:04
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 239
Регистрация: 30-10-07
Из: Санкт-Петербург
Пользователь №: 31 866



Уважаемый Паша, привет!

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

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

Конкретные данные:
- время между фронтами по линиям 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 несуществующего...

Сообщение отредактировал rezident - Apr 13 2009, 16:50
Причина редактирования: Оформление цитаты исходника.
Go to the top of the page
 
+Quote Post
galjoen
сообщение Apr 13 2009, 20:29
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(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 элементов).
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016