中断函数地址不固定 中断跳转只能到固定地址执行程序 跳转到不固定的中断函数,需要在内存中定义地址列表(中断向量表)。 中断发生后先跳转这个地址,再由编译器跳转中断函数。 实际中C由编译器操作,不用编程

相同的Pin不能同时触发中断 PA1,PB1,PC1;PA0,PB0;不行 外部中断9-5和15-10分到同一个端口,触发一个函数 根据标志位触发是哪个中断进入的

AFIO主要完成两个任务: 复用功能引脚重映射:把引脚默认复用功能重定义 中断引脚选择

请求挂起寄存器是标志位 可以读取判断是哪个通道触发的中断

NVIC:内核外设,需要参考Cortex-M3手册 注意:中断分组配置寄存器在SCB里:SCB_AIRCR

配置外部中断

  1. 配置GPIO,AFIO的RCC时钟(EXTI,NVIC时钟始终打开 NVIC为内核外设,内核外外设由RCC管理
  2. 配置GPIO为输入模式
  3. 配置AFIO选择用到的GPIO连到EXTI AFIO的库函数和GPIO一起
  4. 配置EXTI,选择边沿触发,响应方式
  5. 配置NVIC优先级

AFIO

void GPIO_AFIODeInit(void);//复位AFIO void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//锁定引脚参数 void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); void GPIO_EventOutputCmd(FunctionalState NewState);//配置AFIO事件输出功能 void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);//引脚重映射(重映射方式,重映射状态) void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//AFIO数据选择器,选择想要的中断引脚 void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);//以太网相关,本芯片没有

EXTI

每个外设基本都有的模板化函数 void EXTI_DeInit(void);//复位exti,清除配置,恢复成上电默认 void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//根据结构体里的参数初始化配置EXTI外设 void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);//给参数传递的结构体变量赋默认值 void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);//软件触发外部中断

关于状态寄存器和标志位的函数

  1. (一般)主程序内使用 FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);//获取指定标志位函数是否置一 void EXTI_ClearFlag(uint32_t EXTI_Line);//对置一标志位清除
  2. (一般)中断函数内使用,判断中断是否允许 ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);///获取中断标志位是否置一,返回set/reset void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除中断挂起标志位

EXTI只有一个,不用像GPIO一样指定AB。。

EXTI结构体参数 EXTI_InitStruct.EXTI_Line = EXTI_Line14;//要配置的中断线 EXTI_InitStruct.EXTI_LineCmd = ENABLE;//开启或关闭 EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式或事件模式 EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;//上升沿,下降沿,共同触发

NVIC

内核函数,库函数在杂项misc里 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);//中断分组(中断分组方式 ) void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);//设置中断向量表 void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);//系统低功耗配置 void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);

配置NVIC: 指定中断分组:芯片只分一组,一个工程只执行一次;注意模块里分组的话需要进行统一,不然最好在外面分 初始化

NVIC结构体参数 NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;//指定中断通道开启、关闭 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能或失能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//响应优先级 NVIC同时设置两路的话,结构体可重复使用,但要分别初始化

中断函数

一个中断通道对应一个中断函数, 可在中断向量表查询,在启动函数startup_stm32f10x_md.s里 以IRQHandler结尾的就是中断函数

函数名从向量表复制过来,创建子函数,但不用放到头文件,被其他文件调用,程序自动执行 内容: 中断标志位判断,确认中断源 执行 清除中断标志位:如果不清,程序一直跳到中断函数

调试能否进入中断: 调试模式在中断函数内设置断点, 触发外界中断条件,查看程序是否在断点暂停

旋转编码器

如果把一相下降沿作为读取另一相电平的标志可只初始化一个端口外部中断,但有瑕疵:正反转触发时间不同 采用方案:初始化两个端口外部中断 正转:B下降沿读A低电平 反转:A下降沿读B低电平 反过来是,边沿相反,电平不变

注意

  1. 不要在中断函数里太久
  2. 不要在中断调用主函数相同硬件 CPU会保护现场外部硬件不会

results matching ""

    No results matching ""