当前位置: 首页 > article >正文

STM32F103C8T6学习笔记4--模拟旋转编码器的按键中断

1、实验内容

通过旋转编码器正反转来计数,由对应的GPIO产生中断。但是我在Proteus里面没有找到相关的EC11旋转编码器元件,暂时通过电路模拟的方式实现。

S1按下引脚PB0产生低电平信号,触发中断,计数值减一。

S2按下引脚PB1产生低电平信号,触发中断,计数值加一。

2、OLED驱动

电路图添加了OLED12864I2C的0.96OLED屏,通过该屏显示数据。

3、中断初始化配置

(1)配置GPIOB-0/1口作为外部中断触发引脚

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);        //开启GPIOB的时钟
        /*配置GPIOB*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//默认高电平上拉输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);        

(2)配置中断引脚选择AFIO

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);     //开启AFIO的时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);

(3)配置EXTI边沿检测

EXTI_InitTypeDef EXTI_InitStructure;                                                  EXTI_InitStructure.EXTI_Line = EXTI_Line0|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);

(4)配置NVIC,中断的抢占和响应优先级。使能这两个中断

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

NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&NVIC_InitStructure);

4、中断服务函数

/**
  * 函    数:EXTI0外部中断函数
  * 参    数:无
  * 返 回 值:无
  * 注意事项:此函数为中断函数,无需调用,中断触发后自动执行
  *           函数名为预留的指定名称,可以从启动文件复制
  *           请确保函数名正确,不能有任何差异,否则中断函数将不能进入
  */
void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)		//判断是否是外部中断0号线触发的中断
	{
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)
		{
			Encode_Counter--;					//此方向定义为反转,计数变量自减
			EXTI_ClearITPendingBit(EXTI_Line0);			//清除外部中断0号线的中断标志位
														//中断标志位必须清除
												//否则中断将连续不断地触发,导致主程序卡死
		}
	}
}

/**
  * 函    数:EXTI1外部中断函数
  * 参    数:无
  * 返 回 值:无
  * 注意事项:此函数为中断函数,无需调用,中断触发后自动执行
  *           函数名为预留的指定名称,可以从启动文件复制
  *           请确保函数名正确,不能有任何差异,否则中断函数将不能进入
  */
void EXTI1_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line1) == SET)		//判断是否是外部中断1号线触发的中断
	{

		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1)
		{
				Encode_Counter++;					//此方向定义为正转,计数变量自增
			
		EXTI_ClearITPendingBit(EXTI_Line1);			//清除外部中断1号线的中断标志位
													//中断标志位必须清除
		}
	}
}

将Encode_Counter这个返回值封装到函数里面,供主函数调用。


int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp=Encode_Counter;
	Encode_Counter=0;
	return Temp;
}

5、主函数

#include "stm32f10x.h"                  // Device header
#include "delay.h"  
#include "Encoder.h" 
#include "OLED.h" 

int16_t Num;


int main(void)
{
	OLED_Init();
	Encoder_Init();
	OLED_ShowString(1,1,"Count:");
	while(1)
	{
		Num+=Encoder_Get();
		OLED_ShowSignedNum(1,7,Num,5);
	}
		
}


http://www.kler.cn/a/388916.html

相关文章:

  • 申论1_概括、分析
  • ubuntu-desktop-24.04上手指南(更新阿里源、安装ssh、安装chrome、设置固定IP、安装搜狗输入法)
  • 前端-同源与跨域
  • 【Vue】Vue3.0(十九)Vue 3.0 中一种组件间通信方式-自定义事件
  • flink sql + kafka + mysql 如何构建实时数仓
  • 使用 Visual Studio Installer 彻底卸载 Visual Studio方法与下载
  • 【MongoDB】MongoDB的聚合(Aggregate、Map Reduce)与管道(Pipline) 及索引详解(附详细案例)
  • 【业务】支付总结和GP支付功能测试
  • LRU缓存算法
  • Java集合框架之数组列表(ArrayList)
  • SDL事件相关
  • 中安OCR电子行驶证、驾驶证识别,助力便捷出行与智慧交通
  • Objective-C 1.0和2.0有什么区别?
  • git中使用tag(标签)的方法及重要性
  • 股票量化实时行情接口WebSocket接入Python封装
  • netcat工具安装和使用
  • 目前对于后期的打算
  • ubuntu使用DeepSpeech进行语音识别(包含交叉编译)
  • linux笔记(selinux)
  • 欢迎 Stable Diffusion 3.5 Large 加入 Diffusers
  • Android MavenCentral 仓库更新问题
  • 【9692】基于springcloud+vue的智慧养老平台
  • Linux:理解动静态库
  • Linux安装与配置 Gitblit 1.9.3 服务
  • 如何在 Linux 服务器上安装 Git
  • Linux——入门