stm32f103标准库按键外部中断

最终效果描述

按键按下触发外部中断, 点亮灯, 再次按下熄灭灯.

RCC配置

 需要打开外设GPIO, AFIO, 两个. 查看源代码竟然发现EXTI和NVIC竟然不属于外设, 不过想想也对, 因为中断不光是为用户来准备的, 还有一部分是系统需要的.

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

AFIO介绍

 AFIO是数据选择器, 用于引脚的复用功能的选择和重定义. stm32最多只有16个外部中断通道, 为了实现每个io口都可以作为一个触发引脚, 使用数据选择器来选择, 但编号0的只能选择一个. 这里AFIO配置就是将IO口配置为一个外部中断引脚. 硬件原理图样子如下所示.

 将IO口配置为一个外部中断引脚代码如下.

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);

GPIO配置

因为需要读取外面的信号, 所以模式需要设置为输入模式, 防止引脚悬空选择上拉模式.

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

EXTI配置

 通过框图可以知道, 可以外部触发, 也可以配置软件中断事件寄存器来触发.

EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line1; //选择中断通道
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //开启中断通道
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_Init(&EXTI_InitStructure);

NVIC(向量中断控制器)配置

NVIC是中断的大闸门, 总开关, 可以配置中断的优先级. 

抢占优先级:  抢占低抢占优先级的中断, 实现中断嵌套.

响应优先级: 同时响应时, 高响应优先级的先响应.

根据优先级分组的配置来选择抢占和响应优先级的个数, 数字越低, 优先级越高.

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);

中断向量表与中断服务函数

中断服务函数返回值皆为void, 参数为void. 函数名在中断向量表中, 名字唯一, 不可以更改.

中断向量表为start up汇编文件中, 这是单片机真正的入口, 里面的Vector Table Mapped.

void EXTI1_IRQHandler()
{
    if(EXTI_GetITStatus(EXTI_Line1) == SET) //判断中断信号是否触发
    {
        flag++;
        Delay_ms(250);
        EXTI_ClearITPendingBit(EXTI_Line1); //清空中断标志位
    }
}

按键消除抖动

 按键按下会触发抖动, 原因就是两个金属弹片快速碰撞来的抖动, 造成信号的抖动, 旋转式的老式风扇开关会出火花也是这个原因, 不能瞬间的充分接触导致的. 软件消除抖动就是使用延时函数, 硬件的消除抖动并联电容, 利用电容的滤波特性. 这里选择延时消除抖动.

在中断服务函数中可以看出延时了250ms, 在使用逻辑分析仪来反复监测按键的抖动, 发现最高是240多毫秒, 250ms之后才可以消除抖动带来的影响, 但是大大增加了按键的触发延迟.

程序主逻辑

上面的配置完成了, 任务的主逻辑就很简单了, 利用flag变量, 按键按下触发flag+1, 偶数次熄灭, 奇数次点亮LED.

uint8_t flag = 0;

int main(void)
{
    //灯
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    extiInit();
    
    while (1)
    {
        if(flag % 2 == 1){
            GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);
        }else{
            GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值