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

 
 
> STM32F4 DAC+DMA Normal mode
Sprite
сообщение Mar 18 2018, 12:56
Сообщение #1


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

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Добрый день всем участникам форума!

Есть задача: выводить на ЦАП массив из 32-х значений данных в произвольное время (скажем в цикле или по нажатию кнопки). ЦАП настраивается на Normal mode, т.е. по задумке он должен один раз отработать массив данных и выключиться. Проблема в том, что данные выводятся только один (первый) раз при инициализации. Делаю так:
Код
//======================================================================
    __HAL_RCC_DMA1_CLK_ENABLE();
    __HAL_RCC_TIM4_CLK_ENABLE();
    __HAL_RCC_DAC_CLK_ENABLE();
    
    
    TIM4->PSC = 0;                                    //Предделитель
    TIM4->ARR = 83;                                    //Максимальное значение счетного регистра
    TIM4->CR2 = 0x0020;                                //MMS = Update
    TIM4->CR1 |= TIM_CR1_CEN;                        //Включаем таймер
    
    
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    DAC->CR |= DAC_CR_DMAEN1;                        //разрешить прием данных канала №1 от ДМА
    DAC->CR |= DAC_CR_TSEL1_0|DAC_CR_TSEL1_2;        //Timer 4 TRGO event
    DAC->CR |= DAC_CR_TEN1;
    DAC->CR |= DAC_CR_EN1;                            //включить канал 1


    DMA1_Stream5->PAR = (uint32_t)&DAC1->DHR12R1;
    DMA1_Stream5->M0AR = (uint32_t)&Wave1[0];
    DMA1_Stream5->NDTR = 32;
    
    DMA1_Stream5->CR|= DMA_SxCR_CHSEL_0|DMA_SxCR_CHSEL_1|DMA_SxCR_CHSEL_2;    //DMA chanel 7 (согласно таблице "DMA1 request mapping" RM)
    DMA1_Stream5->CR|= DMA_SxCR_MSIZE_0;            //Memory data size = Half-word (16 bit)
    DMA1_Stream5->CR|= DMA_SxCR_PSIZE_0;            //Peripheral data size = Half-word (16 bit)
    DMA1_Stream5->CR|= DMA_SxCR_MINC;                //Memory address pointer is incremented after each data transfer
    //DMA1_Stream5->CR|= DMA_SxCR_CIRC;                //Circular mode
    DMA1_Stream5->CR|= DMA_SxCR_DIR_0;                //Направление 01: Memory-to-peripheral
    
    
    DMA1_Stream5->CR|= DMA_SxCR_EN;                    //Enable DMA
    
//======================================================================


И далее в программе так:
Код
    while (1)
    {
        HAL_Delay(1000);
      
        DMA1_Stream5->CR&= ~DMA_SxCR_EN;            //Disable DMA
        DMA1_Stream5->NDTR = 32;
        DMA1_Stream5->CR|= DMA_SxCR_EN;                //Enable DMA
    }


После первой инициализации данные выводятся, в цикле - не работает( Подозреваю, что не сбрасываю какой-то флаг.
Заранее спасибо!

Сообщение отредактировал Sprite - Mar 18 2018, 12:57
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
jcxz
сообщение Mar 18 2018, 14:19
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Sprite @ Mar 18 2018, 14:56) *
DMA1_Stream5->CR|= DMA_SxCR_CHSEL_0|DMA_SxCR_CHSEL_1|DMA_SxCR_CHSEL_2; //DMA chanel 7 (согласно таблице "DMA1 request mapping" RM)
DMA1_Stream5->CR|= DMA_SxCR_MSIZE_0; //Memory data size = Half-word (16 bit)
...

А зачем все эти чтения-модификации-записи??? Зачем читаете перед каждой операцией? Какой смысл? Причём ещё в много шагов.
Если откроете мануал на МК, то увидите что никакие чтения для регистров CR (ни DMA ни DAC) не нужны. И записать в них всё необходимое можно одной командой записи.
Потому и косяки что непонятно что туда пишете.
К тому же не сбрасываете флаги состояний перед стартом операции.
Вобщем: следует хотя-бы открыть мануал на МК и почитать описание регистров. Всех.

Код
#define timDac (&concat(TIMER, nTIM_dac))
#define timMp3 (&concat(TIMER, nTIM_hr))
#define dmaU   ((nDMASTR_DAC >> 3) ? &DMA2: &DMA1)
#define dmaS   (&dmaU->STREAM[nDMASTR_DAC & 7])
...
  timDac->DIER = timDac->CNT = timDac->PSC = timDac->CR[0] = 0;
  timDac->ARR = DAC_DIV - 1;
  timDac->EGR = B0;
  timDac->CR[1] = 2 << 4;
  __DMB();
  DAC.CR = 0;
  DAC.SR = B13 | B29;
  DAC.CR = (B12 | B13) << concat(DAC_DMASTR, nDMASTR_DAC) * 16 |
    (B0 | B2 | concat(DAC_TIMER, nTIM_dac, _TRGO) << 3) * (B0 | B16);
  __DMB();
  dmaU->IFCR[nDMASTR_DAC >> 2 & 1] = (B0 | B2 | B3 | B4 | B5) <<
    (nDMASTR_DAC & 3) * 6 << (nDMASTR_DAC & B1) * 2;
  dmaS->PAR = (u32)&DAC.DHR12LD;
  dmaS->MAR[1] = dmaS->MAR[0] = (u32)&smplBuf.dummy[0];
  dmaS->NDTR = DMA_CHUNK;
  dmaS->FCR = 3 << DMA_FCR_FTH | 1 << DMA_FCR_DMDIS;
  dmaS->CR = 1 << DMA_CR_EN | 1 << DMA_CR_TEIE | 1 << DMA_CR_TCIE |
    1 << DMA_CR_DIR | 1 << DMA_CR_DBM | DMAPRI_DAC << DMA_CR_PL |
    1 << DMA_CR_MINC | 2 << DMA_CR_PSIZE | 2 << DMA_CR_MSIZE |
    concat(DMAREQ_S, nDMASTR_DAC, _DAC, concat(DAC_DMASTR, nDMASTR_DAC)) <<
    DMA_CR_CHSEL;
  PinSelN(tPinmuxAoutOn);
  ENTR_CRT_SECTION();
  timMp3->CCR[0] = timMp3->CNT + mcs2clk(DAC_tWAKEUP, HrTimerCLK(H));  //по даташиту ждать после включения ЦАП >= tWAKEUP мкс
  timMp3->DIER = B1;
  EXIT_CRT_SECTION();
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 19:11
Рейтинг@Mail.ru


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