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

 
 
> 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
Ответов
Sprite
сообщение Mar 19 2018, 03:49
Сообщение #2


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

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



x893
Код
Видимо лень посмотреть примеры перед тем как код писать.
И Вам хорошего дня)

jcxz
Цитата
А зачем все эти чтения-модификации-записи??? Зачем читаете перед каждой операцией? Какой смысл? Причём ещё в много шагов.
Понятно, что код инициализации ДМА можно уложить в 4 строки, записав числа в регистры PAR, M0AR, NDTR и CR. Я специально вынес каждый бит отдельно, чтобы было нагляднее. Тем более что процедура инициализации DMA выполняется один раз при старте, т.е. нет строгих временных требований к выполнению этого кода.

Цитата
следует хотя-бы открыть мануал на МК и почитать описание регистров.
Так и сделал, прочитал внимательно пункт 1 10.3.17 Stream configuration procedure:
All the stream dedicated bits set in the
status register (DMA_LISR and DMA_HISR) from the previous data block DMA
transfer should be cleared before the stream can be re-enabled.
Стало более менее понятно.

adnega, спасибо! Счастье есть) Добавил строчку
Код
DMA1->HIFCR|= DMA_HISR_HTIF5|DMA_HISR_TCIF5;
и все заработало.

В даташите также написано, что нужно после выключения DMA прочитать бит EN, т.е. проверить что он выключился. Ставить while как то "не спортивно") Подскажите как правильно? Надо ли проверять этот бит?


Go to the top of the page
 
+Quote Post



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

 


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


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