AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
25.08.2016, 11:39
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
|
Как оптимизировать алгоритм ?
Доброго всем времени .
Подскажите где собака порылась . что то никак не соображу.
Имеется мега8 , работает на частоте 8МГц. Код написан на кодевижн.
Обработчик прерывания от таймера 2, сам таймер считает с частотой 1000кгц при дочитывании до 0x001B (27) генерируется
прерывание т.е с частотой 37кгц.
В прерывании инкрементируются три счетчика и при достижении нужного значения поднимаются ножки порта В и запускается таймер 0, далее таймер 0 сбросит порт В .
delay1 delay2 delay3 - устанавливаются вне прерывания , одновременно с установкой faza1 faza2 faza3 ( переход через нуль трехфазной сети)
Вынести из прерывания эту часть нежелательно , важно точно отсчитать время.
flag1 - по этому флагу в основной программе инкрементируются счетчики на запуск АЦП и динамической индикации.
С индикацией и загвоздка, для экономии ног, она сделана через сдвиговый регистр.
При при малых значениях delay1 delay2 delay3 происходит замедление обновления цифр , мерцание. При значениях ›100 все нормально.
И я никак не пойму в чем причина ? прерывания от таймера идут всегда , разница только в том сколько раз произойдет инкремент переменных delay
Так вот этот инкремент замедляет основной цикл программы почти в два раза , почему так ?
Вот такой код
Код:
|
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
flag1=1;
if(delay1‹360) delay1++;
if(delay2‹360) delay2++;
if(delay3‹360) delay3++;
#asm("wdr")
if((faza1==1)&&(delay1›=360)&&(Stop==0)) // импульс от синхры A
{ faza1=0;
PORTB|=(1‹‹3)|(1‹‹2)|(1‹‹1)|(1‹‹0);
TCNT0=210;
TCCR0=0x03;
#asm("wdr")
};
if((faza2==1)&&(delay2›=360)&&(Stop==0)) //импульс от B
{ faza2=0;
PORTB|=(1‹‹5)|(1‹‹4)|(1‹‹3)|(1‹‹2);
TCNT0=210;
TCCR0=0x03;
#asm("wdr")
};
if((faza3==1)&&(delay3›=360)&&(Stop==0)) //импульс от C
{ faza3=0;
PORTB|=(1‹‹5)|(1‹‹4)|(1‹‹1)|(1‹‹0);
TCNT0=210;
TCCR0=0x03;
#asm("wdr")
};
} |
__________________
Да здравствует Разум,да сгинет Маразм!
|
|
|
|
25.08.2016, 12:15
|
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,948
Сказали Спасибо 1,327 раз(а) в 578 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
37 кГц - это 27 uS. так вроде? Или 27*8=216 тактов процессора.
Не жирно.
Я б на вашем месте внимательно посмотрел листинг - успевает ли?
Насколько компилер умен - соптимизировал ли?
Так, сравнение с 360 делается два раза...
wdr в прерывании тоже как-то не очень.
Проверку stop сделать 1 раз...
__________________
[ жизнь приятна и красива, если выпить литр пива ]
|
|
|
|
25.08.2016, 14:16
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Сообщение от nml
|
27 uS. так вроде?
|
27.5 uS ,да, совсем не жирно, а куда денешься ? - период сети 20mS или 360 эл.градусов,
один градус около 0,05557 mS. Получается 27.5 uS - разрешение в полградуса .
Переписал код
Код:
|
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
flag1=1;
if(faza1==1) // импульс от синхры A
{
if(delay1›=360)
{
faza1=0;
PORTB|=(1‹‹3)|(1‹‹2)|(1‹‹1)|(1‹‹0);
TCNT0=210;
TCCR0=0x03;
}
else {delay1++;};
} ;
if(faza2==1) //импульс от синхры B
{
if(delay2›=360)
{ faza2=0;
PORTB|=(1‹‹5)|(1‹‹4)|(1‹‹3)|(1‹‹2);
TCNT0=210;
TCCR0=0x03;
}
else{delay2++;};
};
if(faza3==1) //импульс от синхры C
{
if(delay3›=360)
{ faza3=0;
PORTB|=(1‹‹5)|(1‹‹4)|(1‹‹1)|(1‹‹0);
TCNT0=210;
TCCR0=0x03;
}
else{delay3++;};
};
} |
Проверку на stop убрал , стоп и так через внешнее прерывание заводится, высшим приоритетом.
Стало намного лучше.
Уже на глаз я не вижу сбоев цифр,и мерцание в индикации пропало.
На осциллографе вижу небольшое снижение частоты прогонов основного цикла ( каждый проход инвертирует состояние свободного пина порта-меандр выдает). Но уже не в два раза , а где то на треть , да и частота заметно стала выше.
Меня устроит этот результат. Но в дальнейшем планирую использовать еще программный ПИД регулятор, и наверное придется снижать вдвое частоту таймера, делать разрешение в 1 эл градус. А может и нет, увижу. А вообще надо было сразу прикрутить ЖК индикатор , со своим контроллером, но хотел как проще и дешевле.
nml Вам большое спасибо ! за совет , а еще за uniprof, я его юзаю, удобная программа .
__________________
Да здравствует Разум,да сгинет Маразм!
Последний раз редактировалось E_C_C; 25.08.2016 в 14:23.
|
|
|
|
25.08.2016, 14:52
|
|
Супер-модератор
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,948
Сказали Спасибо 1,327 раз(а) в 578 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Сообщение от E_C_C
|
Вам большое спасибо ! за совет
|
Да не за что. Не помню, кажись в GCC компилере... конструкции типа
Код:
|
if((faza3==1)&&(delay3›=360)&&(Stop==0)) |
компилировались как-то совсем некрасиво и неоптимально. Так что листинг все таки рекомендую поглядеть.
Цитата:
|
и мерцание в индикации пропало.
|
Э... А что, динамическая индикация в рабочем цикле? Я бы ее как раз в таймер засунул. Тогда ничего на нее влиять не будет.
__________________
[ жизнь приятна и красива, если выпить литр пива ]
|
|
|
Эти 2 пользователя(ей) сказали Спасибо nml за это сообщение:
|
|
|
25.08.2016, 15:06
|
|
Гражданин KAZUS.RU
Регистрация: 16.02.2012
Сообщений: 441
Сказал спасибо: 89
Сказали Спасибо 735 раз(а) в 149 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
у таймера есть регистры OCR, чтобы не считать задержки программно
|
|
|
|
25.08.2016, 16:04
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Цитата:
|
Э... А что, динамическая индикация в рабочем цикле? Я бы ее как раз в таймер засунул. Тогда ничего на нее влиять не будет.
|
В рабочем , но запускается от таймера , через каждые 50 вызовов прерывания таймера, происходит перелючение знакоместа.
Тут вилка получается - либо стабильно идет индикация и в промежутках я дергаю выхода, либо как можно точнее дергать выход ,а в остальное время индикация , кнопки и.т.п.
А в этом устройстве ,мне нужно, точно и вовремя включать / выключать выхода.
Выпрямитель это будет тиристорный трехфазный , с вольтметром , и обратной связью.И на крайних углах регулирования важно точно выдать управляющий импульс, чтобы не попасть за границы периода.
Листинг смотрел , вроде бы без особых выкрутасов, выложу , как до компа доберусь.
OCR регистры можно было бы использовать , но у меня три независимых задержки , а регистров два...
Хотя, задержки отсчитываются одновременно , и по идее можно обойтись одним отсчетом , а два других вычислить.Надо подумать.
__________________
Да здравствует Разум,да сгинет Маразм!
Последний раз редактировалось E_C_C; 25.08.2016 в 16:07.
|
|
|
|
25.08.2016, 16:56
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Сообщение от E_C_C
|
Имеется мега8 , работает на частоте 8МГц.
|
А почему не на 16, уж коли она может?
faza1, faza2,faza3 могут принимать значения больше единицы, или это флаги? если флаги, то if(faza1==1) попробовать заменить на if(faza1) и т.д., по идее должно быть чуть быстрее
Последний раз редактировалось AR_Favorit; 25.08.2016 в 17:04.
|
|
|
Сказали "Спасибо" AR_Favorit
|
|
|
26.08.2016, 08:26
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Сообщение от AR_Favorit
|
А почему не на 16, уж коли она может?
|
Потому что не вся линейка может , у меня "ATMEGA8L-8PU" , они не могут.
Сообщение от AR_Favorit
|
это флаги?
|
да , флаги , переменная типа bit , я пробовал , что if(faza1==1) ,что if(faza1), компилятор выдает одинаковый листинг. Просто мне как то привычнее, когда со знаками. Турбо Паскаль сказывается .
вот такой листинг получается , весь не буду приводить там три почти одинаковых части. Вроде бы без выкрутасов.
Код:
|
_timer2_comp_isr:
ST -Y,R26
ST -Y,R27
ST -Y,R30
ST -Y,R31
IN R30,SREG
ST -Y,R30
; 0000 006D flag1=1;
SET
BLD R2,3
; 0000 006E
; 0000 006F
; 0000 0070 if(faza1) // импульс от синхры A
SBRS R2,0
RJMP _0x28
; 0000 0071 {
; 0000 0072 if(delay1›=360)
LDS R26,_delay1
LDS R27,_delay1+1
RCALL SUBOPT_0x6
BRLT _0x29
; 0000 0073 {
; 0000 0074 faza1=0;
CLT
BLD R2,0
; 0000 0075 PORTB|=(1‹‹3)|(1‹‹2)|(1‹‹1)|(1‹‹0);
IN R30,0x18
ORI R30,LOW(0xF)
RCALL SUBOPT_0x7
; 0000 0076 TCNT0=210;
; 0000 0077 TCCR0=0x03;
; 0000 0078
; 0000 0079 }
; 0000 007A else {delay1++;};
RJMP _0x2A
_0x29:
LDI R26,LOW(_delay1)
LDI R27,HIGH(_delay1)
RCALL SUBOPT_0x8
_0x2A:
; 0000 007B
; 0000 007C } ;
_0x28:
; 0000 007D
; 0000 007E if(faza2) //импульс от синхры B
SBRS R2,1
RJMP _0x2B |
__________________
Да здравствует Разум,да сгинет Маразм!
|
|
|
|
26.08.2016, 09:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Да, с битовыми переменными без разницы получается. Про восьмимегагерцовые меги уж и забыл, древность такую, может, не мучаться и взять Mega8A?))
И можно еще с оптимизацией поиграть, возможно, ее лучше запретить там, где идет сравнение 16-битных чисел (или переключить на "speed", если это не сделано), чтобы вместо RCALL-ов процедуры 16-битного сравнения и инкремента стояли непосредственно за загрузкой числа в регистры... Пара тактов тут, пара тактов там...
Последний раз редактировалось AR_Favorit; 26.08.2016 в 09:59.
|
|
|
Сказали "Спасибо" AR_Favorit
|
|
|
26.08.2016, 11:01
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
|
Re: Как оптимизировать алгоритм ?
Сообщение от AR_Favorit
|
вместо RCALL-ов процедуры 16-битного сравнения и инкремента стояли непосредственно за загрузкой числа в регистры...
|
Попробовал , есть некоторая прибавка в скорости, правда размер существенно растет 3100 байт против 2600 , но это для всей программы , по идее можно же директивами компилятора только ответственные части оптимизировать по скорости , остальные по размеру... Надо попробовать , как то до сих пор не разбирался с этим.
вот такой листинг выдает-
Нажмите, чтобы открыть спойлер
Код:
|
_timer2_comp_isr:
ST -Y,R26
ST -Y,R27
ST -Y,R30
ST -Y,R31
IN R30,SREG
ST -Y,R30
; 0000 006E flag1=1;
SET
BLD R2,3
; 0000 006F
; 0000 0070
; 0000 0071 if(faza1) // импульс от синхры A
SBRS R2,0
RJMP _0x28
; 0000 0072 {
; 0000 0073 if(delay1›=360)
LDS R26,_delay1
LDS R27,_delay1+1
CPI R26,LOW(0x168)
LDI R30,HIGH(0x168)
CPC R27,R30
BRLT _0x29
; 0000 0074 {
; 0000 0075 faza1=0;
CLT
BLD R2,0
; 0000 0076 PORTB|=(1‹‹3)|(1‹‹2)|(1‹‹1)|(1‹‹0);
IN R30,0x18
ORI R30,LOW(0xF)
OUT 0x18,R30
; 0000 0077 TCNT0=210;
LDI R30,LOW(210)
OUT 0x32,R30
; 0000 0078 TCCR0=0x03;
LDI R30,LOW(3)
OUT 0x33,R30
; 0000 0079
; 0000 007A }
; 0000 007B else {delay1++;};
RJMP _0x2A
_0x29:
LDI R26,LOW(_delay1)
LDI R27,HIGH(_delay1)
LD R30,X+
LD R31,X+
ADIW R30,1
ST -X,R31
ST -X,R30
_0x2A:
; 0000 007C
; 0000 007D } ;
_0x28:
; 0000 007E |
__________________
Да здравствует Разум,да сгинет Маразм!
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
алгоритм опережения зажигания
|
artyomugr |
Микроконтроллеры, АЦП, память и т.д |
18 |
02.03.2012 11:40 |
Алгоритм частотомера
|
artyomugr |
Микроконтроллеры, АЦП, память и т.д |
26 |
11.05.2011 15:42 |
Код Грея, алгоритм ассемблер?
|
picavr |
Микроконтроллеры, АЦП, память и т.д |
8 |
27.03.2009 04:39 |
Нужен алгоритм СRC с результатом 7бит
|
AndryG |
Микроконтроллеры, АЦП, память и т.д |
4 |
05.06.2007 18:51 |
Алгоритм билдер для ПИК контроллеров.
|
Gladkih |
Микроконтроллеры, АЦП, память и т.д |
9 |
24.02.2007 18:41 |
Часовой пояс GMT +4, время: 13:06.
|
|