国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【單片機(jī)】STM32單片機(jī)讀取旋轉(zhuǎn)編碼器,TIM定時(shí)器編碼器模式捕獲,程序

這篇具有很好參考價(jià)值的文章主要介紹了【單片機(jī)】STM32單片機(jī)讀取旋轉(zhuǎn)編碼器,TIM定時(shí)器編碼器模式捕獲,程序。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

旋轉(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è)波形獲取到信息。

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼
前兩個(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è)輸出引腳。

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

主程序邏輯直接檢測(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ù)文件:
stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

定時(shí)器直接解碼旋轉(zhuǎn)編碼器

下圖是定時(shí)器相關(guān)引腳:

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

STM32中文參考手冊(cè)V10.pdf

普通定時(shí)器TIM2~TIM5都有這樣的功能:
stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

定時(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)增加或者減小的。

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

TIM2定時(shí)器編碼器程序

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(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ù)器的變化了:
stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

TIM3定時(shí)器編碼器程序

類(lèi)似地寫(xiě)程序即可。

stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼

#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ě)程序即可。
stm32旋轉(zhuǎn)編碼器,單片機(jī),單片機(jī),stm32,旋轉(zhuǎn)編碼器程序,定時(shí)器解碼文章來(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)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • (STM32)PWM輸出控制電機(jī)旋轉(zhuǎn)并且使用編碼器讀取脈沖數(shù)

    (STM32)PWM輸出控制電機(jī)旋轉(zhuǎn)并且使用編碼器讀取脈沖數(shù)

    目錄 ?前言 一、pwm輸出讓電機(jī)轉(zhuǎn)? 1.電機(jī)的接線說(shuō)明 2.驅(qū)動(dòng)的接線說(shuō)明 3.pwm輸出代碼 ?pwm.c pwm.h 4.輸出pwm控制電機(jī)旋轉(zhuǎn) 二、配置定時(shí)器編碼器模式 1.定時(shí)器編碼器模式 編碼器原理 編碼器相關(guān)的概念 2.編碼器模式——代碼部分 3.獲取脈沖數(shù) 三、定時(shí)讀取編碼器讀取的脈沖數(shù)

    2024年02月03日
    瀏覽(28)
  • 【32單片機(jī)學(xué)習(xí)】(3)霍爾編碼器減速直流電機(jī)控制及測(cè)速

    【32單片機(jī)學(xué)習(xí)】(3)霍爾編碼器減速直流電機(jī)控制及測(cè)速

    提示:文章寫(xiě)完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔 目錄 前言 1.實(shí)驗(yàn)現(xiàn)象 2.實(shí)驗(yàn)接線及原理圖 接線圖 原理圖? 電機(jī)接線圖 3.代碼部分 1.主函數(shù)? main.c 2.按鍵部分? ?key.c ?key.h pwm代碼? ?pwm.c ?pwm.h 電機(jī)驅(qū)動(dòng)? ?motor.c? ?motor.h ?OLED顯示 oled.c oled.h? 編碼器

    2024年02月11日
    瀏覽(35)
  • 使用STM32CubeProgrammer工具讀取單片機(jī)Flash數(shù)據(jù)讀取

    使用STM32CubeProgrammer工具讀取單片機(jī)Flash數(shù)據(jù)讀取

    本文主要介紹,如何使用STM32CubeProgrammer工具讀取和寫(xiě)入單片機(jī)Flash內(nèi)部的數(shù)據(jù),方便調(diào)試使用。 2.1 連接Stlink和單片機(jī),點(diǎn)擊“connect”進(jìn)行連接 2.2 讀取固定長(zhǎng)度的數(shù)據(jù) 根據(jù)程序的大小,設(shè)置需要讀取的字節(jié)數(shù),如下圖所示。點(diǎn)擊“read”將單片機(jī)Flash中的數(shù)據(jù)讀取到STM32Cube

    2024年02月12日
    瀏覽(81)
  • STM32 EC11 旋轉(zhuǎn)編碼器

    STM32 EC11 旋轉(zhuǎn)編碼器

    代碼在最后,復(fù)制可直接食用 以及我的電路圖 在研究EC11的時(shí)序之前首先要了解一點(diǎn),EC11按旋轉(zhuǎn)的輸出動(dòng)作可以分為兩種。一種是轉(zhuǎn)兩格,A、B對(duì)C端輸出一個(gè)完整脈沖(轉(zhuǎn)一格就只是由低電平-高電平或由高電平-低電平);另一種就是轉(zhuǎn)一格,A、B對(duì)C端輸出一個(gè)完整脈沖。

    2024年02月02日
    瀏覽(29)
  • 【單片機(jī)】DS2431,STM32,EEPROM讀取與寫(xiě)入

    【單片機(jī)】DS2431,STM32,EEPROM讀取與寫(xiě)入

    芯片介紹: https://qq742971636.blog.csdn.net/article/details/132164189 DS2431內(nèi)部有128個(gè)字節(jié)的數(shù)據(jù),這篇博客可以對(duì)這128個(gè)字節(jié)的數(shù)據(jù)進(jìn)行讀寫(xiě),而有的人想要改寫(xiě)芯片ROM,這是芯片的唯一地址,請(qǐng)看這里 https://blog.csdn.net/x1131230123/article/details/135667146 接線 串口結(jié)果: 部分代碼: 代碼:

    2024年02月13日
    瀏覽(25)
  • STM32移植LVGL+旋轉(zhuǎn)編碼器接口對(duì)接

    STM32移植LVGL+旋轉(zhuǎn)編碼器接口對(duì)接

    寫(xiě)在前面:本菜鳥(niǎo)結(jié)合了許多大佬的文章,成功實(shí)現(xiàn)了基于LVGL的GUI設(shè)計(jì),小開(kāi)心~淺淺記錄一下!~ 本文以單片機(jī)STM32F103VET6為核心,利用ST7796芯片驅(qū)動(dòng)分辨率為480*320的LCD液晶屏模塊,移植LVGL,對(duì)接顯示接口,對(duì)接外部接口——旋轉(zhuǎn)編碼器,完成以上兩步,就可以實(shí)現(xiàn)LVGL的顯

    2024年02月10日
    瀏覽(45)
  • STM32-微項(xiàng)目07-旋轉(zhuǎn)編碼器計(jì)數(shù)及測(cè)速

    STM32-微項(xiàng)目07-旋轉(zhuǎn)編碼器計(jì)數(shù)及測(cè)速

    一、微項(xiàng)目實(shí)現(xiàn)目標(biāo): 檢測(cè)旋轉(zhuǎn)編碼器模式下,檢測(cè)旋轉(zhuǎn)編碼器的轉(zhuǎn)動(dòng)計(jì)數(shù)值及轉(zhuǎn)速。并且區(qū)分轉(zhuǎn)向,一側(cè)轉(zhuǎn)動(dòng)增加cout,轉(zhuǎn)速值為正,一側(cè)轉(zhuǎn)動(dòng)減少count,轉(zhuǎn)速值為負(fù); ? 二、微項(xiàng)目硬件配置需求: 1,stm32F103C8T6核心板一塊 2,0.96寸OLED顯示,用于顯示計(jì)數(shù) 3,旋轉(zhuǎn)編碼器,

    2024年02月08日
    瀏覽(23)
  • 【STM32】HAL庫(kù)自學(xué)記錄-旋轉(zhuǎn)編碼器的使用

    【STM32】HAL庫(kù)自學(xué)記錄-旋轉(zhuǎn)編碼器的使用

    通過(guò)本文可學(xué)會(huì)兩種實(shí)現(xiàn)判斷旋轉(zhuǎn)編碼器正轉(zhuǎn)反轉(zhuǎn)的方法,可根據(jù)自己的應(yīng)用場(chǎng)景來(lái)選擇使用哪種方法。 1、芯片:STM32F103RCT6 2、STM32CubeMx軟件 3、IDE: MDK-Keil軟件 4、旋轉(zhuǎn)編碼器模塊 5、XCOM V1.4串口軟件 圖中C端為GND。 方向 :A相和B相相差一個(gè)相位,一般來(lái)說(shuō)是90°。A相信號(hào)在

    2024年02月11日
    瀏覽(27)
  • 關(guān)于stm32旋轉(zhuǎn)編碼器計(jì)次亂跳問(wèn)題(消抖)

    旋轉(zhuǎn)編碼器A口接GPIOB0,B口接GPIOB1。設(shè)置中斷類(lèi)型為上升下降沿均觸發(fā)。 輸出是用0.96寸oled輸出 A腳設(shè)置為上升下降沿均會(huì)進(jìn)中斷,下降上升一個(gè)變換周期,判斷這個(gè)周期的A腳,B腳的始末狀態(tài),來(lái)判斷正反轉(zhuǎn)一次。 A口輸出的波形用來(lái)中斷,B口輸出的波形用來(lái)判斷正轉(zhuǎn)還是反轉(zhuǎn)

    2024年02月16日
    瀏覽(29)
  • 【STM32】STM32學(xué)習(xí)筆記-對(duì)射式紅外傳感器計(jì)次 旋轉(zhuǎn)編碼器計(jì)次(12)

    【STM32】STM32學(xué)習(xí)筆記-對(duì)射式紅外傳感器計(jì)次 旋轉(zhuǎn)編碼器計(jì)次(12)

    相關(guān)頭文件: misc.h 1.1 NVIC_PriorityGroupConfig函數(shù) 1.2 NVIC_PriorityGroup類(lèi)型 1.3 NVIC_Init函數(shù) 1.4 NVIC_InitTypeDef類(lèi)型 NVIC_IRQChannel取值 成員NVIC_IRQChannelPreemptionPriority可賦的值:最大取值15,具體有上面設(shè)置的優(yōu)先級(jí)組中規(guī)定的位數(shù)決定 成員NVIC_IRQChannelSubPriority可賦的值:最大取值15,具體有

    2024年01月15日
    瀏覽(17)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包