• 方案介紹
    • 一、前言
    • 二、簡介
    • 三、資料獲取
    • 四、設(shè)備使用
    • 四、代碼編寫
    • 五、參考
  • 附件下載
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

【嵌入式外設(shè)】 雙軸旋鈕傳感器(與按鍵同理)驅(qū)動代碼

02/26 08:39
1132
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

聯(lián)系方式.docx

共1個文件

一、前言

雙軸旋鈕傳感器(也稱為二維旋鈕、2D旋鈕)是一種集成了旋轉(zhuǎn)和推壓功能的輸入設(shè)備,能夠在兩個軸(X軸和Y軸)上進行旋轉(zhuǎn)或推壓操作。它通常由旋轉(zhuǎn)編碼器和一個按壓開關(guān)(按鈕)組成,能夠提供豐富的交互方式,廣泛應(yīng)用于電子產(chǎn)品、工業(yè)設(shè)備、家電控制等領(lǐng)域。

二、簡介

雙軸旋鈕傳感器的構(gòu)造與工作原理

  1. 旋轉(zhuǎn)編碼器:雙軸旋鈕的旋轉(zhuǎn)部分通常使用增量編碼器或旋轉(zhuǎn)電位器。當(dāng)旋鈕旋轉(zhuǎn)時,編碼器會產(chǎn)生一定的電信號,表示旋轉(zhuǎn)的角度或方向。旋轉(zhuǎn)編碼器有兩個主要的電信號(A、B通道),根據(jù)這兩個信號的相對變化來判斷旋轉(zhuǎn)的方向和步數(shù)。
  2. 按壓開關(guān):雙軸旋鈕傳感器通常還集成了一個按壓開關(guān),用戶可以按下旋鈕來觸發(fā)操作。這個按鍵信號是一個簡單的開關(guān)操作,常用于確認選擇或切換模式。
  3. 兩個軸:旋轉(zhuǎn)可以分別控制水平(X軸)和垂直(Y軸)兩個方向的輸入。例如,可以通過旋轉(zhuǎn)控制音量(X軸)和亮度(Y軸),而按下旋鈕則用來確認選擇或進入設(shè)置菜單。

雙軸旋鈕傳感器的應(yīng)用

  1. 音量控制:在許多音響、電視、車載系統(tǒng)等設(shè)備中,雙軸旋鈕傳感器被用來同時控制音量和音效模式(如平衡、低音、高音等),提供更直觀的操作體驗。
  2. 界面操作:在數(shù)字儀表盤、液晶顯示器嵌入式設(shè)備中,雙軸旋鈕傳感器常用于菜單導(dǎo)航、參數(shù)調(diào)節(jié)、光標(biāo)控制等。
  3. 工業(yè)控制:雙軸旋鈕可以在設(shè)備的控制面板中用于調(diào)節(jié)設(shè)備的工作狀態(tài)、溫度、速度等,例如在空調(diào)、機械設(shè)備和電梯的控制面板中應(yīng)用。
  4. 游戲控制器:某些游戲設(shè)備或模擬器中,也會使用雙軸旋鈕傳感器來提供更加精細的控制體驗。

雙軸旋鈕傳感器的使用

在實際應(yīng)用中,雙軸旋鈕傳感器通常會通過與微控制器(如Arduino、STM32等)連接來進行控制。以下是一個簡單的連接和使用示例:

硬件連接

  1. 旋轉(zhuǎn)部分:通常通過3個引腳連接到控制器:VCC(電源)、GND(地線)、和數(shù)據(jù)輸出引腳(通常有兩個信號引腳A和B,負責(zé)讀取旋轉(zhuǎn)的方向和步數(shù))。
  2. 按壓開關(guān):將按壓開關(guān)的兩個引腳連接到一個數(shù)字I/O引腳上,通過讀取按鍵的狀態(tài)來判斷是否被按下。

三、資料獲取

關(guān)注微信公眾號--星之援工作室 發(fā)送關(guān)鍵字(雙軸旋鈕)

代碼含重要注釋,開源,可自行移植

????452c0cf75b1d4e4895194df8a5022c34.png

四、設(shè)備使用

實現(xiàn)效果

連接好線 打開串口工具 即可輸出獲取的數(shù)據(jù)

?

接線

VCC - 5.0

GND - GND

X???? - PB12

Y???? - PB13

SWD - PB14

?

四、代碼編寫

main.c

?實現(xiàn)函數(shù)調(diào)用

/*--------------------------------------------------------*
 *                                       								  
 *   	 星之援網(wǎng)絡(luò)科技工作室學(xué)習(xí)資料v1.0    								
 *		 時間:2023.7.14                    								
 *		 程序介紹:模擬按鍵               								  
 *		 實現(xiàn)效果:雙軸旋鈕 								  
 *     需求請聯(lián)系:13648103287                            
 *--------------------------------------------------------*
*/
/*--------------------------------------------------------*
        VCC - 5.0
        GND - GND
        X 	- PB12
        Y 	- PB13
				SWD - PB14
 *--------------------------------------------------------*
*/

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "rotary.h" 
#include "usart.h"
int main(void)
{
	u16 i;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
	delay_init();
	// 串口初始化
	uart_init(115200);

	// LED 端口初始化 
	LED_GPIO_Config();
	// 雙軸初始化
	Key_GPIO_Config(); 
	
	printf("init okn");
  while(1)
	{
		i++;
		
		if(i % 30 ==0){
			//監(jiān)測旋鈕
			i=0;
			Check_Key_ON_OFF();
		}
		
		delay_ms(10);
	}
}

rotary.c

實現(xiàn)端口為輸入模式 ,實現(xiàn)按鍵讀取

#include "rotary.h"
#include "delay.h"
#include "usart.h"
// 協(xié)議文件
/*********************************************************************************
 * @Function	:  初始化控制LED的IO
 * @Input		:  None
 * @Output		:  None
 * @Return		:  None
 * @Others		:  None
 * @Date			:  2022-07-23
 **********************************************************************************/
void Key_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/*開啟按鍵端口的時鐘*/
	RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);

	// 選擇按鍵的引腳
	GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;
	// 設(shè)置按鍵的引腳為浮空輸入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	// 使用結(jié)構(gòu)體初始化按鍵
	GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);

	// 選擇按鍵的引腳 
	GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;
	// 設(shè)置按鍵的引腳為浮空輸入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	// 使用結(jié)構(gòu)體初始化按鍵
	GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

	// 選擇按鍵的引腳
	GPIO_InitStructure.GPIO_Pin = KEY3_GPIO_PIN;
	// 設(shè)置按鍵的引腳為浮空輸入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	// 使用結(jié)構(gòu)體初始化按鍵
	GPIO_Init(KEY3_GPIO_PORT, &GPIO_InitStructure);
}
/*********************************************************************************
 * @Function	:  檢測是否有按鍵按下
 * @Input		:  GPIOx:x 可以是 A,B,C,D或者 E
 *						:  GPIO_Pin:待讀取的端口位
 * @Output		:  None
 * @Return		:  KEY_OFF(沒按下按鍵)、KEY_ON(按下按鍵)
 * @Others		:  None
 * @Date			:  2022-07-23
 **********************************************************************************/
u8 Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
	/*檢測是否有按鍵按下 */
	if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
	{
		/*等待按鍵釋放 */
		while (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
			;
		return KEY_ON;
	}
	else
		return KEY_OFF;
}
/*********************************************************************************
 * @Function	:  按鍵處理函數(shù)
 * @Input		:  Gmode:0,不支持連續(xù)按;1,支持連續(xù)按;
 * @Output		:  None
 * @Return		:  0,沒有任何按鍵按下
 *							 1,KEY1按下
 *						   2,KEY2按下
 *							 3,KEY3按下
 * @Others		:  注意此函數(shù)有響應(yīng)優(yōu)先級,KEY0>KEY1>KEY2>KEY3!!
 * @Date			:  2022-07-23
 **********************************************************************************/
u8 KEY_Scan(u8 mode)
{
	static u8 key_up = 1; // 按鍵按松開標(biāo)志
	if (mode)
		key_up = 1; // 支持連按
	if (key_up && (KEY1 == KEY_ON || KEY2 == KEY_ON || KEY3 == KEY_ON))
	{
		//delay_ms(10); // 去抖動
		key_up = 0;
		if (KEY1 == KEY_ON)
			return KEY1_PRES;
		else if (KEY2 == KEY_ON)
			return KEY2_PRES;
		else if (KEY3 == KEY_ON)
			return KEY3_PRES;
	}
	else if (KEY1 == KEY_OFF && KEY2 == KEY_OFF && KEY3 == KEY_OFF)
		key_up = 1;
	return 0; // 無按鍵按下
}
// 檢測按鍵是否按下
static u8 num_on = 0;
static u8 key_old = 0;
void Check_Key_ON_OFF(void)
{
	u8 key;
	key = KEY_Scan(1);
	// 與上一次的鍵值比較 如果不相等,表明有鍵值的變化,開始計時
	if (key != 0 && num_on == 0)
	{
		key_old = key;
		num_on = 1;
	}
	if (key != 0 && num_on >= 1 && num_on <= Key_Scan_Time) // 25*10ms
	{
		num_on++; // 時間記錄器
		
	}
	switch (key)
	{
	case KEY1_PRES:
		printf("Leftn");
	
		break;
	case KEY2_PRES:
		printf("Rightn");

		break;

	default:
		break;
	}

	if (key == 0 && num_on > 0 && num_on < Key_Scan_Time) // 短按
	{
		switch (key_old)
		{
		case KEY1_PRES:
			printf("Key1_Shortn");
		
			break;
		case KEY2_PRES:
			printf("Key2_Shortn");

			break;
		case KEY3_PRES:
			printf("Key3_Shortn");


			break;

		default:
			break;
		}
		num_on = 0;
	}
	else if (key == 0 && num_on >= Key_Scan_Time) // 長按
	{
		switch (key_old)
		{
		case KEY1_PRES:
			printf("Key1_Longn");

			break;
		case KEY2_PRES:
			printf("Key2_Longn");

			break;
		case KEY3_PRES:
			printf("Key3_Longn");

			break;
		default:
			break;
		}
		num_on = 0;
	}
}
/*********************************************END OF FILE**********************/

rotary.h

配置函數(shù)

#ifndef __KEY_H
#define __KEY_H

#include "stm32f10x.h"

//  引腳定義
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOB
#define KEY1_GPIO_PORT GPIOB
#define KEY1_GPIO_PIN GPIO_Pin_12

#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOB
#define KEY2_GPIO_PORT GPIOB
#define KEY2_GPIO_PIN GPIO_Pin_13

#define KEY3_GPIO_CLK RCC_APB2Periph_GPIOB
#define KEY3_GPIO_PORT GPIOB
#define KEY3_GPIO_PIN GPIO_Pin_14

#define KEY1 GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN) // 讀取按鍵0
#define KEY2 GPIO_ReadInputDataBit(KEY2_GPIO_PORT, KEY2_GPIO_PIN) // 讀取按鍵1
#define KEY3 GPIO_ReadInputDataBit(KEY3_GPIO_PORT, KEY3_GPIO_PIN) // 讀取按鍵2

#define KEY1_PRES 1 // KEY1按下
#define KEY2_PRES 2 // KEY2按下
#define KEY3_PRES 3 // KEY3按下

#define Key_Scan_Time 30 // 短按時長時間判斷

/** 按鍵按下標(biāo)置宏
 *  按鍵按下為高電平,設(shè)置 KEY_ON=1, KEY_OFF=0
 *  若按鍵按下為低電平,把宏設(shè)置成KEY_ON=0 ,KEY_OFF=1 即可
 */
#define KEY_ON 0
#define KEY_OFF 1
/*********************************************************************************
 * @Function	:  初始化控制LED的IO
 * @Input		:  None
 * @Output		:  None
 * @Return		:  None
 * @Others		:  None
 * @Date			:  2022-07-23
 **********************************************************************************/
void Key_GPIO_Config(void);
/*********************************************************************************
 * @Function	:  檢測是否有按鍵按下
 * @Input		:  GPIOx:x 可以是 A,B,C,D或者 E
 *						:  GPIO_Pin:待讀取的端口位
 * @Output		:  None
 * @Return		:  KEY_OFF(沒按下按鍵)、KEY_ON(按下按鍵)
 * @Others		:  None
 * @Date			:  2022-07-23
 **********************************************************************************/
uint8_t Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
/*********************************************************************************
 * @Function	:  按鍵處理函數(shù)
 * @Input		:  Gmode:0,不支持連續(xù)按;1,支持連續(xù)按;
 * @Output		:  None
 * @Return		:  0,沒有任何按鍵按下
 *							 1,KEY1按下
 *						   2,KEY2按下
 *							 3,KEY3按下
 * @Others		:  注意此函數(shù)有響應(yīng)優(yōu)先級,KEY0>KEY1>KEY2>KEY3!!
 * @Date			:  2022-07-23
 **********************************************************************************/
u8 KEY_Scan(u8 mode);
/*********************************************************************************
 * @Function	:  按鍵事件返回
 * @Input		:  None
 *						:  None
 * @Output		:  None
 * @Return		:  None
 * @Others		:  注意此函數(shù)有響應(yīng)優(yōu)先級,KEY0>KEY1>KEY2>KEY3!!
 * @Date			:  2022-07-23
 **********************************************************************************/
void Send_Cmd(void);

void Check_Key_ON_OFF(void);
	
#endif /* __KEY_H */



五、參考

STM32 -- 實現(xiàn)按鍵的長按與短按檢測(其他單片機可移植)https://blog.csdn.net/herui_2/article/details/128473627?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522d7f1b7e24384cae191eb4b90201ac1df%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=d7f1b7e24384cae191eb4b90201ac1df&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128473627-null-null.nonecase&utm_term=%E6%8C%89%E9%94%AE&spm=1018.2226.3001.4450https://blog.csdn.net/herui_2/article/details/128473627?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522d7f1b7e24384cae191eb4b90201ac1df%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=d7f1b7e24384cae191eb4b90201ac1df&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128473627-null-null.nonecase&utm_term=%E6%8C%89%E9%94%AE&spm=1018.2226.3001.4450

聯(lián)系方式 微信號:13648103287

  • 聯(lián)系方式.docx
    下載

相關(guān)推薦

方案定制

去合作
方案開發(fā)定制化,2000+方案商即時響應(yīng)!

方案定制,程序設(shè)計方案、單片機程序設(shè)計與講解、APP定制開發(fā)。本公眾號致力于向讀者傳遞關(guān)于程序設(shè)計和開發(fā)的相關(guān)知識,并分享一些關(guān)于軟件開發(fā)的最佳實踐。如果您有什么問題或建議,請隨時聯(lián)系我們。我們將竭誠為您服務(wù)