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

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

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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

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