Forum: Mikrocontroller und Digitale Elektronik externer Interrupt STM32F4


von Ma B. (drumstick)


Lesenswert?

Guten Tag.

Ich habe einen Motor mit Drehgeber. jetzt möchte ich die Pulse zählen, 
die er "zurücklegt". ich habe die Leitung des Drehgebers an den Pin PD13 
geführt. Im Datenblatt vom Motor steht:

6 Impulse pro Umdrehung - Pullup Spannung max. 6VDC - open drain

So habe ich den Pin entsprechen initialisiert:
1
  GPIO_InitTypeDef GPIO_InitStructurePB;
2
  GPIO_InitTypeDef GPIO_InitStructure;
3
//  
4
  EXTI_InitTypeDef   EXTI_InitStructure;
5
  NVIC_InitTypeDef   NVIC_InitStructure;
6
  
7
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);  // Enable the Clock for Port D
8
9
// Configure PD.13 FG -------------------------
10
  GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_13;
11
  GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_IN;
12
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
13
  GPIO_InitStructure.GPIO_PuPd   =  GPIO_PuPd_UP; 
14
  GPIO_Init(GPIOD, &GPIO_InitStructure);
15
16
  EXTI_InitStructure.EXTI_Line     = EXTI_Line13;                    // External Interrupt on Line 5   
17
  EXTI_InitStructure.EXTI_Mode     = EXTI_Mode_Interrupt;            // Set the Interrupt Mode         
18
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;    // Set the Interrupt trigger Mode 
19
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;                         // Enabele the Interrupt Line     
20
  EXTI_Init(&EXTI_InitStructure);
21
  
22
  NVIC_InitStructure.NVIC_IRQChannel                     = EXTI15_10_IRQn;
23
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority   = 0x0F;
24
  NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 0x0F;
25
  NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;
26
  NVIC_Init(&NVIC_InitStructure);
27
  NVIC_EnableIRQ(EXTI15_10_IRQn);

Der Interrupt Handler sieht dann so aus:
1
void EXTI15_10_IRQHandler(void)
2
{
3
  int cnt = 0; 
4
  cnt = get_Mot_FG_CNT();
5
  set_Mot_FG_CNT(cnt++);
6
  EXTI_ClearITPendingBit(EXTI_Line13); 
7
}

Das seltsame ist, der Interrupt Handler wird auch ausgeführt, wenn ich 
gar nichts am Pin angeschlossen habe. Auch dann wenn ich den Enable gar 
nie freigebe.

Das andere Problem ist, dass ich gar keine Pulse am Drehgeber habe. Kann 
es sein, dass der Interne Pullup ca. 40kOhm zu klein ist? Habe 
zusätzlich einen 50kOhm vom Pin auf 3.3V geschlossen, funktionierte 
ebenfalls nicht.

Ich habe sonst niergends Interrupts auch der Pin PD13 ist auf dem 
MCBSTM32F400er Board nicht andersweitig belegt.

Vielleicht hat jemand von euch eine Idee?

Vielen Dank und Grüsse

MC Bu

von Kris (Gast)


Lesenswert?

Zu deinem Interrupt-Problem: wäre möglich, dass einer der anderen Pins 
dafür verantwortlich ist, der Interrupt-Handler den du benutzt ist ja 
für mehrere zuständig. Weiß ja nicht, was du sonst noch so angeschlossen 
hast?

Aber mal was anderes: warum benutzt du nicht einfach einen Timer im 
Encoder-Modus, zum Beispiel mit den Pins PA0 und PA1? Mit den 
Bibliotheken von Uwe 
(http://mikrocontroller.bplaced.net/wordpress/?page_id=2140) sehr leicht 
einzurichten und funktioniert dann auch wunderbar, so brauchst du gar 
nicht mehr manuell zu zählen...

von Ma B. (drumstick)


Lesenswert?

Hallo

Dank für den guten Hinweis.

Hab das mit dem Encoder Mode versucht. Das Problem ist, dass der CNT 
Wert nur entweder 0 oder den Autoreloadwert enthält. Ist der 
Autoreloadwert 0, wechselt der CNT Wert zwischen 0 und 1.

Timer 4 Init:
1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
2
    
3
  TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
4
  
5
  TIM_SetAutoreload      (TIM4, 0xFFF);
6
            
7
  TIM_Cmd(TIM4, ENABLE);

GPIOs
1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
2
3
// Configure PD.13 for encoder mode timer 4 Channel 2 CHA -------------------------
4
  GPIO_InitStructure.GPIO_Pin      = GPIO_Pin_13;
5
  GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_AF;
6
  GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
7
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
8
  GPIO_InitStructure.GPIO_PuPd     =  GPIO_PuPd_UP; 
9
  GPIO_Init(GPIOD, &GPIO_InitStructure);
10
  
11
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
12
  
13
  // Configure PD.14 for encoder mode timer 4 Channel 3 CHB -------------------------
14
  GPIO_InitStructure.GPIO_Pin      = GPIO_Pin_14;
15
  GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_AF;
16
  GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
17
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
18
  GPIO_InitStructure.GPIO_PuPd     =  GPIO_PuPd_UP; 
19
  GPIO_Init(GPIOD, &GPIO_InitStructure);
20
  
21
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);

Vielen Dank und freundliche Grüsse

MC Bu

von Ma B. (drumstick)


Lesenswert?

Das Bit DIR im Register CR1 toggelt zwischen 0 und 1, das bedeutet, das 
der Zähler aufwärts zählt und dann wieder abwärts. Dies würde ja so 
stimmen.

Hab ich dann da was falsch verstanden? Ich bin der Meinung, das im CNT 
Register jeder einzelne Zählwert erfasst werden müsste, damit ich ja die 
einzelnen Impulse, die der Motor zurückgelegt hat erfassen kann!?

Danke und Gruss

MC Bu

von Uwe B. (derexponent)


Lesenswert?

ließ das Datenblatt vom STM32F4 nochmal durch

im Encoder-Mode kann nur CH1 und CH2 benutzt werden
(du benutzt CH2 und CH3)

und im Encoder-Mode muss an beiden Pins
ein um 90° Phasenversetztes Signal anliegen

wenn du aber nur eine Signal-Leitung hast,
wird das so nichts
(ich vermute er zählt immmer +1, -1 , +1, -1 usw)

Gruss Uwe

von Ma B. (drumstick)


Lesenswert?

Danke für den Hinweis...

ich benutze jetzt PD12 und PD13 / CHN1 und CHN2 von Timer 4.

Mit dem KO mess ich ja die Signale, die sind 90° verschoben.

Der Effekt bleibt allerdings der gleiche, leider.

Danke und Gruss

MC Bu

von Ma B. (drumstick)


Lesenswert?

Jetzt passts, Fehler beim Pin initialisieren.

Super vielen Dank für die Hilfe!

Grüsse

MC Bu

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.