Skocz do zawartości

STM32L452 jak uruchomić przetwornik ADC w Low Layer


Protektor28

Pomocna odpowiedź

Czołem, mam pewien problem. Czytając reference manuala STM'a nie do końca rozumiem jak uruchomić przetwornik analogowo-cyfrowy pisząc na poziomie Low Layer ( założeniem projektu jest nie korzystać z bibliotek HAL'a). Jestem początkujący w programowaniu "bez HAL", dlatego proszę o wyrozumiałość i o pomoc/rady. Ustawienia ADC jakie wygenerowałem przy użyciu Cube'a wyglądają następująco:

static void MX_ADC1_Init(void)
{

  LL_ADC_InitTypeDef ADC_InitStruct;
  LL_ADC_REG_InitTypeDef ADC_REG_InitStruct;
  LL_ADC_CommonInitTypeDef ADC_CommonInitStruct;

  LL_GPIO_InitTypeDef GPIO_InitStruct;

  /* Peripheral clock enable */
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
  
  /**ADC1 GPIO Configuration  
  PC0   ------> ADC1_IN1
  PC4   ------> ADC1_IN13 
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_4;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /* ADC1 interrupt Init */
  NVIC_SetPriority(ADC1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(ADC1_IRQn);

    /**Common config 
    */
  ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
  ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
  ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
  LL_ADC_Init(ADC1, &ADC_InitStruct);

  ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
  ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
  ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
  ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
  ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_LIMITED;
  ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
  LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);

  LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);

  ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1;
  LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);

  LL_ADC_EnableIT_EOC(ADC1);

  LL_ADC_DisableIT_EOS(ADC1);

    /**Configure Regular Channel 
    */
  LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_1);

  LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_2CYCLES_5);

  LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SINGLE_ENDED);

}

A ciało przerwania ADC tak:

void ADC1_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_IRQn 0 */

  /* USER CODE END ADC1_IRQn 0 */
  /* USER CODE BEGIN ADC1_IRQn 1 */

  /* USER CODE END ADC1_IRQn 1 */
}

Wstawiłem tylko wygenerowane fragmenty kodu, gdyż stwierdziłem że nie ma sensu wstawiać tu kodów wszystkich moich prób. Bardzo proszę o wskazanie mi, co mam gdzie wpisać, bądź jakich funkcji użyć, lub jeśli to nie problem napisać fragmenty uzupełniając powyższy kod, bo już sam nie wiem jak to mam zrobić. Za wszystkie odpowiedzi i pomoc bardzo dziękuję. 

Edytowano przez Treker
Poprawiłem formatowanie.
Link do komentarza
Share on other sites

@Protektor28, poprawiłem formatowanie Twojej wiadomości - "pokolorowałem" kody. Może teraz (gdy coś w nich widać) ktoś będzie wstanie Ci pomóc. Pamiętaj na przyszłość, aby kody programów umieszczać za pomocą narzędzia KOD (ikona <>). Dzięki niemu programy są odpowiednio formatowane i kolorowane 😉

  • Lubię! 1
Link do komentarza
Share on other sites

Dnia 6.11.2018 o 17:18, Protektor28 napisał:

Czołem, mam pewien problem. ...

A ciało przerwania ADC tak:


void ADC1_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_IRQn 0 */

  /* USER CODE END ADC1_IRQn 0 */
  /* USER CODE BEGIN ADC1_IRQn 1 */

  /* USER CODE END ADC1_IRQn 1 */
}

Wstawiłem tylko wygenerowane fragmenty kodu, gdyż stwierdziłem że nie ma sensu wstawiać tu kodów wszystkich moich prób. Bardzo proszę o wskazanie mi, co mam gdzie wpisać, bądź jakich funkcji użyć, lub jeśli to nie problem napisać fragmenty uzupełniając powyższy kod, bo już sam nie wiem jak to mam zrobić. Za wszystkie odpowiedzi i pomoc bardzo dziękuję. 

Cześć,

wklej kod, który miałeś w funkcji obsługi przerwania: ADC1_IRQHandler.

Pozdrawiam.

  • Lubię! 1
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

Witaj

Ostatnia wersja przerwania jaką zapisałem wygląda następująco:

uint32_t Sample;
void ADC1_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_IRQn 0 */
	LL_ADC_Enable(ADC1);
	Sample=LL_ADC_REG_ReadConversionData32 (ADC1);
  /* USER CODE END ADC1_IRQn 0 */
  /* USER CODE BEGIN ADC1_IRQn 1 */

  /* USER CODE END ADC1_IRQn 1 */
}

 

Link do komentarza
Share on other sites

Cześć,

a próbowałeś tak :

Deklaracja przed funkcją obsługi przerwania:

/* Variables for ADC conversion data */
__IO uint16_t uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE; /* ADC group regular conversion data */

A w funkcji obsługi przerwania:

 /* Init variable containing ADC conversion data */
    uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE;
    
    /* Perform ADC group regular conversion start, poll for conversion        */
    /* completion.                                                            */
    ConversionStartPoll_ADC_GrpRegular();
    
    /* Retrieve ADC conversion data */
    /* (data scale corresponds to ADC resolution: 12 bits) */
    uhADCxConvertedData = LL_ADC_REG_ReadConversionData12(ADC1);
    
    /* Update status variable of ADC unitary conversion */
    ubAdcGrpRegularUnitaryConvStatus = 1

Twój przetwornik ADC jest 12 bitowy. Nie wiem, czy to zadziała, ale można spróbować.

Pozdrawiam

Edytowano przez Treker
Poprawiłem formatowanie.
  • Lubię! 2
Link do komentarza
Share on other sites

właściwie w deklaracjach powinno być:

/* Init variable out of expected ADC conversion data range */
  #define VAR_CONVERTED_DATA_INIT_VALUE    (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)

/* Variables for ADC conversion data */
__IO uint16_t uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE; /* ADC group regular conversion data */ 

a potem:

4 minuty temu, Protektor28 napisał:

FlyingDutch, bardzo dziękuję za odpowiedź 

Nie wiem czy dobrze rozumiem, czym jest VAR_CONVERTED_DATA_INIT_VALUE oraz ubAdcGrpRegularUnitaryConvStatus = 1;  ?

Kompilator pokazuje, że nie są zadeklarowane

 

Właśnie pisałem odpowiedź, bo zrobiłem pomyłkę.

Spróbuj tylko podmienić:

uint16_t Sample;
void ADC1_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_IRQn 0 */
	LL_ADC_Enable(ADC1);
	Sample=LL_ADC_REG_ReadConversionData12(ADC1);
  /* USER CODE END ADC1_IRQn 0 */
  /* USER CODE BEGIN ADC1_IRQn 1 */

  /* USER CODE END ADC1_IRQn 1 */
}

 

 

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

FlyingDutch

Dnia 8.11.2018 o 17:57, FlyingDutch napisał:

właściwie w deklaracjach powinno być:


/* Init variable out of expected ADC conversion data range */
  #define VAR_CONVERTED_DATA_INIT_VALUE    (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)

/* Variables for ADC conversion data */
__IO uint16_t uhADCxConvertedData = VAR_CONVERTED_DATA_INIT_VALUE; /* ADC group regular conversion data */ 

a potem:

Właśnie pisałem odpowiedź, bo zrobiłem pomyłkę.

Spróbuj tylko podmienić:


uint16_t Sample;
void ADC1_IRQHandler(void)
{
  /* USER CODE BEGIN ADC1_IRQn 0 */
	LL_ADC_Enable(ADC1);
	Sample=LL_ADC_REG_ReadConversionData12(ADC1);
  /* USER CODE END ADC1_IRQn 0 */
  /* USER CODE BEGIN ADC1_IRQn 1 */

  /* USER CODE END ADC1_IRQn 1 */
}

 

 

Hej , wciąż wyskakuje, że  ubAdcGrpRegularUnitaryConvStatus jest niezadeklarowana, to ma być jakieś makro?  Również funkcja ConversionStartPoll_ADC_GrpRegular(); nie jest znana.

Dnia 9.11.2018 o 09:23, FlyingDutch napisał:

Hej,

 w "Keil uVision" jest sporo przykładów LL - miedzy innymi kilka dla ADC. Warto może byłoby zainstalować sobie Keil'a i skorzystać z tych przykładów.

Pozdrawiam

Mógłbyś powiedzieć co trzeba doinstalować do Keil, aby zobaczyć przykłady w LL? Nie mogę nic takiego znaleźć.

Edytowano przez Protektor28
Nieścisłość
Link do komentarza
Share on other sites

Cześć,

wybierasz z opcji Project -> Manage -> Pack Installer.

Keil_01.thumb.png.04fd25ae90541bcaf69c026d9c46e388.png

Jak "Pack Installer" się uruchomi to wybierasz z prawej strony producenta płytki i konkretną płytkę, W oknie po prawej wybierasz co chcesz zainstalować. Nie wiem tylko, czy dla licencji "trial" jest wszystko dostępne

.PackInstaller.thumb.png.925e50786d2b380553f259ebdab3eed8.png

Jest też chyba nawet więcej gotowych przykładów w darmowym programie: "STM32CubeMX" (z którego pewnie korzystasz) - musisz pobrać biblioteki HAL/LL dla twojej rodziny CPU i wtedy też masz bardzo dużo przykładów z wykorzystaniem tych bibliotek i to dla kilku IDE).

Pozdrawiam

Edytowano przez FlyingDutch
  • Lubię! 1
Link do komentarza
Share on other sites

1 godzinę temu, Protektor28 napisał:

Niestety w przypadku L452 uVision nie jest pomocne. Nie wiem wciąż, czym są zmienne w kodzie, który podałeś.

 

Cześć,

w pliku masz spakowane przykłady LL dla ADC dla płytki NucleoF411RE (bo akurat taką posiadam i dla niej ściągałem biblioteki CubeMX). Pewnie trzeba je trochę przerobić dla L452. Przykłady są z programu "STM32CubeMX" - w kalalogu (Win10 64 bit):

C:\Users\XXX_twoj_user\STM32Cube\Repository\STM32Cube_FW_F4_V1.21.0\Projects\STM32F411RE-Nucleo\Examples_LL\ADC

ADC.zip

Możesz je sam ściągnąć programem "STM32CubeMX" (jest w pełni darmowy).

Pozdrawiam

BTW: z Keilem niestety jest tak, że w zależności od posiadanej licencji zawartość może się różnić.

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.