Skocz do zawartości

[C] [STM32] Problem z ADC i DMA


Pomocna odpowiedź

Napisano

Mam problem z ADC i DMA z którym nie mogę sobie poradzić...

Mianowicie - sprawdzam stan 8 czujników KTIR. W debugerze tablica przechowująca pomiary zawiera za każdym razem podobne pomiary (bez względu na połozenie czujników). 7 z 8 czujników pokazuje wartość około 2500, jeden zaś zawsze 0 (wszystkie czujniki świecą).

Wklejam kod funkcji inicjującej DMA, ADC i RCC i proszę o pomoc 😉

void RCC_Config(void) {
SystemInit(); //@72Mhz - maksymalne możliwosci procesora

//Taktowanie peryferiów
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1EN, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

void ADC_Config(void) {
ADC_InitTypeDef ADC_InitStructure; //konf przetwornika ADC
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //jeden przetwornik, praca niezalezna
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //pomiar wielu kanalow, skan wlaczony
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //pomiar ciągły
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //brak wyzwalania zewnetrznego
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //wyrownanie danych do prawej
ADC_InitStructure.ADC_NbrOfChannel = 8; //liczba uzywanych kanalow = 8
ADC_Init(ADC1, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 8, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 7, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 6, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 5, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 2, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_7Cycles5);

ADC_DMACmd(ADC1,ENABLE); //DMA dla ADC1
ADC_Cmd(ADC1,ENABLE); //wlacz ADC12

ADC_ResetCalibration(ADC1); //reset rejestrow kalibracyjnych
while(ADC_GetResetCalibrationStatus(ADC1)); //odczekanie na wykonanie testu
ADC_StartCalibration(ADC1); //wykonanie kalibracji
while(ADC_GetCalibrationStatus(ADC1)); //odczekanie na koniec kalibracji
}

void DMA_Config(void) {
  //konfigurowanie DMA

  #define ADC1_DR_Address 0x4001244C;                                             //adres rejestru ADC1->DR

  DMA_InitTypeDef DMA_InitStructure;


  DMA_DeInit(DMA1_Channel1);                                                      //Usun ewentualna poprzednia konfiguracje DMA

  DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned long int)ADC1_DR_Address;  //Adres docelowy transferu
  DMA_InitStructure.DMA_MemoryBaseAddr = (unsigned long int)&buforADC;            //Adres poczatku bloku do przeslania
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                              //Kierunek transferu
  DMA_InitStructure.DMA_BufferSize = 8;                                           //Liczba elementow do przeslania (dlugosc bufora)
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //Wylaczenie automatycznego zwiekszania adresu po stronie ADC
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                         //Wlaczenie automatycznego zwiekszania adresu po stronie pamieci (bufora)
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;     //Rozmiar pojedynczych przesylanych danych po stronie ADC (HalfWord = 16bit)
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;             //Rozmiar pojedynczych przesylanych danych po stronie pamieci (bufora)
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                 //Tryb dzialania kontrolera DMA - powtarzanie cykliczne
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                             //Priorytet DMA - wysoki
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                    //Wylaczenie obslugi transferu z pamieci do pamieci
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);                                    //Zapis konfiguracji

  //Wlacz DMA, kanal 1
  DMA_Cmd(DMA1_Channel1, ENABLE);
}

Masz gdzieś uruchomienie konwersji?

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

Czy mierzyłeś wyjścia czujników, zmienia się tam sygnał?

Mam uruchomioną konwersję, zaraz przed pętlą główną programu (while).

Fizycznie nie mierzyłem sygnału wyjściowego czujników... Jeszcze 😉

  • 2 tygodnie później...

Zdaje mi się że musisz zarejestrować przerwanie od ADC. Inaczej NVIC nie powiadomi DMA o zakończeniu konwersji w ADC. Nie wiem co tam uruchamiasz jeszcze, nie zamieściłeś całego kodu.

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...