Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы
Непрочитано 25.08.2016, 11:39  
E_C_C
Почётный гражданин KAZUS.RU
 
Аватар для E_C_C
 
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
E_C_C на пути к лучшему
По умолчанию Как оптимизировать алгоритм ?

Доброго всем времени .
Подскажите где собака порылась . что то никак не соображу.

Имеется мега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")
                                               };   

         


}
Реклама:
__________________
Да здравствует Разум,да сгинет Маразм!
E_C_C вне форума  
Непрочитано 25.08.2016, 12:15  
nml
Супер-модератор
 
Аватар для nml
 
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,948
Сказали Спасибо 1,327 раз(а) в 578 сообщении(ях)
nml на пути к лучшему
По умолчанию Re: Как оптимизировать алгоритм ?

37 кГц - это 27 uS. так вроде? Или 27*8=216 тактов процессора.
Не жирно.
Я б на вашем месте внимательно посмотрел листинг - успевает ли?
Насколько компилер умен - соптимизировал ли?
Так, сравнение с 360 делается два раза...


wdr в прерывании тоже как-то не очень.
Проверку stop сделать 1 раз...
__________________
[ жизнь приятна и красива, если выпить литр пива ]
nml вне форума  
Сказали "Спасибо" nml
E_C_C (25.08.2016)
Непрочитано 25.08.2016, 14:16  
E_C_C
Почётный гражданин KAZUS.RU
 
Аватар для E_C_C
 
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
E_C_C на пути к лучшему
По умолчанию 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.
E_C_C вне форума  
Непрочитано 25.08.2016, 14:52  
nml
Супер-модератор
 
Аватар для nml
 
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,948
Сказали Спасибо 1,327 раз(а) в 578 сообщении(ях)
nml на пути к лучшему
По умолчанию Re: Как оптимизировать алгоритм ?

Сообщение от E_C_C Посмотреть сообщение
Вам большое спасибо ! за совет
Да не за что. Не помню, кажись в GCC компилере... конструкции типа
Код:
 if((faza3==1)&&(delay3›=360)&&(Stop==0))
компилировались как-то совсем некрасиво и неоптимально. Так что листинг все таки рекомендую поглядеть.

Цитата:
и мерцание в индикации пропало.
Э... А что, динамическая индикация в рабочем цикле? Я бы ее как раз в таймер засунул. Тогда ничего на нее влиять не будет.
__________________
[ жизнь приятна и красива, если выпить литр пива ]
nml вне форума  
Эти 2 пользователя(ей) сказали Спасибо nml за это сообщение:
Alex9797 (25.08.2016), E_C_C (25.08.2016)
Непрочитано 25.08.2016, 15:06  
zöner
Гражданин KAZUS.RU
 
Регистрация: 16.02.2012
Сообщений: 441
Сказал спасибо: 89
Сказали Спасибо 735 раз(а) в 149 сообщении(ях)
zöner на пути к лучшему
По умолчанию Re: Как оптимизировать алгоритм ?

у таймера есть регистры OCR, чтобы не считать задержки программно
zöner вне форума  
Сказали "Спасибо" zöner
E_C_C (25.08.2016)
Непрочитано 25.08.2016, 16:04  
E_C_C
Почётный гражданин KAZUS.RU
 
Аватар для E_C_C
 
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
E_C_C на пути к лучшему
По умолчанию Re: Как оптимизировать алгоритм ?

Цитата:

Э... А что, динамическая индикация в рабочем цикле? Я бы ее как раз в таймер засунул. Тогда ничего на нее влиять не будет.
В рабочем , но запускается от таймера , через каждые 50 вызовов прерывания таймера, происходит перелючение знакоместа.
Тут вилка получается - либо стабильно идет индикация и в промежутках я дергаю выхода, либо как можно точнее дергать выход ,а в остальное время индикация , кнопки и.т.п.
А в этом устройстве ,мне нужно, точно и вовремя включать / выключать выхода.
Выпрямитель это будет тиристорный трехфазный , с вольтметром , и обратной связью.И на крайних углах регулирования важно точно выдать управляющий импульс, чтобы не попасть за границы периода.
Листинг смотрел , вроде бы без особых выкрутасов, выложу , как до компа доберусь.

OCR регистры можно было бы использовать , но у меня три независимых задержки , а регистров два...
Хотя, задержки отсчитываются одновременно , и по идее можно обойтись одним отсчетом , а два других вычислить.Надо подумать.
__________________
Да здравствует Разум,да сгинет Маразм!

Последний раз редактировалось E_C_C; 25.08.2016 в 16:07.
E_C_C вне форума  
Непрочитано 25.08.2016, 16:56  
AR_Favorit
Почётный гражданин KAZUS.RU
 
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
AR_Favorit на пути к лучшему
По умолчанию Re: Как оптимизировать алгоритм ?

Сообщение от E_C_C Посмотреть сообщение
Имеется мега8 , работает на частоте 8МГц.
А почему не на 16, уж коли она может?
faza1, faza2,faza3 могут принимать значения больше единицы, или это флаги? если флаги, то if(faza1==1) попробовать заменить на if(faza1) и т.д., по идее должно быть чуть быстрее

Последний раз редактировалось AR_Favorit; 25.08.2016 в 17:04.
AR_Favorit вне форума  
Сказали "Спасибо" AR_Favorit
E_C_C (26.08.2016)
Непрочитано 26.08.2016, 08:26  
E_C_C
Почётный гражданин KAZUS.RU
 
Аватар для E_C_C
 
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
E_C_C на пути к лучшему
По умолчанию 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
__________________
Да здравствует Разум,да сгинет Маразм!
E_C_C вне форума  
Непрочитано 26.08.2016, 09:46  
AR_Favorit
Почётный гражданин KAZUS.RU
 
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
AR_Favorit на пути к лучшему
По умолчанию Re: Как оптимизировать алгоритм ?

Да, с битовыми переменными без разницы получается. Про восьмимегагерцовые меги уж и забыл, древность такую, может, не мучаться и взять Mega8A?))

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

Последний раз редактировалось AR_Favorit; 26.08.2016 в 09:59.
AR_Favorit вне форума  
Сказали "Спасибо" AR_Favorit
E_C_C (26.08.2016)
Непрочитано 26.08.2016, 11:01  
E_C_C
Почётный гражданин KAZUS.RU
 
Аватар для E_C_C
 
Регистрация: 08.05.2008
Адрес: регион 63
Сообщений: 1,827
Сказал спасибо: 739
Сказали Спасибо 683 раз(а) в 386 сообщении(ях)
E_C_C на пути к лучшему
По умолчанию 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
__________________
Да здравствует Разум,да сгинет Маразм!
E_C_C вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
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.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot