我在使用STM32F103C8T6上的Timer2作爲四路增量編碼器的接口時遇到問題。 我無法讓程序進入IRQHandler並切換LED。編碼器接口模式下STM32F103上的Timer2問題
我做了幾乎相同的Timer4的初始化工作正常。所以問題是,初始化定時器2時我做錯了什麼?
不言而喻;我已經檢查了接線。
請注意,我需要重新映射PA0到PA15和PA1到PB3。據我可以從ST參考手冊中知道,我需要在AFIO寄存器中執行此操作。另外我需要禁用JTDI和JTDO才能釋放PA15和PB3。我是否正確?
的代碼如下:
/*------------------------------------------------------------------------------------
MACROS
------------------------------------------------------------------------------------*/
#define GEARRATIO 9.68
#define ENCODERRESOLUTION 48
#define COUNTSPERREV GEARRATIO*ENCODERRESOLUTION // 9.68*48 = 465
/*------------------------------------------------------------------------------------
PREPROCESSOR
------------------------------------------------------------------------------------*/
#include <stm32f103xb.h>
#include "Timer2.h"
#include "IO.h"
/*------------------------------------------------------------------------------
Timer2 init (Encoder interface mode)
*------------------------------------------------------------------------------*/
void Timer2_init_Encoder(void)
{ /* Explain function here */
/* GPIO setup */
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Enable clock
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // Enable clock
AFIO->MAPR |= (AFIO_MAPR_SWJ_CFG & 0b100); // Disable JTAG-DP and SW_DP to release PA15 and PB3
AFIO->MAPR |= (AFIO_MAPR_TIM2_REMAP & 0b01); // Remap PA0->PA15, PA1->PB3 (needs to be 5V tol.)
// PA15 (Timer 2 Input CH1)
GPIOA->CRH |= (GPIO_CRH_CNF15 & 0b01); // 01 => Floating input (default)
GPIOA->CRH &= ~GPIO_CRH_MODE15; // 00 => Input mode (default)
// PB3 (Timer 2 Input CH2)
GPIOB->CRL |= (GPIO_CRL_CNF3 & 0b01); // 01 => Floating input (default)
GPIOB->CRL &= ~GPIO_CRL_MODE3; // 00 => Input mode (default)
/* Timer setup */
// Clock
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable clock
TIM2->SMCR |= TIM_SMCR_SMS & 0b011; //011 => Encoder mode 3. Count on both TI1 and TI2 edges (gives 48 CPR)
// Timebase unit
TIM2->ARR = COUNTSPERREV - 1; // CNT counts to this value and restarts
TIM2->RCR = 0x0000; // set repetition counter
TIM2->CNT = 0; // Set initial counter value (optional)
// Control Register
TIM2->CR1 |= TIM_CR1_URS; // 1 => ONLY overflow/underflow generates interrupt
TIM2->CR1 |= TIM_CR1_ARPE; // 1 => ARR is updated at each UEV
TIM2->CR1 &= ~TIM_CR1_UDIS; // 0 => Update Event (UEV) is generated at each overflow/underflow
TIM2->CCMR1 |= TIM_CCMR1_CC1S & 0b01; // 01 => CC1 Channel is configured as input
TIM2->CCMR1 |= TIM_CCMR1_CC2S & 0b01; // 01 => CC2 Channel is configured as input
TIM2->CCMR1 &= ~TIM_CCMR1_IC1F; // 0000 => No Input Capture filter
TIM2->CCMR1 &= ~TIM_CCMR1_IC2F; // 0000 => No Input Capture filter
TIM2->CCER &= ~TIM_CCER_CC1P; // 0 => Rising edge
TIM2->CCER &= ~TIM_CCER_CC2P; // 0 => Rising edge
// Interrupts
TIM2->DIER |= TIM_DIER_UIE; // DMA/Interrupt Register: Update Interrupt Enabled
NVIC->ISER[0] |= (1 << (TIM2_IRQn & 0x1F)); // enable interrupt globally
TIM2->CR1 |= TIM_CR1_CEN; // enable timer (counter begins one clock-cycle after enabling)
}
/*------------------------------------------------------------------------------
Timer2 Update Interrupt Handler
*------------------------------------------------------------------------------*/
void TIM2_IRQHandler(void)
{
if ((TIM2->SR & TIM_SR_UIF) == 1)
{
IO_LED_Toggle();
TIM2->SR &= ~TIM_SR_UIF; // clear UIF flag
}
}
希望你們可以幫忙。
問候, 的Mikkel
您無法重新映射STM32上的引腳。您必須使用要使用的外設的引腳連接到內部。 – Olaf
@Olaf當然你可以,但選擇是有限的。在舊版本(如F1xx)中,通過重新映射redisters來完成,在更現代的版本中,通過設置正確的AF模式(並且通常有多個引腳可供選擇) –
@PeterJ:OP所要求的重新映射意味着GPIO功能和所有其他外設功能進行了重新映射,這明顯不被STM32系列支持。 AF僅僅是某個GPIO引腳不同外設功能的選擇器。當然,**不同的GPIO上可能有相同的外設功能。 – Olaf