Автор Тема: DAC (ЦАП) stm32f429 Лаба  (Прочитано 8381 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
DAC (ЦАП) stm32f429 Лаба
« : Сентябрь 27, 2020, 07:19:51 pm »
Провел несколько дней за экспериментом : Вывод звука через цап.
Так как больше у меня ничего нет, делаю фактически на голой плате.

Вот такой код написал по выводу то одного буфера то другого. Заполнение с сохранением фазы. Просто Синус пытаюсь вывести на ЦАП. Все работает в бесконечном цикле через DMA без участия процессора. Настроил DMA , ЦАП, таймер на 24кГц сэмплирование. Короче работает, но есть проблема. Она на фотке. Это момент переключения буфера.

void DMA1_Stream6_IRQHandler(void)
{
 
    uint8_t old = dacTxBankNawNumber;
      dacTxBankNawNumber= (uint8_t)(~dacTxBankNawNumber & 1);
      HAL_DAC_Stop_DMA(&hdac,DAC_CHANNEL_2);

    if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *) &pOutDac[dacTxBankNawNumber][0], FRAME_SIZE,
                          DAC_ALIGN_12B_R) != HAL_OK) { Error_Handler(); }


    float32_t delta = pp * 1500 / bit;
    for (int i = 0; i < FRAME_SIZE; i++) {
            pOutDac[old][i ] = (uint32_t) (100 + arm_sin_f32(phase) * 100);

        phase += delta;
        if (phase > pp) phase -= pp;

    }


   HAL_DMA_IRQHandler(&hdma_dac2);
}
« Последнее редактирование: Сентябрь 27, 2020, 07:22:07 pm от ra0ahc »
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #1 : Сентябрь 27, 2020, 07:20:41 pm »
Причем фаза действительно совпадает. Но вот этот скачок я не могу победить.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #2 : Октябрь 01, 2020, 05:15:26 pm »
Прогресс !
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #3 : Октябрь 01, 2020, 05:16:54 pm »
Нашел причину. Достал Геннадия. Как всегда не документированные переменные в  CubeMX
Теперь так
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #4 : Октябрь 01, 2020, 05:19:11 pm »
Из-за использования дешевой звуковухи , у нее только микрофонный вход, а у меня выход 3 вольта с цап (при 12БИТ). Так что пришлось снижать искусственно битность выхода (типа регулировка громкости) 
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #5 : Октябрь 01, 2020, 05:24:35 pm »
Ну и пришлось переделывать стандартные процедуры HAL. Это связано с тем , что я не знаю как создавать CallBack функции.
Ну и листинг программы того , что на фотке.

Обработчик прерывания по окончанию передачи буфера. (заполнение синусом свободного буфера)

void DMA1_Stream6_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream6_IRQn 0 */


    if ((DMA1->HISR & DMA_HISR_TCIF6) != 0) {

        uint8_t b = (uint8_t) ((hdma_dac2.Instance->CR & DMA_SxCR_CT) != 0);
        if (b != 0)
            dacTxBankNawNumber = 0;
        else
            dacTxBankNawNumber = 1;
float32_t amp=550;
        for (int i = 0; i < FRAME_SIZE ; i++) {
            pOutDac[dacTxBankNawNumber][i ] = (uint32_t) (amp + arm_sin_f32(phase) * amp);
            phase += delta;
            if (phase > pp) phase -= pp;
            pOutDac[dacTxBankNawNumber][i ] = (uint32_t) (amp + arm_sin_f32(phase) * amp) | pOutDac[dacTxBankNawNumber][i ]<<16 ;
            phase += delta;
            if (phase > pp) phase -= pp;

        }

    }

  /* USER CODE END DMA1_Stream6_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_dac2);
  /* USER CODE BEGIN DMA1_Stream6_IRQn 1 */


  /* USER CODE END DMA1_Stream6_IRQn 1 */
}
« Последнее редактирование: Октябрь 01, 2020, 05:27:35 pm от ra0ahc »
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #6 : Октябрь 01, 2020, 05:26:02 pm »
старт ДМА передачи на цап

__IO uint32_t pOutDac[2][FRAME_SIZE];
.
.
.
     delta = (float32_t) (2 * 3.14159265359 * 740 / 24000);//740Hz

  if (HAL_DAC_Start_DMA_DBM(&hdac, DAC_CHANNEL_2, (uint32_t *) &pOutDac[0][0],  (uint32_t *) &pOutDac[1][0],FRAME_SIZE*2) != HAL_OK) {
    Error_Handler();
  }

Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #7 : Октябрь 01, 2020, 05:26:39 pm »
///

HAL_StatusTypeDef HAL_DAC_Start_DMA_DBM(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t *pData, uint32_t *pData1, uint32_t Length) {
    uint32_t tmpreg = 0U;

    /* Check the parameters */
    assert_param(IS_DAC_CHANNEL(Channel));
    // assert_param(IS_DAC_ALIGN(Alignment));

    /* Process locked */
    __HAL_LOCK(hdac);

    /* Change DAC state */
    hdac->State = HAL_DAC_STATE_BUSY;

    /* Set the DMA transfer complete callback for channel2 */
    hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;

    /* Set the DMA half transfer complete callback for channel2 */
    hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;

    /* Set the DMA error callback for channel2 */
    hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;

    /* Enable the selected DAC channel2 DMA request */
    hdac->Instance->CR |= DAC_CR_DMAEN2;

    /* Case of use of channel 2 */

    /* Get DHR12R2 address */
    tmpreg = (uint32_t) &hdac->Instance->DHR12R2;

    /* Enable the DAC DMA underrun interrupt */
    __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);

    /* Enable the DMA Stream */

    HAL_DMAEx_MBStart_IT(hdac->DMA_Handle2, (uint32_t) pData, tmpreg, (uint32_t) pData1, Length);
    /* Enable the Peripheral */
    __HAL_DAC_ENABLE(hdac, Channel);

    /* Process Unlocked */
    __HAL_UNLOCK(hdac);

    /* Return function status */
    return HAL_OK;
}

HAL_StatusTypeDef HAL_DMAEx_MBStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress,
                                                uint32_t SecondMemAddress, uint32_t DataLength) {
    HAL_StatusTypeDef status = HAL_OK;

    /* Check the parameters */
    assert_param(IS_DMA_BUFFER_SIZE(DataLength));

    /* Process locked */
    __HAL_LOCK(hdma);

    if (HAL_DMA_STATE_READY == hdma->State) {
        /* Change DMA peripheral state */
        hdma->State = HAL_DMA_STATE_BUSY;

        /* Initialize the error code */
        hdma->ErrorCode = HAL_DMA_ERROR_NONE;

        /* Enable the Double buffer mode */
        hdma->Instance->CR |= (uint32_t) DMA_SxCR_DBM;

        /* Configure DMA Stream destination address */
        hdma->Instance->M1AR = SecondMemAddress;

        /* Configure the source, destination address and the data length */
        //DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
        hdma->Instance->NDTR = DataLength;

        /* Peripheral to Memory */

        /* Configure DMA Stream destination address */
        hdma->Instance->PAR = DstAddress;

        /* Configure DMA Stream source address */
        hdma->Instance->M0AR = SrcAddress;

        /* Clear all flags */
        __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

        /* Enable Common interrupts*/
        hdma->Instance->CR |= DMA_IT_TC;

        /* Enable the peripheral */
        __HAL_DMA_ENABLE(hdma);
    } else {
        /* Process unlocked */
        __HAL_UNLOCK(hdma);

        /* Return error status */
        status = HAL_BUSY;
    }
    return status;
}

Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #8 : Октябрь 01, 2020, 05:30:08 pm »
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #9 : Октябрь 01, 2020, 05:31:27 pm »
Точность подбора частоты деления  cr123 cr123 cr123
Должно быть 740Гц
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #10 : Октябрь 01, 2020, 05:35:17 pm »
 lllol
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #11 : Октябрь 01, 2020, 05:41:33 pm »
Сейчас с цап идёт вот такой сигнал , поэтому палок там в сигнале полно.  lllol
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #12 : Октябрь 01, 2020, 06:00:08 pm »
Походу ошибка в заполнении буфера . Не должно быть такой зебры.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #13 : Октябрь 01, 2020, 08:09:39 pm »
Я так и думал, не правильно массив заполнил. Очень быстро перегружается вход. Вот более менее нормальный синус.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: DAC (ЦАП) stm32f429 Лаба
« Ответ #14 : Октябрь 01, 2020, 08:10:15 pm »
void DMA1_Stream6_IRQHandler(void) {
    /* USER CODE BEGIN DMA1_Stream6_IRQn 0 */


    if ((DMA1->HISR & DMA_HISR_TCIF6) != 0) {

        uint8_t b = (uint8_t) ((hdma_dac2.Instance->CR & DMA_SxCR_CT) != 0);
        if (b != 0)
            dacTxBankNawNumber = 0;
        else
            dacTxBankNawNumber = 1;

        float32_t amp = 100;

        for (int i = 0; i < FRAME_SIZE; i++) {
            pOutDac[dacTxBankNawNumber][i ] = (uint32_t) (amp + arm_sin_f32(phase) * amp);

            phase += delta;
            if (phase >= pp) phase -= pp;

            pOutDac[dacTxBankNawNumber][i ] |= ((uint16_t) (amp + arm_sin_f32(phase) * amp)) << 16;
            phase += delta;
            if (phase >= pp) phase -= pp;

        }

    }

    /* USER CODE END DMA1_Stream6_IRQn 0 */
    HAL_DMA_IRQHandler(&hdma_dac2);
    /* USER CODE BEGIN DMA1_Stream6_IRQn 1 */


    /* USER CODE END DMA1_Stream6_IRQn 1 */
}
Да да, я знаю, у меня ничего не получится )))