Hallo Ich möchte bei einem STM32F407 eine Frequenz bei PA2 messen. Dazu nehme ich den Timer5. Mit dem Capture Compare müsste das doch gehen oder was mache ich falsch? TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); // GPIOB clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); // Connect TIM pin to AF2 GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5); NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8; TIM_ICInitStructure.TIM_ICFilter = 0x2; TIM_PWMIConfig(TIM5, &TIM_ICInitStructure); TIM_SelectInputTrigger(TIM5, TIM_TS_TI2FP2); Oder geht das bei PA2 nicht? Ich habe einen externen Encoder bei PA2 (Spur A) und PA3 (Spur B) angeschlossen, davon möchte ich die Geschwindigkeit messen.. Danke
Mach Fax schrieb: > Oder geht das bei PA2 nicht? Das geht, Du darfst PA2 allerdings nicht als Ausgang konfigurieren! Ich habe ein Beispiel für T9 an PE5 und ein bißchen Schnickschnack drum herum: Beitrag "reziproker Frequenzzähler mit STM32F4Discovery" Die init_t9() kann man ja auf t5 ändern.
Hallo
Ich habe Deine Initialisierung übernommen, jedoch leider immer noch ohne
Erfolg. Was ist denn daran falsch, ich finde den Fehler einfach nicht:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); // Timer5
aktivieren
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // PortA
aktivieren
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// PA5 und PA6 als capture-input zu T5
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM5);
NVIC_EnableIRQ(TIM5_IRQn); // Int-T9 aktivieren
NVIC_SetPriority(TIM5_IRQn,14); // sehr hohe Priorität
TIM5->CCMR1 = TIM_CCMR2_CC3S_0 + TIM_CCMR2_CC3S_1; // capture
zuordnung IC1 -> TI1
TIM5->CCER = TIM_CCER_CC3E; // capture freigeben
TIM5->CCMR1 |= TIM_ICPSC_DIV8; // Vorteiler /8 aktivieren
TIM5->DIER |= TIM_DIER_CC1IE + TIM_DIER_UIE; // mit interrupts
TIM5->CR1 |= TIM_CR1_CEN; // T5 starten
Danke
> RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); // Timer5
^ ^
| |
Schau mal GENAU hin.
Das wird noch ein echter Klassiker werden;)
holger schrieb: >> RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); // Timer5 > ^ ^ > | | > > Schau mal GENAU hin. Meckert da nicht schon der Compiler? Aber immerhin hast Du einen Blick für diesen Kopierkram :-) Längere Quelltexte der STM (u.a.) sind ja fast nicht mehr lesbar, da sich gleiche Befehlssequenzen immer wiederholen, sich dann aber doch in nur einem Zeichen unterscheiden. Mach Fax schrieb: > Ich habe Deine Initialisierung übernommen, jedoch leider immer noch ohne > Erfolg. Du hättest auch TIM9 auf PA2+PA3 legen können, um erst einmal einen Erfolg zu haben, aber jetzt sollte es bei Dir auch so funktionieren.
m.n. schrieb: > Du hättest auch TIM9 auf PA2+PA3 legen können, um erst einmal einen > Erfolg zu haben, aber jetzt sollte es bei Dir auch so funktionieren. Nein kann ich leider nicht, da Timer9 schon benutzt wird, aber Danke habe ich am späteren Abend übersehen... Werde ich ausprobieren und danach ein Feedback geben. Danke & Gruss
Ich habe das jetzt mit dem TimerLib gemacht, jedoch funktioniert da
immer noch etwas nicht wie gewünscht, sprich es wird kein Interrupt
ausgelöst bei Flanken auf PA2. Das kann doch nicht so schwierig sein,
hat niemand eine Lösung dazu?
void EncoderSyncConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // PortA
aktivieren
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL;
//GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL;
//GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/////////////////////////////////////////
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5);
//GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM5);
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Control
with dead zone.
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
//Counter direction
TIM_TimeBaseInitStructure.TIM_Prescaler = 10;// 84-1; //Timer clock
= sysclock /(TIM_Prescaler+1) = 2M
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//TIM_ICSelection_IndirectTI
TIM_ICInit(TIM5,&TIM_ICInitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x05;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_SetPriority(TIM5_IRQn,14); // sehr hohe Priorität
NVIC_EnableIRQ(TIM5_IRQn); // Int-T9 aktivieren
TIM_ITConfig(TIM5, TIM_IT_CC3, ENABLE);
TIM_Cmd(TIM5,ENABLE);
}
Mach Fax schrieb: > GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5); Dazu fehlt (mindestens) der Init-Aufruf.
So, es funktioniert jetzt (Code unten)
Was aber noch nicht geht, ist dass bei einer positiven Flanke auf PA3
der Timer automatisch wieder auf 0 gestellt wird, jetzt wird der
Interrupt ausgelöst, ich kann den Capture Wert auslesen in der IRQ
Routine aber der Timer zählt munter weiter und bei der nächsten
positiven Flanke habe ich den alten TimerStand plus den neuen im
Register. Es sollte laut Library mit diesen beiden Zeilen eigentlich den
Timer bei einer Flanke von extern zurücksetzen, oder was fehlt da noch?
TIM_SelectInputTrigger(TIM5, TIM_TS_ETRF);
TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset);
Danke
void EncoderSyncConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//Activate PortA
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Activate the Timer5
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
//connect the Timer5 to the Sync Encoder PINs
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM5);
//configure the Counter
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//without ClockDivision
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
//Counter direction Up
TIM_TimeBaseInitStructure.TIM_Prescaler = 1; //Timer
clock = sysclock /(TIM_Prescaler+1) = 2M
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInitStructure.TIM_Period = 0xFFFFFFFF;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//TIM_ICSelection_IndirectTI
TIM_ICInit(TIM5,&TIM_ICInitStructure);
//Enable the TIM5 CC3 Interrupt Request
TIM_ITConfig(TIM5, TIM_IT_CC3, ENABLE);
//TIM enable counter
TIM_Cmd(TIM5, ENABLE);
TIM_SelectInputTrigger(TIM5, TIM_TS_ETRF);
TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM5, TIM_MasterSlaveMode_Enable);
}
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.