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

 
 
> Как бы оптимальней закодировать алгоритм, IAR AVR 6.1
_Артём_
сообщение Feb 1 2012, 01:02
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Здраствуйте.
Посоветуйте как оптимальней (по скорости исполнения) реализовать алгоритм для xmega256A3:
Обрабатываются 8 каналов ацп A и 8 каналов ацп B.
Каждый канал ацп суммируется 16 раз в прерывании таймера, кроме того каналы ацп а могут использоваться как логические входы (пороги задаются), и также перепады могут фиксироваться (инкремент счётчика). В каждом прерывании считываются и запускается 4 преобразования ацп а и 4 ацп Б.
CODE
#ifndef adc_h__
#define adc_h__

#include "avr_compiler.h"
#include "adc_driver.h"



#include "adc_driver.h"

struct TADC_AChannel {// данные канала на АЦП А
unsigned char Cnt;// счётчик передов
unsigned char CntUp;// считать фронт
unsigned char CntDown;// считать срез
unsigned char State;// состояние входа
unsigned char NextMux;// значение MUX
unsigned short LvlH, LvlL;// уровни 1 и 0
unsigned short Sum;// накопленная сумма
void Init(
unsigned short level_h, // уровень 1
unsigned short level_l, // уровень 0
unsigned char cnt_mode, // счёт. импульсов/ аналоговый вход
unsigned char state // начальное логическое состояние
) {
Cnt=0;
LvlH=level_h;
LvlL=level_l;
CntUp = (cnt_mode&1) ? (1) : (0);
CntDown = (cnt_mode&2) ? (1) : (0);
State=state;
}
void Exec(unsigned short new_value) {
if (Cnt) {
// режим счёта импульсов
if (State) {
if (new_value<LvlL) {
State=0;
if (CntDown)
Cnt++;
}
}
else {
if (new_value>LvlH) {
State=1;
if (CntUp)
Cnt++;
}
}
}
Sum+=new_value;
}
};

struct TADC_BChannel {// данные канала на АЦП А
unsigned short Sum;// накопление суммы
unsigned char NextMux;
void Exec(unsigned short new_value) {
Sum+=new_value;
}
};



class TAdc {
unsigned char ADCAMode;
volatile unsigned char ActiveArray;
volatile unsigned char SumReady;
struct TADC_AChannel AdcA[2][8];
struct TADC_BChannel AdcB[2][8];

volatile unsigned char ADCReady;
unsigned char CycleCnt;


public:
void StartNextConvervion()
{
TADC_AChannel *adc_ptr;

// определение текущего блока памяти для записи
unsigned char active_block = (ActiveArray) ? (1) : (0);
adc_ptr= (active_block) ? (&AdcA[1][0]) : (&AdcA[0][0]);

if (CycleCnt&1)
adc_ptr+=4; // чтение каналов 4-7
unsigned short adc_result;

// виртуальный канал 0 АЦП А
adc_result=ADCA.CH0.RES;
adc_ptr->Exec(adc_result);
ADCA.CH0.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

// виртуальный канал 1 АЦП А
adc_result=ADCA.CH1.RES;
adc_ptr->Exec(adc_result);
ADCA.CH1.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

// виртуальный канал 2 АЦП А
adc_result=ADCA.CH2.RES;
adc_ptr->Exec(adc_result);
ADCA.CH2.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

// виртуальный канал 3 АЦП А
adc_result=ADCA.CH3.RES;
adc_ptr->Exec(adc_result);
ADCA.CH3.MUXCTRL=adc_ptr->NextMux;
adc_ptr++;

struct TADC_BChannel *adcb_ptr=(active_block) ? (&AdcB[1][0]) : (&AdcB[0][0]);

// виртуальный канал 1 АЦП B
adc_result=ADCB.CH0.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH0.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// виртуальный канал 2 АЦП B
adc_result=ADCB.CH1.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH1.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// виртуальный канал 3 АЦП B
adc_result=ADCB.CH2.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH2.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// виртуальный канал 4 АЦП B
adc_result=ADCB.CH3.RES;
adcb_ptr->Exec(adc_result);
ADCB.CH3.MUXCTRL=adcb_ptr->NextMux;
adcb_ptr++;

// запуск преобразования
ADC_Conversions_Start(&ADCA, 0xF<<2);
ADC_Conversions_Start(&ADCB, 0xF<<2);

if (++CycleCnt>=16) {
// накоплено 16 отсчётов
CycleCnt=0;
adc_ptr= (active_block) ? (&AdcA[0][0]) : (&AdcA[1][0]);
TADC_AChannel *adc_ptr2= (active_block) ? (&AdcA[1][0]) : (&AdcA[0][0]);
for (char i=0; i<16; i++) {
adc_ptr->Cnt=0;
adc_ptr->Sum=0;
adc_ptr->State=adc_ptr2->State;
adc_ptr++;
adc_ptr2++;
}
adcb_ptr=(active_block) ? (&AdcB[0][0]) : (&AdcB[1][0]);
for (char i=0; i<16; i++) {
adcb_ptr->Sum=0;
}
SumReady=1;
}
}
};



extern TAdc Adc;
void InitADC();

#endif // adc_h__


Прерывание:

Код
TAdc Adc;
ISR(TCC0_OVF_vect)
{
    Adc.StartNextConvervion();
}


IAR выдал код с временем выполнения 450-550 циклов в зависимости от настроек оптимизации, что не есть гуд.
Из интереса создал проект для GCC, проверил в симуляторе ~320-350 тактов (не ожидал такого результата - удивлён).
Как получить от IAR похожий результат?

P.S. Проект сначала не компилился для GCC:
Код
In file included from ../../avr_compiler.h:132:0,
                 from ../task1.cpp:2:
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: In function 'void _delay_ms(double)':
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:149:42: error: 'fabs' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:149:43: error: 'ceil' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h: In function 'void _delay_us(double)':
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:226:42: error: 'fabs' was not declared in this scope
c:\avr_toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h:226:43: error: 'ceil' was not declared in this scope
make: *** [task1.o] Ошибка 1

Что за ...?
Прект:Прикрепленный файл  avr1513.rar ( 313.16 килобайт ) Кол-во скачиваний: 89

Закоментировал delay.h. Тогда откомпилировалось.

Сообщение отредактировал IgorKossak - Feb 1 2012, 07:51
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 17:22
Рейтинг@Mail.ru


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