Files
rtos/01_freertos_template/Drivers/DshanMCU-F103/driver_rotary_encoder.c
syx_computer 0196ca1e90 The new start
2025-09-30 11:49:27 +08:00

237 lines
7.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-License-Identifier: GPL-3.0-only
/*
* Copyright (c) 2008-2023 100askTeam : Dongshan WEI <weidongshan@qq.com>
* Discourse: https://forums.100ask.net
*/
/* Copyright (C) 2008-2023 深圳百问网科技有限公司
* All rights reserved
*
*
* 免责声明: 百问网编写的文档,仅供学员学习使用,可以转发或引用(请保留作者信息),禁止用于商业用途!
* 免责声明: 百问网编写的程序,可以用于商业用途,但百问网不承担任何后果!
*
*
* 本程序遵循GPL V3协议使用请遵循协议许可
* 本程序所用的开发板: DShanMCU-F103
* 百问网嵌入式学习平台https://www.100ask.net
* 百问网技术交流社区: https://forums.100ask.net
* 百问网官方B站 https://space.bilibili.com/275908810
* 百问网官方淘宝: https://100ask.taobao.com
* 联系我们(E-mail) weidongshan@qq.com
*
* 版权所有,盗版必究。
*
* 修改历史 版本号 作者 修改内容
*-----------------------------------------------------
* 2023.08.04 v01 百问科技 创建文件
*-----------------------------------------------------
*/
#include "driver_rotary_encoder.h"
#include "driver_lcd.h"
#include "driver_timer.h"
#include "stm32f1xx_hal.h"
#include "tim.h"
/*
* PB12 - S1
* PB0 - S2
* PB1 - Key
*/
#define ROTARY_ENCODER_S1_GPIO_GROUP GPIOB
#define ROTARY_ENCODER_S1_GPIO_PIN GPIO_PIN_12
#define ROTARY_ENCODER_S2_GPIO_GROUP GPIOB
#define ROTARY_ENCODER_S2_GPIO_PIN GPIO_PIN_0
#define ROTARY_ENCODER_KEY_GPIO_GROUP GPIOB
#define ROTARY_ENCODER_KEY_GPIO_PIN GPIO_PIN_1
static int32_t g_count = 0;
static int32_t g_speed = 0; /* 速度(正数表示顺时针旋转,负数表示逆时针旋转,单位:每秒转动次数) */
/**********************************************************************
* 函数名称: RotaryEncoder_Get_Key
* 功能描述: 读取旋转编码器Key引脚电平
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 1-按键被按下, 0-按键被松开
* 修改日期: 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/04 V1.0 韦东山 创建
***********************************************************************/
static int RotaryEncoder_Get_Key(void)
{
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(ROTARY_ENCODER_KEY_GPIO_GROUP, ROTARY_ENCODER_KEY_GPIO_PIN))
return 1;
else
return 0;
}
/**********************************************************************
* 函数名称: RotaryEncoder_Get_S1
* 功能描述: 读取旋转编码器S1引脚电平
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期: 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/04 V1.0 韦东山 创建
***********************************************************************/
static int RotaryEncoder_Get_S1(void)
{
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(ROTARY_ENCODER_S1_GPIO_GROUP, ROTARY_ENCODER_S1_GPIO_PIN))
return 0;
else
return 1;
}
/**********************************************************************
* 函数名称: RotaryEncoder_Get_S2
* 功能描述: 读取旋转编码器S2引脚电平
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期: 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/04 V1.0 韦东山 创建
***********************************************************************/
static int RotaryEncoder_Get_S2(void)
{
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(ROTARY_ENCODER_S2_GPIO_GROUP, ROTARY_ENCODER_S2_GPIO_PIN))
return 0;
else
return 1;
}
/**********************************************************************
* 函数名称: RotaryEncoder_IRQ_Callback
* 功能描述: 旋转编码器的中断回调函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期: 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/04 V1.0 韦东山 创建
***********************************************************************/
void RotaryEncoder_IRQ_Callback(void)
{
uint64_t time;
static uint64_t pre_time = 0;
/* 1. 记录中断发生的时刻 */
time = system_get_ns();
/* 上升沿触发: 必定是高电平
* 防抖
*/
mdelay(2);
if (!RotaryEncoder_Get_S1())
return;
/* S1上升沿触发中断
* S2为0表示逆时针转, 为1表示顺时针转
*/
g_speed = (uint64_t)1000000000/(time - pre_time);
if (RotaryEncoder_Get_S2())
{
g_count++;
}
else
{
g_count--;
g_speed = 0 - g_speed;
}
pre_time = time;
}
/**********************************************************************
* 函数名称: RotaryEncoder_Init
* 功能描述: 旋转编码器的初始化函数
* 输入参数: 无
* 输出参数: 无
* 返 回 值: 无
* 修改日期: 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/05 V1.0 韦东山 创建
***********************************************************************/
void RotaryEncoder_Init(void)
{
/* PB0,PB1在MX_GPIO_Init中被配置为输入引脚 */
/* PB12在MX_GPIO_Init中被配置为中断引脚,上升沿触发 */
}
/**********************************************************************
* 函数名称: RotaryEncoder_Write
* 功能描述: 旋转编码器的读取函数
* 输入参数: 无
* 输出参数: pCnt - 用于保存计数值
* pSpeed - 用于保存速度(正数表示顺时针旋转,负数表示逆时针旋转,单位:每秒转动次数)
* pKey - 用于保存按键状态(1-按键被按下, 0-按键被松开)
* 返 回 值: 无
* 修改日期: 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/05 V1.0 韦东山 创建
***********************************************************************/
void RotaryEncoder_Read(int32_t *pCnt, int32_t *pSpeed, int32_t *pKey)
{
static int32_t pre_count = 0;
*pCnt = g_count;
if (g_count == pre_count)
*pSpeed = 0;
else
*pSpeed = g_speed;
pre_count = g_count;
*pKey = RotaryEncoder_Get_Key();
}
/**********************************************************************
* 函数名称: RotaryEncoder_Test
* 功能描述: 旋转编码器测试程序
* 输入参数: 无
* 输出参数: 无
* 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/05 V1.0 韦东山 创建
***********************************************************************/
void RotaryEncoder_Test(void)
{
int32_t count, speed, key;
int len;
RotaryEncoder_Init();
while (1)
{
LCD_PrintString(0, 0, "RotaryEncoder: ");
RotaryEncoder_Read(&count, &speed, &key);
len = LCD_PrintString(0, 2, "Cnt : ");
len += LCD_PrintSignedVal(len, 2, count);
LCD_ClearLine(len, 2);
len = LCD_PrintString(0, 4, "Speed: ");
len += LCD_PrintSignedVal(len, 4, speed);
LCD_ClearLine(len, 4);
len = LCD_PrintString(0, 6, "Key : ");
len += LCD_PrintString(len, 6, key ? "Pressed":"Released");
LCD_ClearLine(len, 6);
}
}