• STM32中断和外部中断


     

    NVIC:嵌套中断向量控制器:用于统一分配中断优先级和管理中断

    响应式优先级:也可以称为插队式优先级哪个优先级高优先处理哪个

    抢占式优先级:优先级高的可以优先被处理,相当于CPU可以暂时中断当前处理的程序,优先处理优先级更高的程序,该程序执行完成后再执行原先没有执行完毕的程序,也可以称之为嵌入式中断优先级

    AFIO中断引脚选择:是一个中断引脚选择器可以在前面GPIO外设的16个引脚中选择一个连接到EXTI边沿检测及控制中所以

    相同的Pin不能同时触发中断,因为PA0,PB0,PC0通过AFIO选择后只有其中一个可以连接到EXTI的通道0上,PB1,PC1等也只有一个可以接入EXTI上

    模拟电子技术与或门基础

    旋转编码器讲解

    旋转编码器的硬件电路

    外部中断寄存器代码

    1:接线

    1. #include "stm32f10x.h" // Device header
    2. // 编写初始化函数--->模块化的第一步是编写初始化函数
    3. void CountSersor_Init(void){
    4. /*
    5. 外部中断配置
    6. 1: 配置RCC进涉及的外部中断时钟全部打开
    7. 2:配置GPIO选择端口为输入模式
    8. 3: 配置AFIO选择需要使用到的GPIO并连接后面的exit
    9. 4:配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式
    10. 5:配置NVIC给中断选择一个合适的优先级
    11. */
    12. }

    AFIO相关函数


                 用于复位AFIO外设,调用这个函数会清除AFIO外设
                 void GPIO_AFIODeInit(void);
                 用于锁定GPIO配置调用这个函数参数指定某个引脚,锁定引脚配置防止意外更改
                 void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
                 以下的两个函数是用于配置AFIO的事件输出功能
               void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
               void GPIO_EventOutputCmd(FunctionalState NewState);

                 这个函数可以用作引脚重映射,第一个参数是重映射的方式,第二个参数是新的状态
                 void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
              
      这个函数外部中断需要使用到的函数,调用这个函数可以选择我们的中断引脚
           void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
                 和以太网相关外设暂时没有使用到
                 void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

    EXTI相关函数

    NVIC配置

    编写中断函数代码实现当遮挡传感器时oled显示屏中的数字加1

    中断函数代码

    1. #include "stm32f10x.h" // Device header
    2. uint16_t CountSensor_Count;
    3. // 编写初始化函数--->模块化的第一步是编写初始化函数
    4. void CountSersor_Init(void){
    5. //1------>todo : 配置RCC进涉及的外部中断时钟全部打开
    6. // 开启GPIOB的时钟
    7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    8. // 开启AFIO的时钟
    9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    10. // EXPI和NVIC的时钟一直处于打开状态不需要我们手动开启
    11. //2------>todo : 配置GPIO选择端口为输入模式
    12. GPIO_InitTypeDef GPIO_InitStructure;
    13. // 引出结构体模式
    14. GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU ; // 配置模式
    15. GPIO_InitStructure.GPIO_Pin =GPIO_Pin_14 ;
    16. GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
    17. // 调用GPIO初始化函数,初始GPIOB
    18. GPIO_Init(GPIOB,&GPIO_InitStructure);
    19. // 3:todo -------> 配置AFIO选择需要使用到的GPIO并连接后面的exit
    20. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
    21. // 3:todo ------->配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式
    22. EXTI_InitTypeDef Exit_InitStruct;
    23. // 引出结构体成员
    24. Exit_InitStruct.EXTI_Line =EXTI_Line14; // 指定需要配置的中断线
    25. Exit_InitStruct.EXTI_LineCmd =ENABLE; // 开启中断
    26. Exit_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 模式:中断模式
    27. Exit_InitStruct.EXTI_Trigger =EXTI_Trigger_Falling ;// 下降沿触发
    28. EXTI_Init(&Exit_InitStruct);
    29. // 选择中断分组函数
    30. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    31. NVIC_InitTypeDef NVIC_Initstructure;
    32. NVIC_Initstructure.NVIC_IRQChannel = EXTI15_10_IRQn;
    33. NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE;
    34. NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 1;
    35. NVIC_Initstructure.NVIC_IRQChannelSubPriority = 1;
    36. NVIC_Init(&NVIC_Initstructure);
    37. }
    38. uint16_t CountSensor_Get(void){
    39. return CountSensor_Count;
    40. }
    41. void EXTI15_10_IRQHandler(void){
    42. if(EXTI_GetITStatus(EXTI_Line14) == SET){
    43. CountSensor_Count++;
    44. // 中断程序结束后一定要清除中断程序标志位函数
    45. EXTI_ClearITPendingBit(EXTI_Line14);
    46. }
    47. }

    中断函数头文件

    1. #ifndef __COUNT_SENSOR_H__
    2. #define __COUNT_SENSOR_H__
    3. /*
    4. 外部中断配置
    5. 1: 配置RCC进涉及的外部中断时钟全部打开
    6. 2:配置GPIO选择端口为输入模式
    7. 3: 配置AFIO选择需要使用到的GPIO并连接后面的exit
    8. 4:配置EXTI选择边沿触发的方式如上升沿,下降沿,或者是双边沿,选择触发响应的方式
    9. 5:配置NVIC给中断选择一个合适的优先级
    10. */
    11. void CountSersor_Init(void);
    12. uint16_t CountSensor_Get(void);
    13. #endif

    主函数调用代码

    1. #include "stm32f10x.h" // Device header
    2. #include "Delay.h"
    3. #include "OLED.h"
    4. #include "CounterSensor.h"
    5. int main(void)
    6. {
    7. // 初始化oled
    8. OLED_Init();
    9. CountSersor_Init();
    10. // 使用OLED显示字符串
    11. OLED_ShowString(1,3,"Count:");
    12. while (1)
    13. {
    14. OLED_ShowNum(1, 7, CountSensor_Get(), 5);
    15. }
    16. }

  • 相关阅读:
    php 对接IronSource海外广告平台收益接口Reporting API
    HTML5-4-表单
    关于标准库中的string类 - c++
    PAT甲级真题1153: 解码PAT准考证
    超算/先进计算如何改变现如今对的生活
    基于人工智能(AI)的蛋白结构预测工具合集
    STL线程各种容器对比、数组和vector如何互相转换
    工程坐标转换方法C#代码实现
    CTF-sql注入(get)【简单易懂】
    【笔记 Pytorch】模型网络结构、网络参数可视化
  • 原文地址:https://blog.csdn.net/qq_45973003/article/details/136603934