AnsweredAssumed Answered

Spurious EXTIO ISR (I cant Understand Why)

Question asked by slimsly on Feb 10, 2013
Latest reply on Feb 10, 2013 by slimsly
Hello,

I am relatively New to ARM Cortex Microcontroller but with experience in Microchip 8Bit to 32bits Microcontrollers. I am having a serous issue with configuring the external Interrupt of STM32F103RB. I want to Toggle two LED connected to PB8-PB9  in EXTI0 ISR [PA0]. I connect PA0 to TIM1 PWM CH4 PA11 (20KHz) Pin to trigger the External Interrupt on the Falling Edge of PA0.

After going through RM0008 Reference manual (Page 200 hardware interrupt selection), it has just 3 lines  explaining how to configure EXT Interrupt.I thought It will be easy but how wrong I was.Probing with Logic Analyzer, I noticed that the LED Toggle 435KHz in the EXTI0 ISR instead of the 20KHz that is triggering it.

I disconnect the wire that is connecting PA0 and PWM CH4 PA11 and view  the PWM and 2 LED in Logic Analyzer. The LED are in active High, the default state I set in my code (Please see attached Logic Analyzer Screen shot " No_Interrupt.jpg").I connect it back and the LED are toggling at 435KHz instead of the 20KHz (please see attached Logic Analyzer Screen shot " Interrupt_Connected.jpg).I do not want to use ST Peripherals library.

I have read the Datasheet so many times, perform all voodoo dance known to me but I still can't get it to work. I have the feeling I did not configure the Interrupt properly. I just can't figure out the missing piece.

Please I need help.

----Code---
#include "stm32f10x.h"

void PWM_init(void);
void Init_System(void);
void Init_ExtIO(void);

int main(void)
{

  Init_System();              //Initialize GPIOA-D & Peripherals
  PWM_init();                 //Initialize 20KHz PWM on CH 1-3
  Init_ExtIO();

    while(1)
      {

       }
}

void Init_System()
{
  RCC-> CFGR |= RCC_CFGR_ADCPRE_DIV4;     //ADC divided by 4
  /*Enable Alternate Function,GPIOA,GPIOB,GPIOC, GPIOD & TIMER1, ADC1 & ADC2 Clock Clock*/
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN |
                  RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_TIM1EN |
                  RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN;

  /*Enable TIMER2, TIMER3,I2C1  & USART2 Clock*/
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN |RCC_APB1ENR_I2C1EN |
                  RCC_APB1ENR_TIM4EN | RCC_APB1ENR_USART2EN;

  RCC->AHBENR = RCC_AHBENR_DMA1EN ;   //DMA1 clock enable

/*Partial Remap TIM1: CH1/PA8,CH2/PA9,CH3/PA10,CH4/PA11,CH1N/PA7,CH2N/PB0,CH3N/PB1
Remap USART1: TX/PB6, RXPB7*/
  AFIO->MAPR |= AFIO_MAPR_TIM1_REMAP_PARTIALREMAP | AFIO_MAPR_USART1_REMAP;

 //PA2, PA7 Alternate Function Push Pull Output | PA0 Input Floating
  GPIOA->CRL = 0xA4444B44;
  GPIOA->CRH = 0x4444AAAA;  //PA8 - PA11 Alternate Function Push Pull Output

  //PB0 & PB1 =>Alt Function Push Pull O/P | PB6-PB7 Alt Function Open Drain
  GPIOB->CRL = 0xFF4444AA;
  GPIOB->CRH = 0x44444422;    //Configure PB8 & PB9 as Output (Push Pull)
  GPIOB->ODR |= 0x00000300;        //Set GPIOB8 & GPIOB9
}

void PWM_init(void)
{

  TIM1->PSC = 0;            //Pre-Scale Value=>0
  TIM1->ARR = (2800 - 1);  // Auto reload value 2800 (Period = 50us)
  TIM1->CCR1 = 1000;       // Start PWM duty for channel 1
  TIM1->CCR2 = 800;        // Start PWM duty for channel 2
  TIM1->CCR3 = 600;       // Start PWM duty for channel 3
  TIM1->CCR4 = 1400;      //CH4 Compare Value

  TIM1->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 |  //CH1-3 PWM mode 1
                 TIM_CCMR1_OC2M_2 |TIM_CCMR1_OC2M_1;   //CH3-4 PWM mode 1

  TIM1->CCMR2 |= TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | //CH3 & CH4 is configured as output
                 TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;

  /* Channel 1-4 active high | CH1-4 O/P Compare Enable | CH1-3N O/P Enable*/
  TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E  | TIM_CCER_CC4E|
                TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE;

  TIM1->BDTR |= TIM_BDTR_MOE | TIM_BDTR_OSSR | TIM_BDTR_DTG_7; //Enable Main O/P & Enable OSSR
  TIM1->CR1 |= TIM_CR1_CEN | TIM_CR1_ARPE; //Enable Counter,Center Align Mode 1,Automatic Reload Enable

}

void Init_ExtIO(void)
{
  AFIO->EXTICR[0]|= AFIO_EXTICR1_EXTI0_PA; //Enable Ext Interrupt on PA0 pin
  EXTI->IMR |= EXTI_IMR_MR0;    //Interrupt Mask on line 0
  EXTI->FTSR |=EXTI_FTSR_TR0;   //Falling trigger Interrupt enabled
  NVIC_EnableIRQ(EXTI0_IRQn);     //Enable EXTIO Interrupt in NVIC
}

void EXTI0_IRQHandler(void)
{
  if(EXTI->PR & EXTI_PR_PR0)          // if CC4IF flag is set
    {
      EXTI->PR &= ~(EXTI_PR_PR0);     //Clear CC4IF Flag
      GPIOB->ODR ^= 0x00000300;        //Toggle GPIOB8 & GPIOB9
     }
}
-------Code---------------

Note: I use CooCox IDE and GNU 4.7 C Compiler

Regards
Slim

Attachments

Outcomes