STM32——旋转编码器计次(七)

一、简介

旋转编码器:用来测量位置、速度或旋转方向的装置,当其旋转轴旋转时,其输出端可以输出与旋转速度和方向对应的方波信号,读取方波信号的频率和相位信息即可得知旋转轴的速度和方向

类型:机械触点式/霍尔传感器式/光栅式

本篇采用的是机械触点式的旋转编码器

二、硬件电路图

图中的左边,接了一个上拉电压,当旋转编码器没有旋转时,A端口是高电平,当旋转编码器旋转时电路与接地连通,A端口输出低电平。

这个旋转编码器就是利用A、B的相位差,来判断它的旋转方向。

三、调用库函数

调用的函数

GPIO.h

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

Line:线、线路;Config(Configuration):配置;Source:源、来源

将指定的 GPIO 引脚,映射到 STM32 的外部中断控制器(EXTI)的对应中断线(Line)上。

exti.h

DeInit(De-Initialize):反初始化 / 复位初始化;Generate:生成;SW:Software,软件;Interrupt:中断;Flag:标志位;Pending:挂起的;

EXTI 反初始化

void EXTI_DeInit(void);//所有 EXTI 中断线的配置恢复为芯片复位默认状态

EXTI 核心初始化

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//结构体中的配置写入 EXTI 寄存器

EXTI 结构体初始化

void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);//将EXTI_InitTypeDef结构体的所有成员赋上标准库默认值

软件触发 EXTI 中断

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);通过代码手动触发指定 EXTI 中断线

获取 EXTI 中断状态【中断服务函数首选】

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

清除 EXTI 中断挂起位【中断服务函数必用】

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

misc.h

Priority:优先级;Group:分组;Vector:向量;

NVIC 优先级分组配置函数

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

NVIC 初始化函数

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

代码:

打开GPIOB和AFIO的时钟,选择B0,B1GPIO口,配置为上拉输入模式。

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_0 | GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB,&GPIO_InitStructure);

AFIO选择线路,必须一个一个的选择。

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);

配置EXTI

选择EXTI_Line0 和 EXTI_Line1通道并使能ENABLE,配置成中断模式EXTI_Mode_Interrupt,下降沿触发EXTI_Trigger_Falling。

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

选择优先级分组2,即2 位抢占优先级 + 2 位响应优先级

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

配置 EXTI0_IRQn(对应 PB0 编码器引脚)

因为目前只有这一个中断,所以占优先级Priority和响应优先级SubPriority配置为1即可。

NVIC_InitTypeDef NVIC_InitStructure;

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

配置 EXTI1_IRQn(对应 PB1 编码器引脚)

仅修改中断通道,响应优先级配置为2,复用其他参数,

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

执行逻辑

定义一个全局变量用来计数

int16_t Encoder_Count;

逆时针旋转

A先输出低电平,B后输出低电平,所以通道EXTI_Line0先触发中断,然后等待B输出电平,读取到B1口的低电平就执行 Encoder_Count --,执行完要将中断复位。

void EXTI0_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line0) == SET)

{

if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)

{

Encoder_Count --;

}

EXTI_ClearITPendingBit(EXTI_Line0);

}

}

顺时针旋转

与逆时针旋转相反。

void EXTI1_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line1) == SET)

{

if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)

{

Encoder_Count ++;

}

EXTI_ClearITPendingBit(EXTI_Line1);

}

}

返回计数

逆时针就返回-1,顺时针就返回1;

int16_t Encoder_Get(void)

{

int16_t Temp;

Temp = Encoder_Count;

Encoder_Count = 0;

return Temp;

}

声明

中断函数不用声明,达到中断条件,硬件会自动执行。

在main中调用相关函数

中断函数在md.s文件中

STM32F1 系列单片机的中断通道(IRQn)编号映射表在stm32f10x.h。

相关推荐
羽获飞2 小时前
从零开始学嵌入式之STM32——3.使用寄存器点亮一盏LED灯
单片机·嵌入式硬件
浩子智控3 小时前
商业航天计算机抗辐射设计
单片机·嵌入式硬件
独处东汉7 小时前
freertos开发空气检测仪之输入子系统结构体设计
数据结构·人工智能·stm32·单片机·嵌入式硬件·算法
風清掦7 小时前
【江科大STM32学习笔记-04】0.96寸OLED显示屏
笔记·stm32·学习
czy87874757 小时前
机智云 MCU OTA可以对MCU程序进行无线远程升级。
单片机·嵌入式硬件
A9better9 小时前
嵌入式开发学习日志52——二值与计数信号量
单片机·嵌入式硬件·学习
日更嵌入式的打工仔10 小时前
(实用向)中断服务程序(ISR)的优化方向
笔记·单片机
想放学的刺客11 小时前
单片机嵌入式试题(第25)嵌入式系统可靠性设计与外设驱动异常处理
stm32·单片机·嵌入式硬件·mcu·物联网
wotaifuzao11 小时前
STM32+FreeRTOS 长期可维护架构设计(事件驱动篇)-- 告别“屎山”代码
c语言·stm32·嵌入式硬件·freertos·状态机·事件驱动·嵌入式架构