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

 
 
> ADC+DMA AVR ATxmega192
KIG
сообщение Jan 13 2014, 07:12
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 25-12-06
Пользователь №: 23 884



Добрый день!

Использую DMA для передачи значений АЦП в буфер (массив из 4652 ячеек). Останов преобразований АЦП происходит в произвольный момент времени. Однако регистр DMA.CH0.TRFCNT всегда считываю равным 4652.
Подскажите, пожалуйста, в чем ошибка?

Я пишу в буфер по кругу (т.е. когда дохожу до конца массива перепрыгиваю на начало), поэтому мне необходимо знать номер ячейки массива, где записана последняя точка.

Инициализацию DMA и считывание регистра DMA.CH0.TRFCNT следующим образом:

Код
void DMAC_init()
{
  DMA.CTRL=0;//DMA отключен
  DMA.CH0.CTRLA|=(1<<7)|(1<<2);//посылка из 1 байта
                        //разрешение работы 0 канала DMA
                        //singleshot
  DMA.CH0.ADDRCTRL|=(1<<3)|(1<<2);//Начальное значение перезагружается
                                  // в регистр адреса получателя DMA в конце каждой транзакции
  DMA.CH0.ADDRCTRL|=(1);//Инкрементное увеличение адреса получателя                                  
  DMA.CH0.TRIGSRC=0x20;//Запуск оn ADCB
  DMA.CH0.TRFCNT=4652;//Количество байт в блоке
  DMA.CH0.SRCADDR0=0x64;//младший байт адреса RESL ADCB.CH0
  DMA.CH0.SRCADDR1=0x02;//старший байт адреса RESL ADCB.CH0
  DMA.CH0.DESTADDR0=((int)&Ch0)&255;
  DMA.CH0.DESTADDR1=((int)&Ch0)>>8;
}

void main
{
DMAC_init();
DMA.CTRL|=(1<<7);//Включили DMA
ADCB_init();
ADCB.CTRLA|=1;//Включаем АЦП
ADCB.CTRLB|=(1<<3); // Старт первого преобразования АЦП

//....  //работа DMA;

ADCB.CTRLA=0;//Отключил АЦП
unsigned int ch_i;
ch_i=DMA.CH0.TRFCNT;
}


Заранее спасибо!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KIG
сообщение Jan 21 2014, 10:44
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 25-12-06
Пользователь №: 23 884



Добрый день!

В продолжении темы...

Цитата
Чтобы dma работал без остановки нужно настроить регистрs канала так: REPEAT=1, SINGLE=1, REPCNT=0. По другому никак.

При вышеуказанных настройках и включенном прерывании от АЦП все работает как и требовалось. Однако, в связи с тем, что переход в функцию обработки прерывания занимает достаточно длительное время (примерно 1,7 мкс при тактовой частоте 29,4912 МГц и частоте дискретизации АЦП 1,08 МГц, т.е. 1 мкс) пришлось отказаться от прерываний. В замен контролирую флаг СН0IF. Если он установлен преобразование завершено, можно сбрасывать флаг и считывать значение регистра результата АЦП.

При этом DMA стал работать следующим образом (наблюдаю по отладчику в AVR Studio 5): запускается раньше, чем устанавливается флаг СH0IF (при этом значение регистра результата преобразования АЦП заполняется значением раньше, чем устанавливается флаг CH0IF) и продолжает работать независимо от состояния флага CH0IF, записывая в массив текущее значение регистра результата АЦП.

Подскажите, пожалуйста, где я ошибся? Заранее спасибо.

Код проверки состояния флага следующий:
Код
asm("loopInt1:");
asm("wdr");
asm("LDS r18,0x0240");//ADCB.CTRLA - Bit 1 - Enable ADCB
asm("TST r18");//if (!(ADCB.CTRLA&1)) goto loopEx1;
asm("BRNE loopInt4");
asm("rjmp loopEx1");
asm("loopInt4:");
asm("LDS r18,0x0263");//INTFLAGS
asm("CPI r18,1");
asm("BRNE loopInt1");
asm("STS 0x0263,1");//Сбрасываем INTFLAG0
asm("LDS r18, 0264");
asm("INC r2");
asm("CP r2,r3");
asm("BRNE loopInt1");
asm("MOV r5,r18");//t1=ADCB.CH0.RES
asm("CLR r2");//t_i=0;
asm("CLR r4");//FLAG=0;


Сообщение отредактировал KIG - Jan 21 2014, 10:51
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jan 21 2014, 11:04
Сообщение #3


Гуру
******

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



Цитата(KIG @ Jan 21 2014, 12:44) *
Однако, в связи с тем, что переход в функцию обработки прерывания занимает достаточно длительное время (примерно 1,7 мкс при тактовой частоте 29,4912 МГц и частоте дискретизации АЦП 1,08 МГц, т.е. 1 мкс)

Что у вас за обработчик такой? Что вы в нём делаете? Вызываете функции из других файлов? Почему вход такой долгий? Приведите код.

Цитата(KIG @ Jan 21 2014, 12:44) *
пришлось отказаться от прерываний.В замен контролирую флаг СН0IF. Если он установлен преобразование завершено, можно сбрасывать флаг и считывать значение регистра результата АЦП.
СН0IF - это флаг статуса АЦП. Так ведь? От ДМА отказались? ДМА само результат должно прочитать и флаг СН0IF сбросить. Или вы что -то другое придумали?

Цитата(KIG @ Jan 21 2014, 12:44) *
При этом DMA стал работать следующим образом (наблюдаю по отладчику в AVR Studio 5): запускается раньше, чем устанавливается флаг СH0IF (при этом значение регистра результата преобразования АЦП заполняется значением раньше, чем устанавливается флаг CH0IF)
Что-то странное...Код приведите...
Цитата(KIG @ Jan 21 2014, 12:44) *
Подскажите, пожалуйста, где я ошибся? Заранее спасибо.

Код проверки состояния флага следующий:
Код
asm("loopInt1:");
asm("wdr");
asm("LDS r18,0x0240");//ADCB.CTRLA - Bit 1 - Enable ADCB

Нужен ли ассемблер тут? Вопрос...

Вы не пробовали использовать ДМА в ping-ping режиме(DMA_DBUFMODE_CH01_gc или DMA_DBUFMODE_CH23_gc и тп)? Если каналы есть, то попробуйте.
Go to the top of the page
 
+Quote Post



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

 


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


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