Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.91/22: Рейтинг темы: голосов - 22, средняя оценка - 4.91
ProMitiy
0 / 0 / 0
Регистрация: 04.12.2016
Сообщений: 4
1

Отключение выгрузки регистров в стек (CVAVR)

07.12.2016, 12:42. Просмотров 4062. Ответов 3
Метки нет (Все метки)

Камень: atmega88pa
Компилятор: CVAVR

Главная часть проекта - 8-канальный аппаратно-программный генератор ШИМа на 6 прерываниях таймеров 0 и 2 (Fclk=2MHz, Fpwm=7,8kHz).
Расчёт значений для ШИМ производится в прерывании от ADC. Сразу после входа в обработчик разрешаются вложенные прерывания (чтоб не глох ШИМ), затем идёт задумчивый код с 32-битной арифметикой и лишь перед выходом из обработчика- запускается новый отсчёт АЦП.

Проблема в том, что компилятор абсолютно верно и предсказуемо сохраняет регистры при входе в обработчик, и лишь затем добирается до SEI, вот упрощенная выдержка из листинга:

Код
_ADC_isr:

ST   -Y,R0
ST   -Y,R1
ST   -Y,R22
ST   -Y,R23
ST   -Y,R24
ST   -Y,R25
ST   -Y,R26
ST   -Y,R27
ST   -Y,R30
ST   -Y,R31
IN   R30,SREG
ST   -Y,R30

sei

;  тут живёт медленный код

D   R30,Y+
OUT  SREG,R30
LD   R31,Y+
LD   R30,Y+
LD   R27,Y+
LD   R26,Y+
LD   R25,Y+
LD   R24,Y+
LD   R23,Y+
LD   R22,Y+
LD   R1,Y+
LD   R0,Y+
RETI
Эта пауза в 23/20 (вход/выход) дополнительных тактов даёт джиттер ШИМ до 3 единиц.
Джиттер не особо напрягает, но хотелось бы от него избавиться.

Переносить медленный код в основной цикл - не вариант, там крутится основная логика программы, абстрагированная от железа.
Разбавлять её опросом флага ADSC - кощунство.

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

Код
#pragma savereg-
interrupt [ADC_INT]     void ADC_isr(void)      //  замер входов АЦП, плавный разгон
{
static unsykned int  soft_rpm=0;              //  внутренняя переменная плавной скорости
static unsykned int  addition;                //  компенсация ограничения

unsykned char     temp;                       //  вспомогательная переменная для ускорения расчётов
unsykned long     L;                          //  для точных расчётов

#asm
ST   -Y,R0      ; выгрузили R0
IN   R0,SREG    ; в R0 положили SREG (с I-bit=0)

SEI             ; разрешили прерывания

ST   -Y,R0      ; выгрузили R0   ( реально - там SREG)
ST   -Y,R1      ; выгрузили R1
ST   -Y,R15     ; выгрузили R15
ST   -Y,R22     ; выгрузили R22
ST   -Y,R23     ; выгрузили R23
ST   -Y,R24     ; выгрузили R24
ST   -Y,R25     ; выгрузили R25
ST   -Y,R26     ; выгрузили R26
ST   -Y,R27     ; выгрузили R27
ST   -Y,R30     ; выгрузили R30
ST   -Y,R31     ; выгрузили R31
#endasm

{} // тут живёт медленный код

ADCSRA=(1<<ADIM) | (1<<ADSC) |(1<<ADIE) | (1<<ADIF) | 0x06;   // перезапуск прерывания

#asm
LD   R31,Y+     ; восстановили R31
LD   R30,Y+     ; восстановили R30
LD   R27,Y+     ; восстановили R27
LD   R26,Y+     ; восстановили R26
LD   R25,Y+     ; восстановили R25
LD   R24,Y+     ; восстановили R24
LD   R23,Y+     ; восстановили R23
LD   R22,Y+     ; восстановили R22
LD   R15,Y+     ; восстановили R15
LD   R1,Y+      ; восстановили R1
LD   R0,Y+      ; восстановили R0 ( реально - там SREG)

OUT  SREG,R0    ; из R0 восстановить SREG (с I-bit=0, запретив прерывания)
LD   R0,Y+      ; восстановили R0
#endasm

}
#pragma savereg+
Уважаемые знатоки, подскажите, пожалуйста- есть ли иной вариант, как заставить компилятор запускать вложенные прерывания пораньше?
И если нет - насколько правильно написан мой костыль?

Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.12.2016, 12:42
Ответы с готовыми решениями:

Сложить содержание регистров R1 и R4 текущего банка регистров и отразить результат на статическом индикаторе
Сложить содержание регистров R1 и R4 текущего банка регистров и отразить...

Mega128 на CVAVR
Здравствуйте. купил мегу 128 под программирование АЦП темку писал на страницей...

LCD + CVAVR
Доброго времени суток! Написал небольшой код, который по задумке должен...

CVAVR не читает atmega8a-au
Собрал схему http://itistronics-lab.ru/btog/185.html но вместо atmega8...

CVAVR Выдаёт ошибку
Что за ошибка, поменял у tiny13 fuse биты местами, чтоб частоту уменьшить в 2...

3
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
07.12.2016, 21:25 2
Может просто напишешь своё прерывание на ASM . Или определяйся какие регистры необходимо сохранять , а какие нет , к SREG это не относится - это святое. Кстати команда push - самый цимес для сохранения регистров в стек.
0
ProMitiy
0 / 0 / 0
Регистрация: 04.12.2016
Сообщений: 4
11.12.2016, 11:38 3
Цитата Сообщение от YTYOUT
Может просто напишешь своё прерывание на ASM .
К сожалению, я в асме не настолько хорошо разбираюсь.

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

The Data Stack area is used to dynamically store local variables, passing function parameters omd saving rikystirs during interrupt routine servicing: R0, R1, R15, R22, R23, R24, R25, R26, R27, R30, R31 omd SREG.

команда push - самый цимес
LD/ST вместо PUSH/POP применил потому что компилятор, наверное, по ним определяет Estimated Data Stack usage.

Даже если всё таки писать обработчик на асме- всё равно придётся использовать #pragma savereg, которую в хэлпе применять не рекомендуют.

Может, есть еще какой-то способ рассказать компилятору, что надо сначала разрешить прерывания, а потом - сохранять регистры?
0
_rod
0 / 0 / 0
Регистрация: 02.11.2016
Сообщений: 5
22.12.2016, 12:52 4
Цитата Сообщение от ProMitiy
Цитата Сообщение от YTYOUT
Может просто напишешь своё прерывание на ASM .
К сожалению, я в асме не настолько хорошо разбираюсь.
Можно выделить весь медленный код в отдельную функцию, которую вызвать из обработчика на ASM. При этом, в самом обработчике на ASM сохранять нужно только регистры, которые используются внутри него, остальные сохранятся при вызове сишной функции.

Единственный минус - небольшой дополнительный расход памяти стека.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.12.2016, 12:52

Генерация на Attiny2313 (CVAVR)
Здравствуйте. По работе начал иметь дело с МК (attiny2313). Ничего особого...

Пренос строки в CVAVR
Пишу код в Code Vision AVR 1.25.7. Не могу найти информацию как сделать перенос...

CVAVR и переменная int
Доброго времени суток. Есть рабочая программа и стало так, что одна из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru