Forum: Mikrocontroller und Digitale Elektronik STM32 HAL Encoder Init Trouble


von technikus (Gast)


Lesenswert?

Hallo Forum!

Ausgangssituation:
Controller STM32F103.

Ich nutze die STM32 HAL Lib und möchte einen Encoder auswerten.
Der Timer zählt einfach drauf los (CNT Register) ohne das der Encoder 
gedreht wird.
Das hat mich dazu veranlasst einen Blick ins Reference Manual zu werfen 
und den Debugger anzuwerfen. Da ich gerade neu in der STM32 Welt bin, 
bin ich ein wenig erschlagen und bitte um Unterstützung.

TIM1_SMCR Nach Aufruf von

1
HAL_TIM_Encoder_Init(&htim1, &sConfig);

steht in TIM1_SMCR immer 0

Hier die HAL Encoder Init Funktion
1
HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef* sConfig)
2
{
3
  uint32_t tmpsmcr = 0U;
4
  uint32_t tmpccmr1 = 0U;
5
  uint32_t tmpccer = 0U;
6
7
  /* Check the TIM handle allocation */
8
  if(htim == NULL)
9
  {
10
    return HAL_ERROR;
11
  }
12
13
  /* Check the parameters */
14
  assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
15
  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
16
  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
17
  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
18
  assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode));
19
  assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection));
20
  assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection));
21
  assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
22
  assert_param(IS_TIM_IC_POLARITY(sConfig->IC2Polarity));
23
  assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
24
  assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler));
25
  assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
26
  assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter));
27
28
  if(htim->State == HAL_TIM_STATE_RESET)
29
  {
30
    /* Allocate lock resource and initialize it */
31
    htim->Lock = HAL_UNLOCKED;
32
    
33
    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
34
    HAL_TIM_Encoder_MspInit(htim);
35
  }
36
37
  /* Set the TIM state */
38
  htim->State= HAL_TIM_STATE_BUSY;
39
40
  /* Reset the SMS bits */
41
  htim->Instance->SMCR &= ~TIM_SMCR_SMS;
42
43
  /* Configure the Time base in the Encoder Mode */
44
  TIM_Base_SetConfig(htim->Instance, &htim->Init);
45
46
  /* Get the TIMx SMCR register value */
47
  tmpsmcr = htim->Instance->SMCR;
48
49
  /* Get the TIMx CCMR1 register value */
50
  tmpccmr1 = htim->Instance->CCMR1;
51
52
  /* Get the TIMx CCER register value */
53
  tmpccer = htim->Instance->CCER;
54
55
  /* Set the encoder Mode */
56
  tmpsmcr |= sConfig->EncoderMode;
57
58
  /* Select the Capture Compare 1 and the Capture Compare 2 as input */
59
  tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);
60
  tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U));
61
62
  /* Set the the Capture Compare 1 and the Capture Compare 2 prescalers and filters */
63
  tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC);
64
  tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F);
65
  tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U);
66
  tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U);
67
68
  /* Set the TI1 and the TI2 Polarities */
69
  tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
70
  tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP);
71
  tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U);
72
73
  /* Write to TIMx SMCR */
74
  htim->Instance->SMCR = tmpsmcr;
75
  /* Write to TIMx CCMR1 */
76
  htim->Instance->CCMR1 = tmpccmr1;
77
78
  /* Write to TIMx CCER */
79
  htim->Instance->CCER = tmpccer;
80
81
  /* Initialize the TIM state*/
82
  htim->State= HAL_TIM_STATE_READY;
83
84
  return HAL_OK;
85
}

Auch ein Ändern von
1
htim->Instance->SMCR = tmpsmcr;

nach
1
htim->Instance->SMCR = 3;

schafft keine Abhilfe. Daraufhin habe ich mir den Wert von tmpsmcr im 
Debugger angeschaut. Hier steht eine 3 drin, so soll es lt. Ref Manual 
sein.
Siehe da, auch die anderen Registerwerte werden nicht übernommen.


Ich habe, als blutiger Einsteiger, wohl Tomaten auf den Augen...
Was läuft in der HAL Encoder Init Funktion falsch?



Danke und Gruß

von Carl D. (jcw2)


Lesenswert?

So was ähnliches gab ich vor ein paar Wochen auch gemacht. Allerdings 
mit direkten Registerzugriff, was aber keinen Unterschied machen sollte.
Was aber wichtig ist, ist den Timer vorher mit Takt zu versorgen. 
Sonst nimmt er nichtmal die Werte an, die man per Debugger in die 
Register schreibt.

Edit:

__HALL_RCC_TIM1_CLK_ENABLE();

sollte helfen

von technikus (Gast)


Lesenswert?

Danke - gelöst

von Carl D. (jcw2)


Lesenswert?

Wie gesagt, ich hab nur 3Wochen Vorsprung ;-)

Wenn dein Debugger das erlaubt, kann man übrigens vieles auch live 
ausprobieren, d.h. Register ändern, so daß man nicht für jeden Versuch 
den Compiler braucht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.