STM32学习笔记——基于正点原子例程编码器模式小结
STM32學(xué)習(xí)筆記——基于正點(diǎn)原子例程編碼器模式小結(jié)
最近一段時間學(xué)習(xí)了,STM32f4的編碼器功能,經(jīng)過自己探索和他人的熱心幫助,對于編碼器模式有了一定了解。STM32f4單片機(jī)提供編碼器模式,以便用戶可以直接使用編碼器模式讀出編碼器所傳輸?shù)奈恢眯畔?#xff0c;供單片機(jī)進(jìn)行下一步操作。
本文章所使用的編碼器為直流電機(jī)尾部自帶的編碼器。
學(xué)習(xí)STM32編碼器模式,首先應(yīng)該知道其模式返回的值所代表的含義是什么,正交編碼器模式在對應(yīng)的定時器數(shù)據(jù)寄存器TIMX->CNT中的值反映的是編碼器所處的“位置”,或者所是角度(個人理解就是其所記錄的脈沖次數(shù)),正負(fù)號代表編碼器是正轉(zhuǎn)還是反轉(zhuǎn)。開始編程之前,首先應(yīng)該知道自己所用的編碼器的線數(shù)(所謂線數(shù),個人理解就是電機(jī)轉(zhuǎn)一圈,所使用的編碼器單獨(dú)一相所產(chǎn)生的脈沖數(shù)是多少),常見的有130、260、390、780。如果實(shí)在不知道自己所用的編碼器的線數(shù),可以在編編好程序后,手動把電機(jī)轉(zhuǎn)一圈,使用串口讀出此時定時器數(shù)據(jù)寄存器TIMX->CNT中的值然后除以自己所設(shè)置的是幾倍頻,對照編碼器常用的線數(shù)規(guī)格,取接近值。
STM32f4正交編碼器設(shè)置步驟
本設(shè)置以16位通用定時器TIM4為例
步驟一:設(shè)置初始化結(jié)構(gòu)體變量
GPIO_InitTypeDef GPIO_InitStructure;//定時器4對應(yīng)IO端口初始化變量TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定時器4初始化變量TIM_ICInitTypeDef TIM_ICInitStructure;//定時器4輸入捕獲參數(shù)步驟二:時鐘設(shè)置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//GPIO時鐘設(shè)置RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//TIM4時鐘設(shè)置步驟三:GPIO口設(shè)置
GPIO_StructInit(&GPIO_InitStructure); //端口復(fù)位,避免干擾GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;//初始化TIM4ch1和ch2通道端口,D12、D13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//端口復(fù)用模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空模式GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//時鐘頻率100MHZGPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD 端口 GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4);GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4);//GPIOD12、D13復(fù)用為TIM4_CH1,CH2步驟四:TIM4定時器模式設(shè)置
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);//結(jié)構(gòu)體參數(shù)設(shè)置設(shè)為默認(rèn)值TIM_TimeBaseStructure.TIM_Period = 520-1;//自動重裝載值為520,這里我采用二倍頻技術(shù),編碼器線數(shù)為260 TIM_TimeBaseStructure.TIM_Prescaler = 0;//預(yù)分頻系數(shù)為1TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計(jì)數(shù)模式TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);//對TIM4初始化步驟五:TIM4輸入捕獲模式參數(shù)設(shè)置
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);//正交編碼器模式,A,B兩相都記錄上升沿跳變,二倍頻技術(shù) TIM_ICStructInit(&TIM_ICInitStructure); //結(jié)構(gòu)體參數(shù)設(shè)置設(shè)為默認(rèn)值TIM_ICInitStructure.TIM_ICFilter = 0; //濾波次數(shù)為1TIM_ICInit(TIM4, &TIM_ICInitStructure);//輸入捕獲初始化TIM_ClearFlag(TIM4, TIM_FLAG_Update); //TIM4更新中斷標(biāo)志清零步驟六:其余參數(shù)設(shè)置
TIM_SetCounter(TIM4,0);//TIM4數(shù)據(jù)寄存器清零TIM_Cmd(TIM4, ENABLE); //使能TIM4步驟七:讀取函數(shù)
//定時器5中斷服務(wù)函數(shù) void TIM5_IRQHandler(void) {if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //是否產(chǎn)生更新(溢出)中斷{printf("\\n編碼器值為:%d\n",TIM4->CNT);}TIM_ClearITPendingBit(TIM5,TIM_IT_Update); //清空TIM5中斷標(biāo)志位 }整體代碼
GPIO_InitTypeDef GPIO_InitStructure;//定時器4對應(yīng)IO端口初始化變量TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定時器4初始化變量TIM_ICInitTypeDef TIM_ICInitStructure;//定時器4輸入捕獲參數(shù)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//GPIO時鐘設(shè)置RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//TIM4時鐘設(shè)置GPIO_StructInit(&GPIO_InitStructure); //端口復(fù)位,避免干擾GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;//初始化TIM4ch1和ch2通道端口,D12、D13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//端口復(fù)用模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//浮空模式GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//時鐘頻率100MHZGPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD 端口 GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4);GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4);//GPIOD12、D13復(fù)用為TIM4_CH1,CH2TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);//結(jié)構(gòu)體參數(shù)設(shè)置設(shè)為默認(rèn)值TIM_TimeBaseStructure.TIM_Period = 520-1;//自動重裝載值為520,這里我采用二倍頻技術(shù),編碼器線數(shù)為260 TIM_TimeBaseStructure.TIM_Prescaler = 0;//預(yù)分頻系數(shù)為1TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計(jì)數(shù)模式TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);//對TIM4初始化TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);//正交編碼器模式,A,B兩相都記錄上升沿跳變,二倍頻技術(shù) TIM_ICStructInit(&TIM_ICInitStructure); //結(jié)構(gòu)體參數(shù)設(shè)置設(shè)為默認(rèn)值TIM_ICInitStructure.TIM_ICFilter = 0; //濾波次數(shù)為1TIM_ICInit(TIM4, &TIM_ICInitStructure);//輸入捕獲初始化TIM_ClearFlag(TIM4, TIM_FLAG_Update); //TIM4更新中斷標(biāo)志清零TIM_SetCounter(TIM4,0);//TIM4數(shù)據(jù)寄存器清零TIM_Cmd(TIM4, ENABLE); //使能TIM4//定時器5中斷服務(wù)函數(shù) void TIM5_IRQHandler(void) {if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //是否產(chǎn)生更新(溢出)中斷{printf("\\n編碼器值為:%d\n",TIM4->CNT);}TIM_ClearITPendingBit(TIM5,TIM_IT_Update); //清空TIM5中斷標(biāo)志位 }本文之前采用四倍頻設(shè)置,但問過小伙伴后,小伙伴說官網(wǎng)的四倍頻程序有問題,建議我我采用二倍頻設(shè)置,自己也經(jīng)過實(shí)驗(yàn)驗(yàn),發(fā)現(xiàn)當(dāng)正交編碼器模式設(shè)置四倍頻時,電機(jī)轉(zhuǎn)一圈所得的脈沖數(shù)是二倍頻模式的一半,二倍頻為精度最高的模式,所以設(shè)置為二倍頻設(shè)置
總結(jié)
以上是生活随笔為你收集整理的STM32学习笔记——基于正点原子例程编码器模式小结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。