#c #stm32 #dma #stm32f4 #data-loss
Вопрос:
Первый раз работаю с DMA здесь, и я получаю потерю данных, когда частота ШИМ-сигнала изменяется во время считывания DMA. Запрос DMA запускается тактовой частотой 16 МГц. Я использую DMA2 на STM32f429zi.
Направление DMA является периферийным для памяти, где я пытаюсь прочитать весь порт GPIO E в память. Потеря данных четко видна в начале считывания DMA при изменении частоты ШИМ. Если я закомментирую код с изменением частоты ШИМ (см. Часть кода ниже), при считывании DMA не произойдет видимой потери данных.
На прикрепленном изображении вы можете видеть, что верхний график теряет точки данных синусоидальной волны (4 точки за период), а на нижнем графике потери данных нет.
Как я понимаю, DMA должна работать независимо и не зависеть от процессора, но для меня это, похоже, не так. Может ли это быть связано с работой со слишком высокой тактовой частотой? Или я упускаю что-то еще? Я действительно застрял на этой проблеме, любая помощь будет признательна.
С уважением, Линда
/*------------------- Comment out when not changing PWM frequency --------------------------------------------------------------------*/
// /* Start 40 MHz */
// TIM3->CCR1 = 1; // 40 MHz
/*------------------------------------------------------------------------------------------------------------------------------------*/
/* Start DMA for ping signal with length BUFFER_SIZE (PA9 (channel 2) is clockout of ADC, sampling on falling edge of PA9) */
if (HAL_DMA_Start_IT(htim1.hdma[TIM_DMA_ID_CC2], (uint32_t)amp;(GPIOF->IDR), (uint32_t)amp;aDST_Buffer, BUFFER_SIZE) != HAL_OK)
{
/* Transfer Error */
Error_Handler();
}
/*------------------- Comment out when not changing PWM frequency --------------------------------------------------------------------*/
// /* Continue while timer is lower than 1,3 us */
// while (__HAL_TIM_GET_COUNTER(amp;htim5) - timer_val1 < 13)
// {
// }
// /* Start ping, 4 MHz */
// TIM3->ARR = 20; // period
// TIM3->CCR1 = 9; // pulse
// timer_val1 = __HAL_TIM_GET_COUNTER(amp;htim5);
// while (__HAL_TIM_GET_COUNTER(amp;htim5) - timer_val1 < 9) // 5 pulses
// {
// }
//
// TIM3->ARR = 1; // 40Mhz
// TIM3->CCR1 = 1;
// while (__HAL_TIM_GET_COUNTER(amp;htim5) - timer_val1 < 25)
// {
// }
/*------------------------------------------------------------------------------------------------------------------------------------*/
Комментарии:
1. Добро пожаловать в StackOverflow. Пожалуйста, найдите время, чтобы правильно отформатировать свой код.
2. Чего вы хотите достичь с помощью своего кода? Если вам кажется, что вы хотите прочитать ШИМ (рабочий цикл) через входы GPIO (выход таймера, подключенный к порту E?). Что делает АЦП в строке комментария 5? Пожалуйста, объясните свое намерение немного подробнее.
3. Предполагается, что DMA должен считывать синусоидальный сигнал, посылаемый АЦП на порт GPIO. В то же время (при чтении потока DMA) следует просто отправить ШИМ-сигнал для другого использования.
4. В целом вы правы, DMA теоретически работают независимо от основного процессора. Тем не менее, они оба используют одну и ту же шину данных, и я предполагаю, что ваши 2 процесса (чтение GPIO, запись PWM) могут влиять на одну и ту же систему и вызывать проблемы с оборудованием, которое вы измеряете. Я бы предложил сначала проверить, действительно ли данные, которые вы пытаетесь отобразить выше, существуют в аппаратном обеспечении, и проблема связана с самим DMA-подключите осциллограф к шине и повторите код, проверьте, поступает ли один и тот же вывод на обоих
5. Какова исходная частота ШИМ (частота, запрограммированная перед настройкой передачи DMA)? Я думаю, что могут возникнуть некоторые проблемы с частотой дискретизации при попытке выполнить выборку сигнала 40 МГц с тактовой частотой 16 МГц. Попробуйте изменить код для вывода постоянной ШИМ 4 МГц и посмотрите на график, затем попробуйте постоянную ШИМ 40 МГц и посмотрите, все ли в порядке с графиками.