k60的FTM模块:配置电机、编码器、舵机
FTM模塊既可以用于PWM模式來產(chǎn)生PWM波控制電機(jī)和舵機(jī),也可以用于正交解碼模式用于讀取編碼器的脈沖數(shù),從而實(shí)現(xiàn)測速。對于有兩個(gè)電機(jī)的智能車,兩個(gè)電機(jī)需要4路PWM波即對應(yīng)著4個(gè)FTM通道(根據(jù)底層庫文檔:FTM0有8個(gè)通道,而FTM1、FTM2都只有2個(gè)通道,因此最好用FTM0來控制兩個(gè)電機(jī)),兩個(gè)編碼器也需要4路通道來解碼(用掉了FTM1和FTM2),剩下的舵機(jī)則只能用PIT定時(shí)器來模擬出一個(gè)PWM波了
觀察上圖,一旦你選定FTM模塊號(hào)(FTM0、1、2)和對應(yīng)的通道號(hào),那么引腳也就確定下來了。或者,即使你仍舊還是配置了對應(yīng)的GPIO口,那么這些GPIO口必須與用到的這些FTM通道對應(yīng)的引腳一致
一、電機(jī)配置
只需配置對應(yīng)的額FTM模塊即可,在畫原理圖時(shí)電機(jī)需要接和FTM通道所對應(yīng)的的那幾個(gè)引腳。接下來是配置FTM來驅(qū)動(dòng)電機(jī)
FTM結(jié)構(gòu)體:
1.聲明FTM的配置結(jié)構(gòu)體
static FTM_InitTypeDef FTM_Init;2.選擇FTM模塊號(hào)(0、1、2共三個(gè),區(qū)別在于通道數(shù)不同,對應(yīng)的引腳有差別)
FTM_Init.FTM_Ftmx = FTM0;//選擇FTM0號(hào)3.選擇FTM的工作模式——選擇PWM模式。產(chǎn)生PWM波可以驅(qū)動(dòng)電機(jī),正交解碼主要用于編碼器計(jì)脈沖數(shù)來測速
FTM_Init.FTM_Mode = FTM_MODE_PWM;//PWM模式4.在PWM模式下需要確定輸出頻率。即一個(gè)周期最多有多少份,占空比不同,則控制電機(jī)的轉(zhuǎn)速不同
FTM_Init.FTM_PwmFreq = 15000;//總共15000份5.死區(qū)設(shè)置。防止同一個(gè)電機(jī)下的兩路同時(shí)導(dǎo)通造成破壞,因此,4路共需要2個(gè)死區(qū)。
FTM_Init.FTM_PwmDeadtimeVal = 2;//死區(qū)個(gè)數(shù)為2 FTM_Init.FTM_PwmDeadtimeCfg = DEADTIME_CH45 | DEADTIME_CH67;//在通道4、5之間,6、7之間各插入一個(gè)死區(qū)6.初始化或者使能
LPLD_FTM_Init(FTM_Init);//配置初始化//使能,并且可以選定通道和引腳的對應(yīng)關(guān)系 LPLD_FTM_PWM_Enable(FTM0, FTM_Ch4, 0, PTD4, ALIGN_LEFT);//FTM0的通道ch4和引腳PTD4對應(yīng) LPLD_FTM_PWM_Enable(FTM0, FTM_Ch5, 0, PTD5, ALIGN_LEFT); LPLD_FTM_PWM_Enable(FTM0, FTM_Ch6, 0, PTD6, ALIGN_LEFT); LPLD_FTM_PWM_Enable(FTM0, FTM_Ch7, 0, PTD7, ALIGN_LEFT);使能過程確定了很多配置:模塊號(hào)、通道號(hào)、初始占空比、通道號(hào)對應(yīng)的引腳號(hào)、脈沖對齊方式
7.控制電機(jī)的轉(zhuǎn)動(dòng)
8.進(jìn)一步的,在中斷中調(diào)用電機(jī)占空比的修改函數(shù),這樣就涉及到了定時(shí)器PIT的配置以及對應(yīng)的中斷優(yōu)先級的配置,以下簡單說明:
8.1 PIT的配置
PIT模塊號(hào)有0、1、2、3,共4個(gè)定時(shí)器
定時(shí)周期T:每隔T時(shí)間就會(huì)觸發(fā)一次定時(shí)器中斷,調(diào)用對應(yīng)的中斷函數(shù)
中斷函數(shù):周期調(diào)用此函數(shù),故可以把電機(jī)輸出函數(shù)放在這里從而實(shí)現(xiàn)周期控制電機(jī)輸出而不是一直控制,造成資源浪費(fèi)
8.2 PIT中斷優(yōu)先級的配置
static NVIC_InitTypeDef NVIC_InitStructure;//聲明NVIC配置結(jié)構(gòu)體 NVIC_InitStructure.NVIC_IRQChannel = PIT0_IRQn;//要配置的那個(gè)中斷號(hào)即配置PIT0中斷 NVIC_InitStructure.NVIC_IRQChannelGroupPriority = NVIC_PriorityGroup_2;//中斷分組 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//配置搶占式優(yōu)先級為最高級 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//配置響應(yīng)式優(yōu)先級為次高級 LPLD_NVIC_Init(NVIC_InitStructure);//初始化NVIC8.3 編寫中斷函數(shù)
void pit0_isr() {//每5ms修改一次電機(jī)轉(zhuǎn)速MotorOut(&PWM); }8.4 另外,上面這些函數(shù)顯然不能都放在一個(gè).c文件中,由此又涉及到了多個(gè).c文件之間的協(xié)調(diào),主要就在對應(yīng)的.h文件的編寫
8.5 PWM[ ]數(shù)組來自于根據(jù)速度偏差和PID算法計(jì)算出來的,在初期可先用常數(shù)值控制讓小車勻速運(yùn)動(dòng),然后再添加控制程序
二、編碼器配置
編碼器用的是FTM的正交解碼模式,這里配置了一個(gè)編碼器
1.配置GPIO口,這些GPIO口和FTM正交解碼通道對應(yīng)
2.配置FTM為正交解碼模式
static FTM_InitTypeDef Init_FTM_Struct;//聲明結(jié)構(gòu)體 Init_FTM_Struct.FTM_Ftmx = FTM2;//選擇模塊號(hào) Init_FTM_Struct.FTM_Mode = FTM_MODE_QD;//正交解碼模式 Init_FTM_Struct.FTM_QdMode = QD_MODE_PHAB;//AB相解碼模式,和編碼器類型有關(guān) LPLD_FTM_Init(Init_FTM_StructR); LPLD_FTM_QD_Enable(FTM2, PTB18, PTB19);//使能,將模塊號(hào)和引腳對應(yīng)3 . 獲取編碼器數(shù)值
4 . 定時(shí)器周期調(diào)用GetSpeed()函數(shù),先配置PIT(同前面),然后放在PIT中斷函數(shù)中以實(shí)現(xiàn)周期調(diào)用
5 . 由編碼器脈沖數(shù)推測速度和行駛距離。設(shè)調(diào)用周期是T,行駛1m所產(chǎn)生的脈沖數(shù)是C,在T時(shí)間內(nèi)調(diào)用GetSpeed()函數(shù)得到的脈沖數(shù)是L_count,則1s內(nèi)產(chǎn)生的脈沖數(shù)應(yīng)該是 L_count / T,對應(yīng)的距離應(yīng)該是(L_count / T)/ C,也就是1s內(nèi)的行駛距離即速度
6 .根據(jù)測的當(dāng)前速度和設(shè)定目標(biāo)速度求速度偏差,然后通過PID算法算出應(yīng)該輸出的PWM占空比值,輸出到電機(jī)
三、舵機(jī)控制
1.需配置舵機(jī)信號(hào)線 —— GPIO口
2 . PIT模擬產(chǎn)生PWM波。先是定時(shí)調(diào)用舵機(jī)輸出即信號(hào)線拉高,然后用這個(gè)PIT定時(shí)再把舵機(jī)輸出拉低,需要兩個(gè)PIT
2.1 配置PIT0來定時(shí)調(diào)用舵機(jī)輸出
void pit0_isr() {//定時(shí)調(diào)用舵機(jī)輸出ServOut(pwm); }2.2 配置PIT1來定時(shí)拉低舵機(jī)PWM從而實(shí)現(xiàn)模擬PWM波
static PIT_InitTypeDef Servo_pit; Servo_pit.PIT_Isr = Servo_pit_isr;//中斷函數(shù) Servo_pit.PIT_PeriodUs = 200000;//200ms,隨便寫的,不影響 Servo_pit.PIT_Pitx = PIT1;//模塊號(hào) LPLD_PIT_Init(Servo_pit); LPLD_PIT_EnableIrq(Servo_pit);PIT->CHANNEL[1].TCTRL &= ~PIT_TCTRL_TEN_MASK;//停止計(jì)時(shí)。然后過了20ms再通過PIT1中斷函數(shù)開始計(jì)時(shí),實(shí)現(xiàn)了每20ms反轉(zhuǎn)一次電平 // 上面是配置舵機(jī)的程序片段//PIT1的中斷函數(shù) void Servo_pit_isr() {PTD12_O = 0;//拉低PIT->CHANNEL[1].TCTRL &= ~PIT_TCTRL_TEN_MASK;//修改寄存器的值以停止計(jì)時(shí) }//舵機(jī)輸出,每20ms調(diào)用一次,由PIT0的中斷函數(shù)調(diào)用 void ServOut(pwm) {PIT->CHANNEL[1].LDVAL = pwm*(g_bus_clock / 1000000) - 1;//把PID計(jì)算出的打角轉(zhuǎn)成占空比加載到PIT的LDVAL寄存器中PTD12_O = 1;//信號(hào)線電平拉高PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK;//開始計(jì)時(shí)即CVAL寄存器開始自減,減到0則觸發(fā)PIT1的中斷,//對應(yīng)的中斷函數(shù)Servo_pit_isr中執(zhí)行的是把電平拉低并停止計(jì)時(shí) }//上面是兩個(gè)PIT配合形成的PWM波LDVAL寄存器:存放計(jì)數(shù)值,自減,當(dāng)減到0時(shí),PIT就會(huì)觸發(fā)中斷。但真正自減的并不是這個(gè)寄存器而是另外一個(gè)即CVAL寄存器,當(dāng)CVAL減到0,PIT重新把LDVAL的值加載到CVAL寄存器
CVAL寄存器:真正在自減的寄存器,減到0則觸發(fā)中斷
TCTRL寄存器:2位可用,一位決定定時(shí)器是否開始工作即CVAL寄存器是否開始自減,一位決定是否產(chǎn)生定時(shí)中斷
過程圖示為:
觀察發(fā)現(xiàn):
Servout()函數(shù)調(diào)用周期是20ms(由PIT0決定),而且主要負(fù)責(zé)拉高電平和給PIT1的LVDAL賦值即決定PIT1的中斷周期,這時(shí)PIT1的中斷周期不再是配置時(shí)的那個(gè)200ms了。當(dāng)LVDAL加載的時(shí)間用盡而觸發(fā)了PIT1的中斷,調(diào)用對應(yīng)的Servo_pit_isr()中斷函數(shù)再把舵機(jī)信號(hào)線電平拉低并且停止計(jì)時(shí),等待下一次給LVDAL裝載值,而這個(gè)下一次給LVDAL裝載值就是下一次調(diào)用Servout()函數(shù)(此時(shí)距上次過去了20ms)
至于為什么是20ms,這和舵機(jī)基準(zhǔn)信號(hào)的周期是20ms有關(guān),可參考這篇介紹:https://blog.csdn.net/weixin_38907560/article/details/81546006
通過兩個(gè)PIT的配合,我們模擬出了一個(gè)PWM波,其中PIT0負(fù)責(zé)拉高和決定高電平持續(xù)時(shí)間,PIT1負(fù)責(zé)拉低電平
總結(jié)一下:
1.電機(jī):FTM的PWM工作模式,一個(gè)電機(jī)有兩路分別控制正反轉(zhuǎn),不能同時(shí)導(dǎo)通,需要配置死區(qū),使能的時(shí)候把通道號(hào)與引腳號(hào)對應(yīng)起來,通過底層庫函數(shù)修改占空比值來控制電機(jī)轉(zhuǎn)速,最好在中斷中調(diào)用
2.編碼器:FTM的正交解碼模式,一個(gè)編碼器有兩路(AB相或者方向計(jì)數(shù)),可通過庫函數(shù)直接讀取對應(yīng)FTM的值即編碼器的值,同樣最好是在中斷中調(diào)用,并介紹了如何由編碼器計(jì)數(shù)值來推測小車的速度和行駛的距離
3.舵機(jī):舵機(jī)的基準(zhǔn)信號(hào)的周期是20ms,因此調(diào)用舵機(jī)輸出函數(shù)的周期也是20ms(是為了配合模擬PWM波),一個(gè)函數(shù)負(fù)責(zé)拉高信號(hào)線電平和決定高電平持續(xù)時(shí)間,一個(gè)負(fù)責(zé)拉低電平
以上是我關(guān)于電機(jī)、編碼器、舵機(jī)方面配置的總結(jié)
總結(jié)
以上是生活随笔為你收集整理的k60的FTM模块:配置电机、编码器、舵机的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 临时文件_在Java中使用临时
- 下一篇: 数据结构练习题——图(含应用题)