不讲基本原理,只给直接使用的代码。亲测可直接移植使用,IO口可自行另外配置。
Encoder.c
#include "Encoder.h"
#include "usart.h"
void Encoder_Init(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 速度MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; // 添加PD10配置
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // 速度MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // 添加PD10配置
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &GPIO_InitStructure);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource8);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource9);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource10); // 配置PD10
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line8 | EXTI_Line9 | EXTI_Line10; // 添加PD10配置
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 配置下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line10; // 添加PD10配置
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 配置下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; // 添加PD10配置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; // 设置PD10的子优先级为2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int16_t Encoder_Get(void)
{
int16_t Temp;
Temp = Encoder_Count;
Encoder_Count = 0;
return Temp;
}
void EXTI9_5_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line8) != RESET)
{
delay_us(4500);
if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_8) == 0)
{
if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_9) == 1)
{
Encoder_Count--;
}
}
EXTI_ClearITPendingBit(EXTI_Line8);
}
if (EXTI_GetITStatus(EXTI_Line9) != RESET)
{
delay_us(4500);
if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_9) == 0)
{
if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_8) == 1)
{
Encoder_Count++;
}
}
EXTI_ClearITPendingBit(EXTI_Line9);
}
}
void EXTI15_10_IRQHandler(void) // 添加PD10配置的中断处理函数
{
// PD10上升沿触发的操作
delay_ms(5);
if (EXTI_GetITStatus(EXTI_Line10) != RESET)
{
if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_10) != 0)
{
// TODO: 添加你需要的操作代码
printf("按键按下");
Encoder_Count+=100;
}
EXTI_ClearITPendingBit(EXTI_Line10);
}
}
Encoder.h
#ifndef __ENCODE_H
#define __ENCODE_H
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_exti.h"
#include "delay.h"
#include "stdint.h"
#include "misc.h"
extern uint16_t Encoder_Count;
void Encoder_Init(void);
int16_t Encoder_Get(void);
#endif /*__DIY_H*/
main.c
#include "sys.h"
uint16_t Encoder_Count = 0;
uint16_t Encoder_KEY_NUMBERS = 0;
uint16_t CH[24] = {0};
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
Encoder_Init(); //旋钮编码器
while(1)
{
Encoder_KEY_NUMBERS += (uint16_t)Encoder_Get();//限制为0~65535
CH[0] = Encoder_KEY_NUMBERS;
printf("%d", (uint16_t)*CH); //输出到串口
}
}