Ekka 0 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Снова привет всем. Засада с ДМА буфером, точнее с размерностью. Настраиваем ДМА с АЦП через Куб. На 4 канала. В чем вопрос: в инете говорится, что запускать ДМА с АЦП надо примерно так: HAL_ADC_Start_DMA(&hadc1, (uint32_t*)dmaBuf, (uint32_t)dmaBufSize*2); Почему вдруг *2 ??? При таком запуске ДМА благополучно лезет в соседние массивы и пихает туда то, что забрал с АЦП. Однако если запустить так: HAL_ADC_Start_DMA(&hadc1, (uint32_t*)dmaBuf, (uint32_t)dmaBufSize); заполняется либо полмассива, либо часть. В результате не могу нормально усреднить значения. Может кто-то знает, в чем моя проблема? Как надо правильно запускать ДМА? Или, может, у меня какая-то настройка отсутствует? У меня уже глаз замылился с этим ДМА. Настройка ДМА: hdma_adc1.Instance = DMA1_Channel1; hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_LOW; if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Снова привет всем. Засада с ДМА буфером, точнее с размерностью. Не отвечу напрямую по-существу (может проблема связана с DMA_MDATAALIGN_WORD), но хочу указать на проблему с циклическим режимом DMA, с которой я столкнулся. Я наблюдал... спорадические сбои в работе DMA в условиях зашумленности по питанию при включении-выключении соседнего оборудования. Для циклического режима DMA вкупе с ADC в моем случае такие сбои означали, что происходил циклический сдвиг данных в буфере: порядок каналов ADC и данных с них в массиве, куда DMA писАл, переставал соответствовать. Вы рискуете нарваться на те же грабли. Единственный work around был, в прерывании от DMA или в процедуре перезапуска ADC (если тот сам не в циклическом режиме) переинициализировать канал DMA. Такие дела... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ekka 0 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Проблема была в том, что ДМА чешет в прерывание по наполнению половины буфера и потом всякий раз (может, я ошибаюсь и не правильно поняла статью из интернета), когда буфер наполнен больше, чем наполовину, что-то шаманит. Пришлось в прерывании по ДМА по наполнению половины буфера запрещать флаг прерывания по половине (криво звучит, конечно), и дальше обрабатывать только тогда массив, когда будет прерывание по наполнению всего буфера и там снова разрешать флаг по наполнению половины буфера. Плохо в этом соображаю, может напутала что-то. Исправьте меня, если не правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Исправьте меня, если не правильно. Исправить нельзя, пока задача и применённое решение не опубликовано. Предполагаю: имеется ADC с несколькими каналами, поэтому данные из него без потерь и потения CPU можно принять только с помощю DMA. Вопрос, а когда данные рассматриваются годными к использованию? Если после полного цикла преобразования, то это можно сделать в прерывании TC от DMA, а прерывание от половины буфера смысла не имеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A_D 15 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Проблема была в том, что ДМА чешет в прерывание по наполнению половины буфера и потом всякий раз (может, я ошибаюсь и не правильно поняла статью из интернета), когда буфер наполнен больше, чем наполовину, что-то шаманит. Пришлось в прерывании по ДМА по наполнению половины буфера запрещать флаг прерывания по половине (криво звучит, конечно), и дальше обрабатывать только тогда массив, когда будет прерывание по наполнению всего буфера и там снова разрешать флаг по наполнению половины буфера. А других прерываний не разрешено в прошивке ? Может банально проблема с уровнем прерываний ? (прерывание от ДМА более низкое, чем какое то другое и оно перебивается) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться