STM32旋转编码器计次(外部中断)

接线图如下:

顺时针旋转count++,反之count--。(这个可以自己在中断函数自己定义count的变化)

旋转编码计次Encode.c和Encode.h 文件

进行STM32外部中断的步骤如下:

1.   /第一步配置RCC  把涉及的外设的时钟打开  EXTI 和NVIC(内核)两个不需要开启时钟 GPIOB和AFIO需要开启时钟   打开时钟

2.配置GPIO 选择我们的端口为输入模式 我连接是是B0和B1接口分别接旋转编码器的A和B

3.配置APIO外部中断引脚选择 来选择我们要中断的引脚 中断的引脚 也分别是B0和B1

4.配置EXTI 选择边沿触发方式

5.配置NVIC 给中断选择合适的优先级  并且对两个通道分别设置优先级

下面是Encode.c的代码与注释:

#include "stm32f10x.h"                  // Device header

int16_t cnt;
void Encode_Init(void)
{
	//打开时钟
    	//第一步配置RCC  把涉及的外设的时钟打开  EXTI  NVIC(内核)两个不需要开启时钟 GPIOB和AFIO需要开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);//AFIO的时钟
	
	//第二步 配置GPIO 选择我们的端口为输入模式
	GPIO_InitTypeDef GPIO_InitStructure;
	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);
	

	
	//第三步 配置APIO外部中断引脚选择 来选择我们要中断的引脚
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//这个函数可以配置AFIO的数据选择器  
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
	
	
	//第四步 配置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);
	
	//第五步配置NVIC 给中断选择合适的优先级   	对两个通道分别设置优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置优先级分组 2个抢占2个响应
	
	NVIC_InitTypeDef  NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;//指定中断通道来开启或关闭 我们用的是STM32F10X_MD的15_10
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//指定的通道是使能还是失能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//设置抢占优先级 2组的取值是0-3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//设置响应优先级  2组的取值是0-3
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;//指定中断通道来开启或关闭 我们用的是STM32F10X_MD的15_10
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//指定的通道是使能还是失能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//设置抢占优先级 2组的取值是0-3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;//设置响应优先级  2组的取值是0-3
	NVIC_Init(&NVIC_InitStructure);
	
}
int16_t getcnt(void)//返回cnt的变化值 用于外部加减变量
{
	int16_t lsbl;
	lsbl=cnt;
	cnt=0;
	return lsbl;
}
void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0)==SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)//判断另外一个引脚的电频 正反可以自己设置 我这里设置的是都是1 就是反转
		{
			cnt--;//正反可以自己定义
		}
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
}
void EXTI1_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line1)==SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0)
		{
			cnt++;
		}
		EXTI_ClearITPendingBit(EXTI_Line1);
	}
}

Encode.h代码如下:

#ifndef  _ENCODE_H
#define  _ENCODE_H

void Encode_Init(void);
int16_t getcnt(void);	

#endif

主函数代码如下:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Encode.h"
int16_t SSum;

int main(void)
{
	Encode_Init();
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	//CountSensor_Init();
	/*OLED显示*/
	OLED_ShowChar(1, 1, 'A');				//1行1列显示字符A
	OLED_ShowString(2, 1, "Count:");
	while (1)
	{
		SSum+=getcnt();	
		OLED_ShowSignedNum(3,1,SSum,5);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elegent C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值