首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

stm32f103c8t6的外部中断

  • 24-03-18 01:47
  • 3443
  • 6462
blog.csdn.net

在单片机中存在着中断系统,这个系统的逻辑和功能在51单片机中已经有所了解。

1.在32单片机中的内核有一个nvic 里面存放许多优先级的设定,外接许多中断源,比如“exti、tim、adc、usart等”接入之后,nvic再通过中断优先级进行排队,再内接入cpu中进行处理,这样子大大减少了cpu的运算,提高了工作效率。

2.其中里面的优先级又有响应优先级 抢占优先级,响应的可以进行优先排队(插队),而抢占可以进行中断嵌套。

3.exti外部中断,注意在支持的gpio口中,不能选择pin相同的来同时触发,比如pa1不能与pb1等等。

4.在外部中断的结构中,有一个afio中断引脚选择,就是一个选择器,用来选择是那个引脚触发。触发方式有上升沿、下降沿、双边沿、软件触发。

5.在exti框图中,当接入的线,可以选择上升、下降来选择触发,出来的值与软件中断事件寄存器进行相或(有1则为1)。出来的值,兵分两路,其一接入请求挂起寄存器,出来与中断屏蔽寄存器共同相与,则中断屏蔽给1,则输出请求挂起的值,给0,则直接输出0。

 ======================================

代码部分

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //注意GPIOB是APB2的外设
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //注意AFIO是APB2的外设 
    
    //EXTI和NVIC外设的时钟是一直打开的,不需要打开了,NVIC属于内核外设,均不用开启时钟
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //外部中断:浮空、上拉、下拉输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    //配置AFIO
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); 
    
    //配置EXTI
    
    EXTI_InitTypeDef EXTI_InitStructure;                 //起个变量名 同GIPO一样
    EXTI_InitStructure.EXTI_Line = EXTI_Line14;          //指定配置的中断线  14对应pin14
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;            //指定中断线的状态  ENABLE开启中断
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //指定外部中断的模式 EXTI_Mode_Interrupt中断模式 EXTI_Mode_Event事件模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
                     //触发信号的有效边沿 EXTI_Trigger_Rising上升沿 EXTI_Trigger_Falling下降沿 EXTI_Trigger_Rising_Falling双边沿
    EXTI_Init(&EXTI_InitStructure);//初始化
    
    //配置NVIC
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//指定中断优先级分组,2组即是2响应2抢占,整个工程(芯片)只需要一种即可
    
    NVIC_InitTypeDef NVIC_InitStructure;                      //起个变量名 同GIPO一样
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;      //指定中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //指定中断通道是使能还是失能
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定抢占取值范围,即是优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //指定响应取值范围,即是优先级
    NVIC_Init(&NVIC_InitStructure);//初始化
}

uint16_t CountSensor_Get(void)
{
    return CountSensor_Count;
}

void EXTI15_10_IRQHandler(void)      //中断函数
{
    if (EXTI_GetITStatus(EXTI_Line14) == SET)   //中断标志位判断,因为EXTI_Line10-EXTI_Line15都能进来,判断是否14进来
                                                  //如果是等于set(1),则可以进入中断程序
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
        {
            CountSensor_Count ++;
        }
        EXTI_ClearITPendingBit(EXTI_Line14);      //清除中断标志位
    }
}
======================================

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
    OLED_Init();
    CountSensor_Init();
    
    OLED_ShowString(1, 1, "Count:");
    
    while (1)
    {
        OLED_ShowNum(1, 7, CountSensor_Get(), 5);
    }
}
 

 ======================================

补充

 上图可以看到APB2总线可以连接的外设

介绍一下相关函数:

void GPIO_AFIODeInit(void);复位AFIO

void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);锁定GPIO,

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);

用来进行引脚重映射,参数1选择重映射方式,参数2是新的状态 。


void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

调用此函数,可以配置AFIO的数据选择器,选择中断引脚,参数1可以选择GPIOA-G,参数2选择pin0-15。

=========

exti

void EXTI_DeInit(void);调用这个函数,可以清除exti的配置,恢复上电默认状态

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);初始化

void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);调用之后,可以把参数传递的结构体变量赋一个默认值

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
软件触发外部中断,参数给指定的中断线

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);读写状态寄存器
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

在单片机中存在着中断系统,这个系统的逻辑和功能在51单片机中已经有所了解。

1.在32单片机中的内核有一个nvic 里面存放许多优先级的设定,外接许多中断源,比如“exti、tim、adc、usart等”接入之后,nvic再通过中断优先级进行排队,再内接入cpu中进行处理,这样子大大减少了cpu的运算,提高了工作效率。

2.其中里面的优先级又有响应优先级 抢占优先级,响应的可以进行优先排队(插队),而抢占可以进行中断嵌套。

3.exti外部中断,注意在支持的gpio口中,不能选择pin相同的来同时触发,比如pa1不能与pb1等等。

4.在外部中断的结构中,有一个afio中断引脚选择,就是一个选择器,用来选择是那个引脚触发。触发方式有上升沿、下降沿、双边沿、软件触发。

5.在exti框图中,当接入的线,可以选择上升、下降来选择触发,出来的值与软件中断事件寄存器进行相或(有1则为1)。出来的值,兵分两路,其一接入请求挂起寄存器,出来与中断屏蔽寄存器共同相与,则中断屏蔽给1,则输出请求挂起的值,给0,则直接输出0。

 ======================================

代码部分

#include "stm32f10x.h"                  // Device header

uint16_t CountSensor_Count;

void CountSensor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //注意GPIOB是APB2的外设
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   //注意AFIO是APB2的外设 
    
    //EXTI和NVIC外设的时钟是一直打开的,不需要打开了,NVIC属于内核外设,均不用开启时钟
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //外部中断:浮空、上拉、下拉输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    //配置AFIO
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); 
    
    //配置EXTI
    
    EXTI_InitTypeDef EXTI_InitStructure;                 //起个变量名 同GIPO一样
    EXTI_InitStructure.EXTI_Line = EXTI_Line14;          //指定配置的中断线  14对应pin14
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;            //指定中断线的状态  ENABLE开启中断
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //指定外部中断的模式 EXTI_Mode_Interrupt中断模式 EXTI_Mode_Event事件模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
                     //触发信号的有效边沿 EXTI_Trigger_Rising上升沿 EXTI_Trigger_Falling下降沿 EXTI_Trigger_Rising_Falling双边沿
    EXTI_Init(&EXTI_InitStructure);//初始化
    
    //配置NVIC
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//指定中断优先级分组,2组即是2响应2抢占,整个工程(芯片)只需要一种即可
    
    NVIC_InitTypeDef NVIC_InitStructure;                      //起个变量名 同GIPO一样
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;      //指定中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //指定中断通道是使能还是失能
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定抢占取值范围,即是优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        //指定响应取值范围,即是优先级
    NVIC_Init(&NVIC_InitStructure);//初始化
}

uint16_t CountSensor_Get(void)
{
    return CountSensor_Count;
}

void EXTI15_10_IRQHandler(void)      //中断函数
{
    if (EXTI_GetITStatus(EXTI_Line14) == SET)   //中断标志位判断,因为EXTI_Line10-EXTI_Line15都能进来,判断是否14进来
                                                  //如果是等于set(1),则可以进入中断程序
    {
        /*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
        if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
        {
            CountSensor_Count ++;
        }
        EXTI_ClearITPendingBit(EXTI_Line14);      //清除中断标志位
    }
}
======================================

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
    OLED_Init();
    CountSensor_Init();
    
    OLED_ShowString(1, 1, "Count:");
    
    while (1)
    {
        OLED_ShowNum(1, 7, CountSensor_Get(), 5);
    }
}
 

 ======================================

补充

 上图可以看到APB2总线可以连接的外设

介绍一下相关函数:

void GPIO_AFIODeInit(void);复位AFIO

void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);锁定GPIO,

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);

用来进行引脚重映射,参数1选择重映射方式,参数2是新的状态 。


void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

调用此函数,可以配置AFIO的数据选择器,选择中断引脚,参数1可以选择GPIOA-G,参数2选择pin0-15。

=========

exti

void EXTI_DeInit(void);调用这个函数,可以清除exti的配置,恢复上电默认状态

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);初始化

void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);调用之后,可以把参数传递的结构体变量赋一个默认值

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
软件触发外部中断,参数给指定的中断线

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);读写状态寄存器
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

注:本文转载自blog.csdn.net的新手小鲁巴的文章"https://blog.csdn.net/weixin_75264509/article/details/130447085"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

124
嵌入式
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top