一、介紹
旋鈕電位器是一種電子元器件,通常用于控制電路中的電阻值。它包括一個旋轉(zhuǎn)式旋鈕和一個電阻體。通過旋轉(zhuǎn)旋鈕,可以改變電阻體的阻值,從而改變電路中的電流、電壓或功率等參數(shù)。旋鈕電位器常用于音量控制、亮度控制、溫度控制等應(yīng)用領(lǐng)域。一般來說,旋鈕電位器的阻值和功率是其最主要的性能指標(biāo)。常見的旋鈕電位器類型包括單軌、雙軌、三軌等,同時還有分別用于直流和交流電路的電位器。
使用的注意事項
1. 本文章使用的編碼器位360度,主要使用的外部中斷已經(jīng)io口的高低電平的判斷進行電位器左右旋轉(zhuǎn)的狀態(tài)進行實時刷新和獲取。
技術(shù)參數(shù)
額定電壓: DC 5V;
各相導(dǎo)線: 0.5mA(Max 5mA;Min 0.5mA)
公共導(dǎo)線:1mA(Max 10mA;Min 0.5mA)
使用溫度范圍::-30℃ to+80℃
關(guān)注微信公眾號--星之援工作室 發(fā)送關(guān)鍵字(360旋鈕編碼器)
????
二、關(guān)鍵代碼講解
?1.我們首先再rotary.h文件里進行io口的定義,并且使用一個結(jié)構(gòu)體來儲存我們的旋轉(zhuǎn)變量,示例代碼如下
rotary.h
#ifndef __EXTI_H
#define __EXTI_H
#include "stm32f10x.h"
#include "sys.h"
//引腳定義
#define KEY1_INT_GPIO_PORT GPIOB
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN GPIO_Pin_8
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOB
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource8
#define KEY1_INT_EXTI_LINE EXTI_Line8
#define KEY1_INT_EXTI_IRQ EXTI9_5_IRQn
#define KEY1_IRQHandler EXTI9_5_IRQHandler
#define KEY2_INT_GPIO_PORT GPIOB
#define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN GPIO_Pin_9
#define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOB
#define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource9
#define KEY2_INT_EXTI_LINE EXTI_Line9
#define KEY2_INT_EXTI_IRQ EXTI9_5_IRQn
#define KEY2_IRQHandler EXTI9_5_IRQHandler
typedef struct
{
u8 Left_State; // 左旋轉(zhuǎn)的標(biāo)志位
u8 Right_State; // 右旋轉(zhuǎn)的標(biāo)志位
u16 Turn_Num; // 旋轉(zhuǎn)度數(shù)
} Left_Right_Typedef; // 電導(dǎo)模式定義
extern Left_Right_Typedef turn_init; // 旋轉(zhuǎn)模式
#define Turn_Left PBin(8)
#define Turn_Right PBin(9)
void EXTI_Key_Config(void);
//監(jiān)測是否停止旋轉(zhuǎn)
void Check_Turn(void);
#endif /* __EXTI_H */
2.通過io口的外部中端來監(jiān)測那一邊先觸發(fā),并將觸發(fā)的狀態(tài)進行更新,之后再通過輪詢的方式監(jiān)測io口高低電平的觸發(fā)情況,以此來推斷出我們的電位器是否處于旋轉(zhuǎn)中,本代碼都有詳細(xì)的注釋,示例代碼如下
rotary.c
#include "rotary.h"
Left_Right_Typedef turn_init; // 旋轉(zhuǎn)模式
/**
* @brief 配置嵌套向量中斷控制器NVIC
* @param 無
* @retval 無
*/
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC為優(yōu)先級組1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置中斷源:按鍵1 */
NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
/* 配置搶占優(yōu)先級 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子優(yōu)先級 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中斷通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 配置中斷源:按鍵2,其他使用上面相關(guān)配置 */
NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief 配置 IO為EXTI中斷口,并設(shè)置中斷優(yōu)先級
* @param 無
* @retval 無
*/
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/*開啟按鍵GPIO口的時鐘*/
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);
/* 配置 NVIC 中斷*/
NVIC_Configuration();
/*--------------------------KEY1配置-----------------------------*/
/* 選擇按鍵用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
/* 配置為浮空輸入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
/* 選擇EXTI的信號源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI為中斷模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中斷 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中斷 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/*--------------------------KEY2配置-----------------------------*/
/* 選擇按鍵用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
/* 配置為浮空輸入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);
/* 選擇EXTI的信號源 */
GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
/* EXTI為中斷模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 下降沿中斷 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
/* 使能中斷 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
//監(jiān)測是否停止旋轉(zhuǎn)
void Check_Turn(void)
{
//左轉(zhuǎn)
if(Turn_Left==0&&turn_init.Left_State>0){
if(turn_init.Turn_Num<=360){
turn_init.Turn_Num++;
}
//重置觸發(fā)
turn_init.Left_State=5;
}
//判斷是否停止旋轉(zhuǎn)
else if(Turn_Left==1&&turn_init.Left_State>0)
{
turn_init.Left_State--;
}
// 右轉(zhuǎn)
if(Turn_Right==0&&turn_init.Right_State>0){
if(turn_init.Turn_Num>0){
turn_init.Turn_Num--;
}
//重置觸發(fā)
turn_init.Right_State=5;
}
//判斷是否停止旋轉(zhuǎn)
else if(Turn_Right==1&&turn_init.Right_State>0)
{
turn_init.Right_State--;
}
}
//外部中斷觸發(fā)
void KEY1_IRQHandler(void)
{
//確保是否產(chǎn)生了EXTI Line中斷
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
{
// 排除已觸發(fā)狀態(tài)
if(turn_init.Right_State==0){
// 左轉(zhuǎn)
turn_init.Left_State=5;
}
//清除中斷標(biāo)志位
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
}
//確保是否產(chǎn)生了EXTI Line中斷
if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET)
{
// 排除已觸發(fā)狀態(tài)
if(turn_init.Left_State==0){
// 右轉(zhuǎn)
turn_init.Right_State=5;
}
//清除中斷標(biāo)志位
EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
}
}
/*********************************************END OF FILE**********************/
3.最后我們直接在主函數(shù)進行輪詢判斷即可,也可以放到我們的定時器中執(zhí)行,在這個了我給了一個延時,讓他大約每30ms執(zhí)行一次監(jiān)測,節(jié)約硬件的cup
main.c
/*--------------------------------------------------------*
* *
* 星之援網(wǎng)絡(luò)科技工作室學(xué)習(xí)資料v1.0 *
* 時間:2022.7.14 *
* 程序介紹:外部中斷 *
* 實現(xiàn)效果:按鍵改變板載LED的狀態(tài) *
* 需求請聯(lián)系:13648103287 *
*--------------------------------------------------------*
*/
#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();
/* 初始化EXTI中斷,按下按鍵會觸發(fā)中斷,
* KEY1_IRQHandler和KEY2_IRQHandler,處理中斷。
*/
EXTI_Key_Config();
printf("init okn");
while(1)
{
i++;
if(i%3==0){
//監(jiān)測旋鈕
Check_Turn();
}
if(i%25==0){
//監(jiān)測旋鈕
i=0;
printf("旋轉(zhuǎn)數(shù)據(jù): %dn",turn_init.Turn_Num);
}
delay_ms(10);
}
}
三、參考
STM32讀取旋鈕編碼器https://blog.csdn.net/qq_36958104/article/details/103577486?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170202402116800182182895%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170202402116800182182895&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-6-103577486-null-null.nonecase&utm_term=%E6%97%8B%E9%92%AE%E7%BC%96%E7%A0%81%E5%99%A8&spm=1018.2226.3001.4450
STM32 編碼器驅(qū)動/旋轉(zhuǎn)編碼器旋鈕encoderhttps://blog.csdn.net/denghuajing/article/details/122683502?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170202402116800182119214%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170202402116800182119214&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_click~default-1-122683502-null-null.nonecase&utm_term=%E6%97%8B%E9%92%AE%E7%BC%96%E7%A0%81%E5%99%A8&spm=1018.2226.3001.4450
完整代碼請關(guān)注衛(wèi)星公眾號進行獲取和咨詢
聯(lián)系方式 微信號:13648103287