旋轉(zhuǎn)編碼器介紹
旋轉(zhuǎn)編碼器簡(jiǎn)單來(lái)說(shuō),就是會(huì)輸出2個(gè)PWM,依據(jù)相位可以知道旋轉(zhuǎn)方向,依據(jù)脈沖個(gè)數(shù)可以知道旋轉(zhuǎn)的角度。一般旋轉(zhuǎn)一圈有一個(gè)固定數(shù)值的脈沖個(gè)數(shù)。
旋轉(zhuǎn)編碼器廣泛用于電機(jī)、或者角度傳感器,STM32的定時(shí)器可以直接接入這兩個(gè)波形獲取到信息。
前兩個(gè)引腳(接地和Vcc)用于為編碼器供電,我這里采用3.3V的供電。除了以順時(shí)針?lè)较蚝湍鏁r(shí)針?lè)较蛐D(zhuǎn)旋鈕外,編碼器還有一個(gè)開(kāi)關(guān)(低電平有效),按下內(nèi)部的旋鈕可以按下該開(kāi)關(guān)。來(lái)自此開(kāi)關(guān)的信號(hào)通過(guò)引腳3(Switch)獲得。最后它有兩個(gè)輸出引腳。
主程序邏輯直接檢測(cè)
主程序中不要加延時(shí),否則可能檢測(cè)不到下降沿。
//旋轉(zhuǎn)編碼器
//CLK–PA0
//DT—PA1
//SW—PA2
3.3V供電。
#include "sys.h"
#include "usart.h"
//旋轉(zhuǎn)編碼器
//CLK--PA0
//DT---PA1
//SW---PA2
#define CLK_in PAin(0)
#define DT_in PAin(1)
#define SW_in PAin(2)
u32 encoder_cnt = 100000;//旋轉(zhuǎn)脈沖計(jì)數(shù)
u8 direction = 0;//旋轉(zhuǎn)方向 1正傳
u8 dt_high_flag = 0;
void rotary_encoder_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* 使能時(shí)鐘 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* 設(shè)置成上拉輸入 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化PC13
}
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí) */
delay_init(); /* 延時(shí)函數(shù)初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* 關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試 */
delay_ms(500); /* 等待穩(wěn)定 */
uart_init(115200);
rotary_encoder_Init();
while (1) {
if (SW_in == 0) {
delay_ms(10);
if (SW_in == 0) {
printf("SW_in=0\r\n");
while (SW_in == 0);
}
}
//DT_in是下降沿的時(shí)候,如果CLK_in是高電平,那么就是正轉(zhuǎn),如果CLK_in是低電平,那么就是反轉(zhuǎn)
if (DT_in == 1 && dt_high_flag == 0) {
dt_high_flag = 1;
}
if (DT_in == 0 && dt_high_flag == 1) {
dt_high_flag = 0;
if (CLK_in == 1) {
direction = 0;
} else {
direction = 1;
}
if (direction == 1) {
encoder_cnt++;
} else {
encoder_cnt--;
}
printf("direction=%d\r\n", (int) direction);
printf("encoder_cnt=%d\r\n", encoder_cnt);
}
}
}
順時(shí)針轉(zhuǎn)一圈可以得到一些結(jié)果,這個(gè)旋鈕有明顯的觸感。順時(shí)針轉(zhuǎn)一個(gè)刻度就加1,逆時(shí)針轉(zhuǎn)一個(gè)刻度就減1。
direction=1
encoder_cnt=100001
direction=1
encoder_cnt=100002
direction=1
encoder_cnt=100003
direction=1
encoder_cnt=100004
direction=1
encoder_cnt=100005
direction=1
encoder_cnt=100006
direction=1
encoder_cnt=100007
direction=1
encoder_cnt=100008
direction=1
encoder_cnt=100009
direction=0
encoder_cnt=100008
direction=1
encoder_cnt=100009
direction=1
encoder_cnt=100010
direction=1
encoder_cnt=100011
direction=1
encoder_cnt=100012
direction=1
encoder_cnt=100013
direction=1
encoder_cnt=100014
direction=1
encoder_cnt=100015
direction=1
encoder_cnt=100016
direction=1
encoder_cnt=100017
direction=1
encoder_cnt=100018
direction=1
encoder_cnt=100019
direction=1
encoder_cnt=100020
用外部中斷檢測(cè)下降沿
將DT輸入設(shè)置為外部中斷 ,下降沿觸發(fā),明顯好用多了。
#include "sys.h"
#include "usart.h"
//旋轉(zhuǎn)編碼器
//CLK--PA0
//DT---PA1
//SW---PA2
#define CLK_in PAin(0)
#define DT_in PAin(1)
#define SW_in PAin(2)
u32 encoder_cnt = 100000;//旋轉(zhuǎn)脈沖計(jì)數(shù)
u8 direction = 0;//旋轉(zhuǎn)方向 1正傳
u8 dt_high_flag = 0;
void rotary_encoder_Init(void) {
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* 使能時(shí)鐘 */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* 關(guān)閉JTAG功能 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* 使能時(shí)鐘 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* 設(shè)置成上拉輸入 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
//將DT_in PAin(1)設(shè)置為外部中斷,下降沿觸發(fā)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line = EXTI_Line1; /* 外部中斷線1 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /* 設(shè)置為中斷請(qǐng)求 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /* 下降沿觸發(fā) */
EXTI_InitStructure.EXTI_LineCmd = ENABLE; /* 使能中斷 */
EXTI_Init(&EXTI_InitStructure); /* 配置 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; /* 外部中斷1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; /* 搶占優(yōu)先級(jí)2 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; /* 子優(yōu)先級(jí)2 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 使能中斷 */
NVIC_Init(&NVIC_InitStructure); /* 配置 */
}
void EXTI1_IRQHandler(void) {
if (CLK_in == 1) {
direction = 0;
} else {
direction = 1;
}
if (direction == 1) {
encoder_cnt++;
} else {
encoder_cnt--;
}
printf("direction=%d\r\n", (int) direction);
printf("encoder_cnt=%d\r\n", encoder_cnt);
EXTI_ClearITPendingBit(EXTI_Line1); /* 清除LINE1上的中斷標(biāo)志位 */
}
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí) */
delay_init(); /* 延時(shí)函數(shù)初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* 關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試 */
delay_ms(500); /* 等待穩(wěn)定 */
uart_init(115200);
rotary_encoder_Init();
while (1) {
if (SW_in == 0) {
delay_ms(10);
if (SW_in == 0) {
printf("SW_in=0\r\n");
while (SW_in == 0);
}
}
}
}
當(dāng)然需要記得添加庫(kù)文件:
定時(shí)器直接解碼旋轉(zhuǎn)編碼器
下圖是定時(shí)器相關(guān)引腳:
STM32中文參考手冊(cè)V10.pdf
普通定時(shí)器TIM2~TIM5都有這樣的功能:
定時(shí)器的編碼器模式
這張圖是很重要的,如果我們這樣配置:
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式1
TIM_EncoderMode_TI1就是編碼模式,TIM_ICPolarity_Rising和TIM_ICPolarity_Rising就是信號(hào)捕獲邊沿選擇。
這張圖告訴我們,編碼器接收到AB相位是要同步的時(shí)候才會(huì)計(jì)數(shù),有毛刺編碼器是不會(huì)計(jì)數(shù)的。
而且還告訴我們,編碼器順時(shí)針旋轉(zhuǎn),逆時(shí)針旋轉(zhuǎn),我們的計(jì)數(shù)器是會(huì)對(duì)應(yīng)增加或者減小的。
TIM2定時(shí)器編碼器程序
#include "sys.h"
#include "usart.h"
//旋轉(zhuǎn)編碼器
//CLK--PA0
//DT---PA1
#define CLK_in PAin(0)
#define DT_in PAin(1)
/**************************************************************************
函數(shù)功能:把TIM2初始化為編碼器接口模式
**************************************************************************/
void Encoder_Init_TIM2(u16 arr, u16 psc) {
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能TIM4時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //選擇你要設(shè)置的IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設(shè)置傳輸速率
GPIO_Init(GPIOA, &GPIO_InitStructure); /* 初始化GPIO */
TIM_TimeBaseStructure.TIM_Period = arr; //自動(dòng)裝載值
TIM_TimeBaseStructure.TIM_Prescaler = psc; //分頻系數(shù)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設(shè)置向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //通道1
TIM_ICInitStructure.TIM_ICFilter = 0x03; //濾波
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //分頻系數(shù)
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA0直接映射到TI1
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //通道1
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA1直接映射到TI2
TIM_ICInit(TIM2, &TIM_ICInitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//搶占優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式1
//TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式3
TIM_ICStructInit(&TIM_ICInitStructure); //將結(jié)構(gòu)體中的內(nèi)容缺省輸入
TIM_ICInitStructure.TIM_ICFilter = 10;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新標(biāo)志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//運(yùn)行更新中斷
TIM_SetCounter(TIM2, 10000);//初始化計(jì)數(shù)器初值
TIM_Cmd(TIM2, ENABLE); //使能定時(shí)器
}
// 計(jì)數(shù)超過(guò)arr就會(huì)產(chǎn)生溢出中斷
// 也可以把NVIC_Init(&NVIC_InitStructure);注釋掉就不要開(kāi)啟中斷
void TIM2_IRQHandler(void) {
if (TIM2->SR & 0X0001)//溢出中斷
{
printf("interrupt\r\n");
}
TIM2->SR &= ~(1 << 0);//清除中斷標(biāo)志位
}
short Read_Encoder(u8 TIMX) {
unsigned Encoder_TIM;
switch (TIMX) {
case 2:
Encoder_TIM = (short) TIM2->CNT;
TIM2->CNT = 0;
break;
case 3:
Encoder_TIM = (short) TIM3->CNT;
TIM3->CNT = 0;
break;
case 4:
Encoder_TIM = (short) TIM4->CNT;
break;
default:
Encoder_TIM = 0;
}
return Encoder_TIM;
}
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí) */
delay_init(); /* 延時(shí)函數(shù)初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* 關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試 */
delay_ms(500); /* 等待穩(wěn)定 */
uart_init(115200);
Encoder_Init_TIM2(0xffff, 0); //初始化TIM2為編碼器接口模式
while (1) {
printf("%d \r\n", (int) TIM_GetCounter(TIM2));
}
}
旋轉(zhuǎn)編碼器就可以看到計(jì)數(shù)器的變化了:
TIM3定時(shí)器編碼器程序
類(lèi)似地寫(xiě)程序即可。
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-644350.html
#include "sys.h"
#include "usart.h"
//旋轉(zhuǎn)編碼器
//CLK--PA6
//DT---PA7
#define CLK_in PAin(6)
#define DT_in PAin(7)
/**************************************************************************
函數(shù)功能:把TIM3初始化為編碼器接口模式
**************************************************************************/
void Encoder_Init_TIM3(u16 arr, u16 psc) {
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能TIM4時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //選擇你要設(shè)置的IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設(shè)置傳輸速率
GPIO_Init(GPIOA, &GPIO_InitStructure); /* 初始化GPIO */
TIM_TimeBaseStructure.TIM_Period = arr; //自動(dòng)裝載值
TIM_TimeBaseStructure.TIM_Prescaler = psc; //分頻系數(shù)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設(shè)置向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //通道1
TIM_ICInitStructure.TIM_ICFilter = 0x03; //濾波
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //分頻系數(shù)
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA6直接映射到TI1
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //通道1
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA7直接映射到TI2
TIM_ICInit(TIM3, &TIM_ICInitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//搶占優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式1
//TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式3
TIM_ICStructInit(&TIM_ICInitStructure); //將結(jié)構(gòu)體中的內(nèi)容缺省輸入
TIM_ICInitStructure.TIM_ICFilter = 10;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);//清除TIM的更新標(biāo)志位
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//運(yùn)行更新中斷
TIM_SetCounter(TIM3, 10000);//初始化計(jì)數(shù)器初值
TIM_Cmd(TIM3, ENABLE); //使能定時(shí)器
}
// 計(jì)數(shù)超過(guò)arr就會(huì)產(chǎn)生溢出中斷
// 也可以把NVIC_Init(&NVIC_InitStructure);注釋掉就不要開(kāi)啟中斷
void TIM3_IRQHandler(void) {
if (TIM3->SR & 0X0001)//溢出中斷
{
printf("interrupt\r\n");
}
TIM3->SR &= ~(1 << 0);//清除中斷標(biāo)志位
}
short Read_Encoder(u8 TIMX) {
unsigned Encoder_TIM;
switch (TIMX) {
case 2:
Encoder_TIM = (short) TIM2->CNT;
TIM2->CNT = 0;
break;
case 3:
Encoder_TIM = (short) TIM3->CNT;
TIM3->CNT = 0;
break;
case 4:
Encoder_TIM = (short) TIM4->CNT;
break;
default:
Encoder_TIM = 0;
}
return Encoder_TIM;
}
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí) */
delay_init(); /* 延時(shí)函數(shù)初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* 關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試 */
delay_ms(500); /* 等待穩(wěn)定 */
uart_init(115200);
Encoder_Init_TIM3(0xffff, 0); //初始化TIM2為編碼器接口模式
while (1) {
printf("%d \r\n", (int) TIM_GetCounter(TIM3));
}
}
TIM4定時(shí)器編碼器程序
類(lèi)似地寫(xiě)程序即可。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-644350.html
#include "sys.h"
#include "usart.h"
//旋轉(zhuǎn)編碼器
//CLK--PB6
//DT---PB7
#define CLK_in PBin(6)
#define DT_in PBin(7)
/**************************************************************************
函數(shù)功能:把TIM4初始化為編碼器接口模式
**************************************************************************/
void Encoder_Init_TIM4(u16 arr, u16 psc) {
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//使能TIM4時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //選擇你要設(shè)置的IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設(shè)置傳輸速率
GPIO_Init(GPIOB, &GPIO_InitStructure); /* 初始化GPIO */
TIM_TimeBaseStructure.TIM_Period = arr; //自動(dòng)裝載值
TIM_TimeBaseStructure.TIM_Prescaler = psc; //分頻系數(shù)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設(shè)置向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //通道1
TIM_ICInitStructure.TIM_ICFilter = 0x03; //濾波
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //分頻系數(shù)
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA6直接映射到TI1
TIM_ICInit(TIM4, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //通道1
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA7直接映射到TI2
TIM_ICInit(TIM4, &TIM_ICInitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;//中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//搶占優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式1
//TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用編碼器模式3
TIM_ICStructInit(&TIM_ICInitStructure); //將結(jié)構(gòu)體中的內(nèi)容缺省輸入
TIM_ICInitStructure.TIM_ICFilter = 10;
TIM_ICInit(TIM4, &TIM_ICInitStructure);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM的更新標(biāo)志位
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//運(yùn)行更新中斷
TIM_SetCounter(TIM4, 10000);//初始化計(jì)數(shù)器初值
TIM_Cmd(TIM4, ENABLE); //使能定時(shí)器
}
// 計(jì)數(shù)超過(guò)arr就會(huì)產(chǎn)生溢出中斷
// 也可以把NVIC_Init(&NVIC_InitStructure);注釋掉就不要開(kāi)啟中斷
void TIM4_IRQHandler(void) {
if (TIM4->SR & 0X0001)//溢出中斷
{
printf("interrupt\r\n");
}
TIM4->SR &= ~(1 << 0);//清除中斷標(biāo)志位
}
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí) */
delay_init(); /* 延時(shí)函數(shù)初始化 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); /* 關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試 */
delay_ms(500); /* 等待穩(wěn)定 */
uart_init(115200);
Encoder_Init_TIM4(0xffff, 0); //初始化TIM2為編碼器接口模式
while (1) {
printf("%d \r\n", (int) TIM_GetCounter(TIM4));
}
}
到了這里,關(guān)于【單片機(jī)】STM32單片機(jī)讀取旋轉(zhuǎn)編碼器,TIM定時(shí)器編碼器模式捕獲,程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!