一、微項目實現(xiàn)目標(biāo):
檢測旋轉(zhuǎn)編碼器模式下,檢測旋轉(zhuǎn)編碼器的轉(zhuǎn)動計數(shù)值及轉(zhuǎn)速。并且區(qū)分轉(zhuǎn)向,一側(cè)轉(zhuǎn)動增加cout,轉(zhuǎn)速值為正,一側(cè)轉(zhuǎn)動減少count,轉(zhuǎn)速值為負;
?
二、微項目硬件配置需求:
1,stm32F103C8T6核心板一塊
2,0.96寸OLED顯示,用于顯示計數(shù)
3,旋轉(zhuǎn)編碼器,反饋正交信號脈沖
三、前置知識:
1,編碼器計數(shù)模式框圖
?①信號流:
兩路GIPO輸入---濾波器----邊沿檢測極性選擇---輸入TI1FP1和TI2FP2給到編碼器接口---根據(jù)相位模式(T1和T2的相位之差)判斷CNT是向上計數(shù)還是向下計數(shù)-----經(jīng)過分頻器處理,最后實現(xiàn)計數(shù)
②計數(shù)模式
?如果一直向下計數(shù)到0,在繼續(xù)計數(shù)時,則寄存器數(shù)據(jù)由于無符號整型緣故,會變成65535,由于數(shù)據(jù)以補碼的形式存儲,則強轉(zhuǎn)為int時刻,會變成-1;
③旋轉(zhuǎn)編碼器的輸入波形情況
正轉(zhuǎn)時刻,A相輸出超出B相輸出90度
反轉(zhuǎn)時刻,A相輸出滯后B相輸出90度
?④設(shè)置正相模式與反相模式
就是對于計數(shù)模式的一次反向處理,并對應(yīng)到原本的計數(shù)模式上(一般用的較少)
反向之后
?
?
四、代碼邏輯分析:
①打開TIM3和GPIOA的時鐘
②配置GPIOA的PA5和PA6
③初始化時基模塊(注意,在編碼器模式下,不需要配置時鐘源,輸入的TI1FP1或TI2FP2作為時鐘),主要是指ARR和PSC
④初始化輸入捕獲模塊,通道1 和通道2都需要配置
⑤配置配置編碼器接口
⑥開啟時鐘模塊
五、代碼示例:
①打開TIM3和GPIOA的時鐘
//初始化時鐘TIM3 ,PA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
②配置GPIOA的PA5和PA6,上拉輸入
//配置PA6\PA7輸入GPIO
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStruct);
③初始化時基模塊(注意,在編碼器模式下,不需要配置時鐘源,輸入的TI1FP1或TI2FP2作為時鐘),主要是指ARR和PSC
//初始化時基模塊
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1 ;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//在編碼器模式下,此參數(shù)無作用
TIM_TimeBaseInitStruct.TIM_Period=65536-1;//ARR
TIM_TimeBaseInitStruct.TIM_Prescaler=1-1;//PSC,不分頻
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct);
④初始化輸入捕獲模塊,通道1 和通道2都需要配置
//輸入捕獲單元配置
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICStructInit(& TIM_ICInitStruct);//先進行默認初始化
TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter=0xf;
TIM_ICInit(TIM3,&TIM_ICInitStruct);//TIM3-CH1通道
TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;
TIM_ICInitStruct.TIM_ICFilter=0xf;
TIM_ICInit(TIM3,&TIM_ICInitStruct);//TIM3-CH2通道
⑤配置配置編碼器接口
//配置編碼器接口
TIM_EncoderInterfaceConfig( TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising
, TIM_ICPolarity_Rising);
⑥開啟時鐘模塊
TIM_Cmd(TIM3,ENABLE);
⑦獲取速度模塊
本質(zhì)上,獲取的是CNT的計數(shù)值,但是如果1S讀取一次,并且清空為0 ,則實現(xiàn)了速度測算的功能
1-注意此處的強制轉(zhuǎn)化為有符號數(shù)據(jù)(反碼存儲)
2-需要配合定時器中斷1S使用(或者延時1S執(zhí)行一次,當(dāng)然中斷的形式更佳)
int16_t getspeedn(void)
{
int16_t temp;
temp= TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return temp;
}
⑧主函數(shù)中配置
1-TIM2_IRQHandler()一秒執(zhí)行文章來源:http://www.zghlxwxcb.cn/news/detail-475626.html
2-speed要整除4,原因是數(shù)據(jù)采樣時刻,一次轉(zhuǎn)動被采樣4次文章來源地址http://www.zghlxwxcb.cn/news/detail-475626.html
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "OLED.H"
#include "encode.h"
#include "timer.h"
int16_t speed=0;
int main()
{
OLED_Init();
encoder_init();
timer_init();
OLED_ShowString(1,1,"count:000");
OLED_ShowString(2,1,"speed:0000rpm");
while(1)
{
OLED_ShowSignedNum(2,7,speed/4,3);
}
}
//中斷服務(wù)函數(shù)
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
speed= getspeedn();
}
TIM_ClearITPendingBit( TIM2,TIM_IT_Update );
}
到了這里,關(guān)于STM32-微項目07-旋轉(zhuǎn)編碼器計數(shù)及測速的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!