Цитата(AlHakim @ Jul 21 2014, 15:28)

вот недавно сам столкнулся с таким же. Нашел решение на этом же форуме. А именно сбрасывать регулярные каналы. И все заработал
вот мой код
Код
//=== Прерывания DMA ADC1 ===//
void DMA1_Channel1_IRQHandler(void)
{
ADC1->CR2 &= ~ADC_CR2_DMA;// | ADC_CR2_ADON); // выключаем DMA запросы АЦП
ADC1->SR &= ~(ADC_SR_STRT); // сброс флага Overrun и старта преобразования
ADC1->SQR1 &= ~ADC_SQR1_L; // сброс количества последовательных преобразований [сброс указателя канала]
DMA1_Channel1->CCR &= ~ (DMA_CCR_EN |DMA_CCR_TCIE); //// деактивация 1го потока DMA1
if(DMA1->ISR & DMA_ISR_TCIF1) EventFlags.Bit.ADCConvFinish = 1; // проверяем прерывание по завершению передачи блока
DMA1->IFCR=DMA_IFCR_CGIF1|DMA_IFCR_CTCIF1|DMA_IFCR_CHTIF1|DMA_IFCR_CTEIF1; //снимаем биты в DMA1->ISR (пока все)
}
//=== Прерывания TMR2 ===//
void TIM2_IRQHandler(void){ // Период - 160 мксек при частоте сети 50 Гц.
vu32 aa, cosa, cosb, cosc;
vu8 i;
TIM2->SR &= ~TIM_SR_UIF; // Снять флаг прерывания.
DMA1_Channel1->CNDTR = 18; // указываем число пересылаемых данных 3 канала по 6-и перобразовании
DMA1_Channel1->CCR |= DMA_CCR_EN | DMA_CCR_TCIE;// запустили очередное преобразование ADC (должны успеть,ааа)
Я тоже так пробую делать (сброс бита DMA в CR2 и STRT в SR, чтение DR три раза) за исключением сброса количества преобразований в SQR1, правда. Сейчас попробую и это, хотя на мой взгляд - как из пушки по воробьям.
Кстати, в Вашем коде нет собственно "взвода" ADC на следующую операцию. Опущено здесь для иллюстрации? Еще для упрощения можно делать ADC1->SR = ~(ADC_SR_STRT), без &=, т.к. регистр SR есть rc/w0 - тип: пишешь прямо 0 в сбрасываемый бит.
Цитата(Сергей Борщ @ Jul 21 2014, 17:25)

Значит на момент старта DMA АЦП уже успело сделать два измерения и результат первого для DMA оказался потерян. В какой последовательности вы запускаете всю эту кухню? По моим понятиям надо делать так:
1) таймер остановлен
2) Настраиваем АЦП, сбрасываем все готовности, которые могли остаться от предыдущей работы.
3) Настраиваем ПДП
4) запускаем таймер.
Ладно, цитатнём код.
Единократная инициализация:
CODE
// TIM8 config:
DBGMCU_Config(DBGMCU_TIM8_STOP, ENABLE);
MIC_TIM_INIT(TIMx);
// At this point TIM8 is still stopped; see MIC_Control(true) below.
// Init DMA2 Channel5:
DMA_DeInit(ADCx_DMA);
DMA_INIT(ADCx_DMA, DMA_InitStruct);
IRQ_INIT(NVIC_DMAInitStructure);
DMA_TC_ENABLE(ADCx_DMA); // transmission complete interrupt enable
// At this point DMA is still disabled; see MIC_Control(true) below.
// Init ADC:
ADCx_ClockConfig(ADCx, SystemCoreClock);
ADC_DeInit(ADCx);
ADC_INIT(ADCx, ADC_InitStructure);
ADC_ConfigChannels(ADCx, MIC_ChannelRanks, sizeof(MIC_ChannelRanks));
ADC_ENABLE(ADCx); // wake up
ADC_Calibrate(ADCx); ADCx->DR; // calibrate once, clear DR afterwards
ADC_ExternalTrigConvCmd(ADCx, ENABLE); // enable by TIM8 TRGO
// Start MIC sampling
MIC_Control(true);
Это объяснение для MIC_Control(true):
CODE
// -----------------------------------------------------------------------------
//
// Clears the data register n times resetting the scan mode
//
void ADC_ClearRegular(ADC_TypeDef* adc, int cnt)
{
adc->SR = ~ADC_SR_STRT; // rc/w0 register
while (cnt--) adc->DR;
}
// -----------------------------------------------------------------------------
//
// Starts/stops the ADC processing
//
void MIC_Control(bool action)
{
// Stop completely
TIM_DISABLE_R(TIMx);
ADC_DMACmd(ADCx, DISABLE);
ADC_ClearRegular(ADCx, MIC_CHAN_COUNT);
if (action)
{
memset(*ADC_MICx, MIC_INIT_VALUE, sizeof(*ADC_MICx));
MIC_DMA_Restart(bufnum = 0);
ADC_DMACmd(ADCx, ENABLE); // use DMA
// Restart completely
MIC_Reload_Timer(MIC_SAMPLE_RATE);
TIM_ENABLE_R(TIMx); // start the sample rate timer
}
}
И самое интересное в прерывании:
CODE
// -----------------------------------------------------------------------------
//
// DMA2 Channel5 IRQ handler
//
void DMA2_Channel4_5_IRQHandler(void)
{
ADC_DMACmd(ADCx, DISABLE);
ADC_ClearRegular(ADCx, MIC_CHAN_COUNT);
MIC_DMA_Restart(bufnum = 1 - bufnum);
ADC_DMACmd(ADCx, ENABLE);
sample_ready.val = 1;
}
В коде много функций, которые на самом деле макросы, но из имен ясно, что они делают. Думаю, последовательность ясна.