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

 
 
> Загрузка DAC через DMA по TACCR0_CCIFG, что-то не так, не запускается цикл DMA
MrYuran
сообщение Jul 2 2009, 07:31
Сообщение #1


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Гляньте пожалуйста, кто в теме, что-то не выходит каменный цветок...
ManDAC(), который внизу, работает, формирует программную синусоиду на 5 ноге.
Таймер работает правильно, тестовые пички в прерываниях расставлены через 78мкс, как и положено (400Гц х 32 сэмпла)
Что-то именно в инициализации DMA

Кристалл - f169
CODE

//**************************************************************************
// Модуль управления генераторами
//**************************************************************************

#include "gen.h"
#include "../main/dco.h"
#include <signal.h>

/**
* Таблица данных для синтеза синусоиды ЦАПом
* Формируется в файле Рассчёты.xls
*/
static const int SinTableData[SIN_TABLE_SIZE] = {
0, 399, 783, 1137, 1447, 1702, 1891, 2008,
2047, 2008, 1891, 1702, 1447, 1137, 783, 399,
0, -399, -783, -1137, -1447, -1702, -1891, -2008,
-2047, -2008, -1891, -1702, -1447, -1137, -783, -399
} ;

static unsigned int TableIndex = 0;

/**
* Инициализация генератора
*/
void GenInit()
{
//---------------------- инициализация порта ----------------
GenPort.dir.GenPin = 1;
GenPort.sel.GenPin = 1;
//---------------------- инициализация ЦАП ------------------
DAC12_0CTL = DAC12SREF_2 // внешняя опора
| DAC12IR // однократный диапазон выходного напряжения
| DAC12AMP_2 // низкое потребление/низкая скорость переключения
| DAC12ENC
| DAC12DF ; // формат данных с дополнением до 2-х

DAC12_0CTL |= DAC12CALON; // запуск калибровки
//---------------------- инициализация канала DMA для ЦАП ---

DMACTL0 &= 0xfff0; // очистка настроек канала 0
DMACTL0 |= DMA0TSEL_7; // запуск от Timer_A CCRIFG.0
DMACTL1 = 0;



DMA0SA = SinTableData; // Источник - начало таблицы сэмплов
DMA0DA = DAC12_0DAT; // Получатель - регистр данных ЦАП
DMA0SZ = SIN_TABLE_SIZE; // Прерывание будет после выдачи всей таблицы

DMA0CTL = DMADT_4 // DMA transfer mode 4: single, repeat
| DMADSTINCR_0 // DMA destination address unchanged
| DMASRCINCR_3 // DMA source address incremented
| DMAEN // DMA enable
| DMAIE; // DMA interrupt enable
//---------------------- инициализация таймера для запуска DMA ---
unsigned long TimerCCR0 = (unsigned long)TA_TICKS_IN_1MS * 1000 / DEFAULT_SAMPLE_RATE;
TACCR0 = (unsigned int)TimerCCR0;
//TACCR0 = 375;
TACCTL0 = CCIE;
TACTL = TASSEL_2 // SMCLK
| ID_0 // /1
| MC_1 // Up
| TACLR; // Clear
}

interrupt (TIMERA0_VECTOR) TA0_isr(void)
{
P6OUT |= 4;
P6OUT &= ~4;
}

interrupt (DACDMA_VECTOR) DMA_isr(void)
{
DMA0CTL &= ~DMAIFG; // сброс флага
DMA0SA = SinTableData; // Источник - начало таблицы сэмплов
//DMA0DA = DAC12_0DAT; // Получатель - регистр данных ЦАП
DMA0SZ = SIN_TABLE_SIZE; // Прерывание будет после выдачи всей таблицы
}

void ManDAC()
{
DAC12_0DAT = SinTableData[TableIndex++];
if(TableIndex >= SIN_TABLE_SIZE) TableIndex = 0;
}


Вообще сейчас ещё раз весь раздел про DMA перечитал, в принципе при повторяющемся однократном переносе (как у меня) прерывание по концу цикла и не нужно, т.к. регистры DMA0SA, DMA0DA и DMA0SZ самовосстанавливаются до исходных значений, и DMAEN не сбрасывается.
То есть фактически после окончания цикла он должен повториться заново на автомате.
Но почему-то не выполняется вообще.
DMA_isr() не вызывается ни разу со времени включения.

###

Пока воткнул костыль в виде ManDAC() внутри TA0_isr()
(надо ещё глянуть, заинлайнился или вызывается через Call)
Оценил, насколько проредился импульс сброса внешнего вочдога в пустом пока ещё мэйне... sad.gif

Обидно, блин... за что тогда 500р, DAC можно было и внешний поставить...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MrYuran
сообщение Jul 2 2009, 09:43
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



####
Продолжаю тему...
Сделал запуск DMA вручную:
Код
DMACTL0 &= 0xfff0;                  // очистка настроек канала 0
    //DMACTL0 |= DMA0TSEL_7;              // запуск от Timer_A CCRIFG.0
    DMACTL0 |= DMA0TSEL_0;
    DMACTL1 = 0;

    DMA0CTL = DMADT_4                   // DMA transfer mode 4: single, repeat
            | DMADSTINCR_0              // DMA destination address unchanged
            | DMASRCINCR_3              // DMA source address incremented
            | DMAEN                     // DMA enable
            | DMAIE;                    // DMA interrupt enable

    DMA0SA = SinTableData;              // Источник - начало таблицы сэмплов
    DMA0DA = DAC12_0DAT;                // Получатель - регистр данных ЦАП
    DMA0SZ = SIN_TABLE_SIZE;            // Прерывание будет после выдачи всей таблицы

    //---------------------- инициализация таймера для запуска DMA ---
    unsigned long TimerCCR0 = (unsigned long)TA_TICKS_IN_1MS * 1000 / DEFAULT_SAMPLE_RATE;
    TACCR0 = (unsigned int)TimerCCR0;
    //TACCR0 = 375;
    TACCTL0 = CCIE;
    TACTL = TASSEL_2                    // SMCLK
          | ID_0                        // /1
          | MC_1                        // Up
          | TACLR;                      // Clear
}

interrupt (TIMERA0_VECTOR) TA0_isr(void)
{
    //ManDAC();
    DMA0CTL |= DMAREQ;
}

interrupt (DACDMA_VECTOR) DMA_isr(void)
{
    P6OUT |= 4;
    DMA0CTL &= ~DMAIFG;                 // сброс флага
    P6OUT &= ~4;
}

Теперь DMA запускается, в конце цикла (32 запуска) формируется прерывание.
Всё бы хорошо, только данные не переносятся.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 2 2009, 10:14
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(MrYuran @ Jul 2 2009, 12:43) *
Продолжаю тему...

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post



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

 


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


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