关于中断和 计时寄存器的有关理论, 有兴趣的朋友可以看我一年前写的笔记 :“STM32F072RB 实作笔记(五)- 计时器加上中断EXTI_IRQHandler(一)” 和 “(二)” 两篇笔记。
这一篇笔记就直接解析实验的程式内容
main.c
和前几篇一样,进入“实验5 外部中断实验” 的 USER 资料夹点开 MDK 的项目档案。执行编译。
以下是 main.c 的内容:
#include "key.h"
#include "beep.h"
#include "usart.h"
#include "exti.h"
/************************************************/
int main(void)
{
Stm32_Clock_Init(9); //
delay_init(72); //
uart_init(72,115200);//
LED_Init(); //
BEEP_Init(); //
EXTIX_Init(); //设定 外部中断的操作方式
LED0=0; //设定 LED0 的初始值
while(1)
{
printf("OKn"); //输出到 SSCom 的程式上
delay_ms(1000);
}
}
我们看到 main.c 除了设定初始值以外,只执行了一个 “printf()” 和 “delay_ms” 就没有其他的动作了。这里有两个重点:
中断后的操作程式是在 exti.c 这个档案里(可以由EXTIX_Init() 取鼠标右键打开档案)
printf() 输出的 “OKn” 这个字串 会透过开发板的 USB 线, 呈现在电脑的 SSCom 程式上面(或是其他你熟悉的串口调试软件)。也可以自行修改 "OKn"的内容,看看输出的结果。SSCom 的操作,请看上一篇笔记 “STM32F103RB 实作笔记(六)- HC-05 蓝牙模组与手机 APP(正点原子 STM32F103 nano开发板)程式解析”
exti.c 程式解析
以下是exti.c 的内容
#include "exti.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
//
void EXTIX_Init(void)
{
KEY_Init();//
Ex_NVIC_Config(GPIO_C,8,FTIR); // 见下面说明
Ex_NVIC_Config(GPIO_C,9,FTIR); //
Ex_NVIC_Config(GPIO_D,2,FTIR); //
Ex_NVIC_Config(GPIO_A,0,RTIR); //
MY_NVIC_Init(2,2,EXTI0_IRQn,2); //见下面说明
MY_NVIC_Init(2,1,EXTI9_5_IRQn,2); //
MY_NVIC_Init(2,0,EXTI2_IRQn,2); //
}
//
void EXTI0_IRQHandler(void)
{
delay_ms(10); //
if(WK_UP==1) //KEY_UP
{
LED0=!LED0;
LED1=!LED1;
}
EXTI->PR=1<<0; //LINE0
}
//
void EXTI2_IRQHandler(void)
{
delay_ms(10); //
if(KEY2==0) //KEY2
{
BEEP=!BEEP;
}
EXTI->PR=1<<2; //LINE2
}
//
void EXTI9_5_IRQHandler(void)
{
delay_ms(10); //
if(KEY0==0) //KEY0
{
LED0=!LED0;
}
if(KEY1==0) //KEY1
{
LED1=!LED1;
}
EXTI->PR=1<<8; //LINE8
EXTI->PR=1<<9; //LINE9
}
exti.c 整个程式除了 include 之外,包含了下面四大部分。
void EXTIX_Init(void)
void EXTI0_IRQHandler(void)
void EXTI2_IRQHandler(void)
void EXTI9_5_IRQHandler(void)
我先说明 三个类似的 IRQHandler(void),
这三个IRQHandler(void) 是 INT 产生后 需要执行的程式入口 (Vectors)。从文件上可以看见 STM32f103 是把所有 GPIO 的同一bit 设一个 EXTI 线,从 EXTI0 到 EXTI5.
不过在记忆体的配置上却只是分成六个
EXTI0_IRQHandler ; EXTI Line 0
EXTI1_IRQHandler ; EXTI Line 1
EXTI2_IRQHandler ; EXTI Line 2
EXTI3_IRQHandler ; EXTI Line 3
EXTI4_IRQHandler ; EXTI Line 4
EXTI9_5_IRQHandler ; EXTI Line 9..15
实际的程式的定义是放在 startup_stm32f10x_md.s 这个档案。
在编写 RQHandler(void) 的时候,最重要的是在结束之前要把 IRQ 复位,使得程式可以接收下一个外部中断。
像这个样子:
void EXTI2_IRQHandler(void)
{
。。。
。。。
。
。
EXTI->PR=1<<2; //LINE2
}
解析 EXTIX_Init(void)
这个涵式里放了几个NVIC 的结构设定涵式,都是放在 sys.c 里,结果如下:
void EXTIX_Init(void)
{
KEY_Init();//
Ex_NVIC_Config(GPIO_C,8,FTIR); //见下面说明
Ex_NVIC_Config(GPIO_C,9,FTIR); //
Ex_NVIC_Config(GPIO_D,2,FTIR); //
Ex_NVIC_Config(GPIO_A,0,RTIR); //
MY_NVIC_Init(2,2,EXTI0_IRQn,2); //MY_NVIC_Init()见下面说明
MY_NVIC_Init(2,1,EXTI9_5_IRQn,2); //EXTI9_5_IRQn 见下面说明
MY_NVIC_Init(2,0,EXTI2_IRQn,2); //
}
第一个追查的是 Ex_NVIC_Config() 涵式,追查每一个定义如下:
//============== sys,c
void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM)
{
u8 EXTADDR;
u8 EXTOFFSET;
EXTADDR=BITx/4;//
EXTOFFSET=(BITx%4)*4;
RCC->APB2ENR|=0x01;//
AFIO->EXTICR[EXTADDR]&=~(0x000F< EXTI->IMR|=1< GPIO_x 的定义 //===========================sys.c //Ex_NVIC_Config #define GPIO_A 0 #define GPIO_B 1 #define GPIO_C 2 #define GPIO_D 3 #define GPIO_E 4 #define GPIO_F 5 #define GPIO_G 6 #define FTIR 1 // #define RTIR 2 // 以下是 AFIO 定义 第二个追查的是 MY_NVIC_Init() 涵式,追查每一个定义如下: //============== sys,c void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) { u32 temp; MY_NVIC_PriorityGroupConfig(NVIC_Group);// 见下面说明 temp=NVIC_PreemptionPriority<<(4-NVIC_Group); temp|=NVIC_SubPriority&(0x0f>>NVIC_Group); temp&=0xf;// NVIC->ISER[NVIC_Channel/32]|=(1< } 以下是 NVIC 定义 以下是 MY_NVIC_PriorityGroupConfig() 定义 //===========================sys.c void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group) { u32 temp,temp1; temp1=(~NVIC_Group)&0x07;// temp1<<=8; temp=SCB->AIRCR; // temp&=0X0000F8FF; // temp|=0X05FA0000; // temp|=temp1; SCB->AIRCR=temp; // SCB 见下面说明 } 以下是 SCB 定义 以下是 EXTIx_IRQn 定义 /****** STM32 specific Interrupt Numbers ******************************************/ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ TAMPER_IRQn = 2, /*!< Tamper Interrupt */ RTC_IRQn = 3, /*!< RTC global Interrupt */ FLASH_IRQn = 4, /*!< FLASH global Interrupt */ RCC_IRQn = 5, /*!< RCC global Interrupt */ EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */ DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */ DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */ DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */ DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */ DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */ DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ 以上是 程式的追踪结果,方便分析。
上一篇:STM32F103RB 实作笔记(八)- IWDG 内部看门狗试验
下一篇:十五年创新路:意法半导体举办首届STM32中国线上技术周
推荐阅读最新更新时间:2024-11-16 23:10
设计资源 培训 开发板 精华推荐
- 盖革计数器
- LTM4632EY 2 模块并联、3.6V 至 15V 输入、1.2V/6A VDDQ、0.6V/±6A VTT 和 10mA VTTR 设计的典型应用电路
- 基于LT6911C的6寸MIPI屏驱动板
- LT1170HVCT、12V/5A 负至正降压-升压转换器的典型应用
- OP482GPZ 低功耗、高速 JFET 运算放大器的典型应用电路
- 101020492, Grove - 3 轴数字罗盘 v2.0
- STM32F411 system1
- AD9119-CBLTX-EBZ,使用 AD9119 高性能、11 位、2.8 GSPS 射频数模转换器的评估板
- LB1838MEVB,基于 LB1838M 双向电机驱动器的评估板
- QZD电子羊