STM32使用外部中断,实现触摸模块的触摸计次

实现效果:

手触摸一次,计数加1

 硬件与电路接线:

触摸模块原理:

        触摸模块中间引脚在空闲时为低电平,当有手指进行触摸时,电平发生跳变,产生上升沿,拿走手指时电平变为低电平,产生下降沿。

显示屏模块接线:

        显示屏VCC与GND分别接3.3V和GND,SCL与SDA分别接B0与B1,通过keil编程设置引脚。

开始编程:

编程思想:

        当外部引脚触发中断时,主程序进入中断函数,执行变量CountSenser_Count++,再调用显示屏显示函数显示,这就是程序完整的执行周期。

编程过程:       

        首先,创建两个文件分别命名为CountSenser.h和CountSenser.c,在CountSenser中实现外部中断引脚初始化函数。

1、开启时钟

GPIOB是在APB2外设上的,因此开启APB2外设上的时钟。

AFIO也是APB2外设上的时钟,因此使用相同的函数,将参数改为AFIO。

EXTI和NVIC外设的时钟是一直打开的,所以不用配置。

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

2、初始化GPIO

        使用中断GPIO要配置为输入模式

        采用中断配置时,引脚模式要配置为浮空、上拉或下拉输入模式。

        使用GPIOB14号口,设置为GPIO_Pin_14。

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

3、初始化AFIO

        配置AFIO的主要目的是选择要用哪一路GPIO,主要作用是选择哪个引脚为中断引脚

        AFIO的函数经常使用的有两个:

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);//配置引脚重映射
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);//配置AFIO的数据选择器,选择想要中断的引脚

         这里使用GPIOB的14号引脚代码如下:

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);

4、配置EXTI

        配置EXTI主要是选择中断触发方式,是上升沿、下降沿还是双边沿触发,还有触发响应方式,是中断响应还是事件响应

        下面是主要代码和注释:

	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;//选定PB14
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//配置为开启中断
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//设置上升沿触发
	EXTI_Init(&EXTI_InitStructure);

5、配置NVIC

        配置NVIC的主要目的是为了给中断一个合适的优先级。

        代码和注释如下:

	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//STM32的EXTI10到EXTI15都合并到了这个通道里
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//指定中断通道为使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//只有一个中断,随便设置
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//只有一个中断,随便设置
	NVIC_Init(&NVIC_InitStructure);

6、中断函数

        中断函数在启动文件中,带IRQHandler都是中断函数,中断函数中,首先先进行中断标志位判断,再进行中断执行程序,再清除中断标志位。代码如下:

void EXTI15_10_IRQHandler() {
	if (EXTI_GetITStatus(EXTI_Line14) == SET){//判断中断标志位
		CountSenser_Count ++;//执行中断程序,计数器加1
		EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
	}

}

整体代码:

主函数main,c

#include "stm32f10x.h"                  // Device header
#include "DELAY.h"
#include "OLED.h"
#include "CountSenser.h"
uint8_t KeyNum;
int main() {
	OLED_Init();
	CountSensor_Init();

	OLED_ShowString(1,1,"project1");
	OLED_ShowString(2,1,"ExitCount:");

	while(1){
		OLED_ShowNum(3,1,CountSensor_Get(),5);
	}
}

CountSenser.c代码:

#include "stm32f10x.h"
uint16_t CountSenser_Count;
void CountSensor_Init() {
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	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);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line14;//选定PB14
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//配置为开启中断
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//设置上升沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	//NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//初始化中断分组,配置为抢占优先级还是响应优先级,这里选择两位响应两位抢占
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//STM32的EXTI10到EXTI15都合并到了这个通道里
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//指定中断通道为使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//只有一个中断,随便设置
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//只有一个中断,随便设置
	NVIC_Init(&NVIC_InitStructure);
}
uint16_t CountSensor_Get() {
	return CountSenser_Count;

}
void EXTI15_10_IRQHandler() {
	if (EXTI_GetITStatus(EXTI_Line14) == SET){//判断中断标志位
		CountSenser_Count ++;//执行中断程序,计数器加1
		EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
	}

}

CountSenser.h代码:

#ifndef __COUNT_SENSOR_H
#define __COUNT_SENSOR_H

void CountSensor_Init();
uint16_t CountSensor_Get();
#endif

其他库函数:

        记得更改OLED.c文件中注释需要更改部分,更改为自己显示器的SLC与SDA的接线引脚。如图:

下载链接:

OLED显示屏库函数

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值