Skocz do zawartości

[STM32f0] ADC i DMA problem z kolejnością pomiarów w buforze [Rozwiązany]


Pomocna odpowiedź

Napisano

Mam problem z ADC i DMA w procku STM32F072RBT i StdPeriph

Otóż pomiary w buforze nie są po kolei, tzn. Powinno być wg. mnie od AIN0 do AIN9 a jest AIN9 AIN0 AIN1 AIN2 ... AIN8

Jakiś pomysł z czym to może być związany problem?? Coś z biblioteką? dodam że jeśli odczytuje przez DMA tylko jeden kanał - to wszystko jest ok. Natomiast jeśli odcztuję "n" kanałów to kolejność jest zawsze "n-ty", "n1", "n2" .... "n-1"


volatile uint16_t RegularConvData_Tab[10];

void IN_InputsInit(void)
{
    ADC_InitTypeDef     ADC_InitStructure;
    GPIO_InitTypeDef    GPIO_InitStructure;
    DMA_InitTypeDef   DMA_InitStructure;

    ADC_DeInit(ADC1);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |  GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 10;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);

    DMA_Cmd(DMA1_Channel1, ENABLE);

    ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_OneShot);

    ADC_DMACmd(ADC1, ENABLE);

    ADC_StructInit(&ADC_InitStructure);

    ADC_InitStructure.ADC_Resolution = ADC_Resolution_10b;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_3 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_4 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_5 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_6 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_7 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_55_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_55_5Cycles);

    ADC_GetCalibrationFactor(ADC1);

    ADC_Cmd(ADC1, ENABLE);

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));

    ADC_StartOfConversion(ADC1);

Ja bym spróbował dać

    ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);

za

     ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_55_5Cycles);

Wygląda to tak jakby ADC startował zaczynając od konwersji na 9 kanale.

Próbowałem tak robić ale to nic nie zmienia bo ta funkcja tylko ustawia poszczególne bity w rejestrze ADC1->CHSELR

Kolejność ustawiania tych bitów w funkcji inicjującej nie ma znaczenia, a później brany jest pod uwagę cały rejestr, gdzie kolejność bitów jest taka jak powinna być

Nie jestem pewien, ale jak dla mnie za wcześnie włączyłeś DMA.

Ja używam:

     
ADC_Cmd(ADC1,ENABLE);

ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));

ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));

ADC_DMACmd(ADC1,ENABLE);

ADC_StartOfConversion(ADC1);
  • Pomogłeś! 1

Faktycznie! Słuszna uwaga! Nie wiem czy sam bym zwrócił na to uwagę...

Teraz mam:

    /* ADC Calibration */
    ADC_GetCalibrationFactor(ADC1);

    /* Enable ADC1 */
     ADC_Cmd(ADC1, ENABLE);

    /* Wait the ADCEN falg */
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));

    /* Enable ADC_DMA */
         ADC_DMACmd(ADC1, ENABLE);

    /* ADC1 regular Software Start Conv */
    ADC_StartOfConversion(ADC1);

Wszystko działa tak jak powinno 🙂

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...