Skocz do zawartości

Pomocna odpowiedź

Napisano

cześć

Używał ktoś z Was układu DWT do odmierzania us odcinków czasu.

Nie wiem dlaczego u mnie na STM32F103RB to nie chce pracować?

Kod znaleziony w sieci ale chyba kazdy go używa bo pojawia się zawsze po wpisany DWT delay

kod wygląda tak
 

/* Use DWT_Delay_Init (); and DWT_Delay_us (microseconds) in the main */

__STATIC_INLINE void DWT_Delay_us(volatile uint32_t microseconds)
{
  volatile uint32_t clk_cycle_start = DWT->CYCCNT;

  /* Go to number of cycles for system */
  microseconds *= ((SYSCLK_FREQ_72) / 1000000);

  /* Delay till end */
  while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}



uint32_t DWT_Delay_Init(void) {
  /* Disable TRC */
  CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
  /* Enable TRC */
  CoreDebug->DEMCR |=  CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;

  /* Disable clock cycle counter */
  DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
  /* Enable  clock cycle counter */
  DWT->CTRL |=  DWT_CTRL_CYCCNTENA_Msk; //0x00000001;

  /* Reset the clock cycle counter value */
  DWT->CYCCNT = 0;

     /* 3 NO OPERATION instructions */
  __ASM volatile ("NOP");
  __ASM volatile ("NOP");
  __ASM volatile ("NOP");

  /* Check if clock cycle counter has started */
     if(DWT->CYCCNT)
     {
       return 0; /*clock cycle counter started*/
     }
     else
  {
    return 1; /*clock cycle counter not started*/
  }
}

 

Możecie podpowiedzieć co może być nie tak?

 

 

Cześć,

też kiedyś natrafiłem na ten sam kod, co ty - on po prostu nie działa. Proponuję użyć jednego timera np. Timer1 aby odliczał mikrosekundy - wtedy funkcja opóźnienia us może wyglądać tak:

void delay_us (uint16_t us)
{
	__HAL_TIM_SET_COUNTER(&htim1,0);  // set the counter value a 0
	while (__HAL_TIM_GET_COUNTER(&htim1) < us);  // wait for the counter to reach the us input in the parameter
}

w pliku main.c musisz oczywiście zadeklarować zmienną:

TIM_HandleTypeDef htim1;

w funkcji main musisz wywołać:

  MX_TIM1_Init();

a następnie:

 HAL_TIM_Base_Start(&htim1);

funkcja konfiguracji timera1 wygląda tak:

static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 64-1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 65535-1;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */

}

Zwróć uwagę, że linia:

  htim1.Init.Prescaler = 64-1;

to wartość częstotliwości zegara w MHz -1 (u mnie zegar wynosił 64 Mhz). Teraz możesz wywoływać w programie np. dla opóźnienia 16  us:

delay_us(18);

Pozdrawiam

  • Lubię! 2

Dziękuję Ci bardzo,

Wiesz może co jest nie tak z tym kodem. Chciałbym po prostu dojść co tu jest nie tak, bo teoretycznie coś powinno ruszyć (DWT jest w f103)

5 godzin temu, vp32 napisał:

Dziękuję Ci bardzo,

Wiesz może co jest nie tak z tym kodem. Chciałbym po prostu dojść co tu jest nie tak, bo teoretycznie coś powinno ruszyć (DWT jest w f103)

Cześć,

nie doszedłem do tego, szkoda mi było czasu. Jak tobie udałoby się dojść co jest nie tak to opisz to w tym wątku - pewnie komuś się przyda.

Pozdrawiam

(edytowany)

A testowaliście rozwiązanie ze StackOverflow? Ktoś napisał, że w jego przypadku pomogło umieszczenie zapisu do jeszcze jednego rejestru, co odblokowało możliwość zapisu do pozostałych rejestrów DWT:

DWT->LAR = 0xC5ACCE55;

Może warto sprawdzić?

Edytowano przez piotr96
  • Lubię! 2
(edytowany)

Poszukam i popytam na zagranicznych forach.

Dam znać co i jak.

 

PS. czytałem to, ale tam było wyraźnie podane że to instrukcja odblokowuje dostęp ale dotyczy tylko F4, a w stm32103 nie ma tego rejestru.

Zresztą u mnie coś w tym rejestrze DWT->CYCCNT coś sie dzieje, ale blokuje się

Edytowano przez vp32

PS do powyższych wpisów.

Bardzo Was proszę sprawdźcie ten załączony na górze kod, wiem po wgraniu to nie chce działać. u mnie jst tak samo, ALE

jak zresetuje ręcznie STMa (przycisk reset na nucleo) to działa normalnie.

wychodzi na to że stlink blokuje dostęp do pewnych peryferiów ale po wgraniu kodu nawet jak nie jest w trybie debuggera to nie zwalnia pewnych zasobów.

Jeszcze nie umiem tego naprawić, wiem że w jakimś rejestrze można to poprawić, jakby ktoś wiedział?

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