Skocz do zawartości

[C] [STM32] Problem z ADC i DMA


Slawus

Pomocna odpowiedź

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);
}
Link do komentarza
Share on other sites

Masz gdzieś uruchomienie konwersji?

ADC_SoftwareStartConvCmd(ADC1, ENABLE);

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

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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

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

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.