2017-07-12 132 views
-1

我在使用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

+0

您無法重新映射STM32上的引腳。您必須使用要使用的外設的引腳連接到內部。 – Olaf

+0

@Olaf當然你可以,但選擇是有限的。在舊版本(如F1xx)中,通過重新映射redisters來完成,在更現代的版本中,通過設置正確的AF模式(並且通常有多個引腳可供選擇) –

+0

@PeterJ:OP所要求的重新映射意味着GPIO功能和所有其他外設功能進行了重新映射,這明顯不被STM32系列支持。 AF僅僅是某個GPIO引腳不同外設功能的選擇器。當然,**不同的GPIO上可能有相同的外設功能。 – Olaf

回答

0

我終於通過使用解決了這個問題代替:

AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0; // JTAG-DP Disabled, SW-DP Enabled 
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1; //     " 
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2; //     " 

根據p。參考手冊(RM0008)中的176,我正在設置正確的寄存器。雖然沒有找出差異。 也許你只能設置一個位。雖然沒有意義,因爲我試圖像這樣設置CFG_1:

AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1; 
0

我有同樣的問題。我的SPL實現:

引腳初始化和重映射

GPIO_InitTypeDef gpio_cfg; 
GPIO_StructInit(&gpio_cfg); 

/* Каналы 1 и 2 таймера TIM3 - на вход, подтянуть к питанию */ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB 
| RCC_APB2Periph_AFIO, ENABLE); 

gpio_cfg.GPIO_Mode = GPIO_Mode_IPU; 
gpio_cfg.GPIO_Pin = GPIO_Pin_15; 
GPIO_Init(GPIOA, &gpio_cfg); 

gpio_cfg.GPIO_Mode = GPIO_Mode_IPU; 
gpio_cfg.GPIO_Pin = GPIO_Pin_3; 
GPIO_Init(GPIOB, &gpio_cfg); 

GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); 

要使用重新映射的引腳和SWD調試:

AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // JTAG-DP Disabled, SW-DP Enabled 

GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE); 
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
+0

我看到了,但我沒有使用SPL,我正在使用低級寄存器編程。似乎我們的工作幾乎相同:在重新映射引腳之前禁用JTAG。 – Kyosanim