Tengo que escribir un programa en C para alternar un LED usando una interrupción externa en STM32F103 (72MHz System Clock). He inicializado EXTI3 en el flanco descendente y el controlador de ISR alterna un led en la entrada de alta frecuencia en el pin de detección de interrupción externo; hay un retraso entre la detección y la ejecución de ISR (aproximadamente 2.6uSec, casi 188 pulsos de reloj del sistema). ¿De dónde viene este retraso?
Estoy adjuntando mi código, he verificado el reloj de mi microcontrolador al escribir el temporizador 1 PWM para una frecuencia específica (witch se calcula por la frecuencia de reloj de 72MHz).
Aquí está mi código:
#include "stm32f10x.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//LED PUTPUT
//JTAG-DP Disabled and SW-DP Disabled PA13, PA14, PA15 PB3 and PB4 Release from JTAG-DP/SW-DP module
//Reset default Value Reset value: 0x4444 4444(ALL INPUT ARE FLOATING) to 0x00000000 (General purpose output push-pull )
//01: Output mode, max speed 10 MHz.
//10: Output mode, max speed 2 MHz.
//11: Output mode, max speed 50 MHz.
#define LED_INIT() RCC->APB2ENR |=RCC_APB2ENR_IOPAEN|RCC_APB2ENR_IOPCEN;\
RCC->APB2ENR |=RCC_APB2ENR_AFIOEN;\
AFIO->MAPR |=AFIO_MAPR_SWJ_CFG_DISABLE;\
GPIOA->CRH &=~(GPIO_CRH_CNF13|GPIO_CRH_CNF14);\
GPIOA->CRH |=(GPIO_CRH_MODE13|GPIO_CRH_MODE14);\
GPIOA->ODR &=~(GPIO_ODR_ODR13|GPIO_ODR_ODR14);\
GPIOC->CRH &=~(GPIO_CRH_CNF13);\
GPIOC->CRH |=GPIO_CRH_MODE13;\
GPIOC->BSRR |=GPIO_BRR_BR13;//Set LED(active Low) BIT PC13 High
//GPIOC->ODR |=(1<<13);//PIN PC13 is High
#define LED0_ON() GPIOC->ODR |=GPIO_ODR_ODR13
#define LED0_OFF() GPIOC->ODR &=~GPIO_ODR_ODR13
#define LED1_ON() GPIOA->ODR |=GPIO_ODR_ODR13
#define LED1_OFF() GPIOA->ODR &=~GPIO_ODR_ODR13
#define LED2_ON() GPIOA->ODR |=GPIO_ODR_ODR14
#define LED2_OFF() GPIOA->ODR &=~GPIO_ODR_ODR14
#define LED0_TOGGLE() GPIOC->ODR ^=GPIO_ODR_ODR13
#define LED1_TOGGLE() GPIOA->ODR ^=GPIO_ODR_ODR13
#define LED2_TOGGLE() GPIOA->ODR ^=GPIO_ODR_ODR14
#define DEL 1000
void LED_SWITCH_INIT(void);
void interrupt_enable(void);
void Blink_LED(uint32_t del);
void delay(uint32_t del);
int main(void)
{
LED_SWITCH_INIT();
interrupt_enable();
while(1)
{
}
}
void LED_SWITCH_INIT(void){
RCC->APB2ENR |=RCC_APB2ENR_IOPBEN;//Clock Enable For Port B
RCC->APB2ENR |=RCC_APB2ENR_AFIOEN;
//LED PUTPUT
LED_INIT();
//SWITCH INPUT 176
AFIO->MAPR =AFIO_MAPR_SWJ_CFG_DISABLE; //TAG-DP Disabled and SW-DP Disabled
GPIOB->CRL &=~GPIO_CRL_CNF3;//|GPIO_CRL_CNF4|GPIO_CRL_CNF5|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
GPIOB->CRL |=GPIO_CRL_CNF3_1;//|GPIO_CRL_CNF4_1|GPIO_CRL_CNF5_1|GPIO_CRL_CNF6_1|GPIO_CRL_CNF7_1);
GPIOB->ODR |=GPIO_ODR_ODR3;//|GPIO_ODR_ODR4|GPIO_ODR_ODR5|GPIO_ODR_ODR6|GPIO_ODR_ODR7|GPIO_ODR_ODR8|GPIO_ODR_ODR9;//Pullup Enable
//AFIO->EVCR |=AFIO_EVCR_EVOE|AFIO_EVCR_PORT_0|AFIO_EVCR_PIN_PX3;
AFIO->EXTICR[0] |=AFIO_EXTICR1_EXTI3_PB; //Select EXT3 on PORTB for External interrupt3
//AFIO->EXTICR[1] |=AFIO_EXTICR2_EXTI5_PB;
EXTI->IMR |=EXTI_IMR_MR3;//|EXTI_IMR_MR19; // (0)Select PIN PB3/* Interrupt mask register (EXTI_IMR) */
//EXTI->IMR |=EXTI_IMR_MR5;
//EXTI->EMR |= EXTI_EMR_MR3;//|EXTI_EMR_MR19; ///* Event mask register (EXTI_EMR) */
EXTI->RTSR |=EXTI_RTSR_TR3; ////0: Rising trigger disabled (for Event and Interrupt) for input line
//EXTI->FTSR |=EXTI_FTSR_TR3; //1: Falling trigger enabled (for Event and Interrupt) for input line.
/* Falling trigger selection register (EXTI_FTSR) */
EXTI->FTSR |=EXTI_FTSR_TR3;
//EXTI->FTSR |=EXTI_FTSR_TR5;
/* Rising trigger selection register (EXTI_RTSR) */
//EXTI->RTSR |=EXTI_RTSR_TR5;
/* Pending register (EXTI_PR) */
EXTI->PR |=EXTI_PR_PR3; //Clear Interrupt Flag
//NVIC IRQ See Interrupt Enable faction */
//EXTI->SWIER |=EXTI_SWIER_SWIER3;
}
void interrupt_enable(void){
unsigned int priority = 0,Group=0;
NVIC_SetPriorityGrouping(Group);
/* bits[7:4] used for Group Priority
N/A used for Sub-Group Priority */
priority = NVIC_EncodePriority(Group,0,0);
/*0= Priority Grouping, 0= Group Priority, 0= Sub-Priority*/
NVIC_SetPriority(EXTI3_IRQn,priority);//Set new Priority
//NVIC_SetPriorityGrouping(NVIC_PriorityGroup_1);
NVIC_EnableIRQ(EXTI3_IRQn);
}
void EXTI3_IRQHandler(void){//
LED0_TOGGLE();
if ((EXTI->PR&EXTI_PR_PR3)) {
EXTI->PR |=EXTI_PR_PR3; //Clear the EXTI line 3 pending bit
}
}