脈沖信號(hào)用于設(shè)備控制是比較常見(jiàn)的,但在一些情況下,我們希望精準(zhǔn)的控制脈沖的數(shù)量以實(shí)現(xiàn)對(duì)運(yùn)動(dòng)的精確控制,實(shí)現(xiàn)的方式也有多種多樣。定時(shí)器是單片機(jī)內(nèi)部最基礎(chǔ)且常用的外設(shè),有著非常豐富的功能,如輸入功能(測(cè)量輸入信號(hào)的脈沖寬度、頻率,PWM 輸入等),輸出功能(PWM 輸出、死區(qū)時(shí)間可編程的互補(bǔ)輸出、 單脈沖模式輸出等) ,容易想到使用定時(shí)器輸出PWM來(lái)實(shí)現(xiàn)此類(lèi)操作。
MM32F5270系列集成有豐富的外設(shè)模塊,其中定時(shí)器部分包括 2 個(gè) 16 位高級(jí)定時(shí)器, 2 個(gè) 16 位通用定時(shí)器、 2 個(gè) 32 位通用定時(shí)器, 2 個(gè) 16 位基礎(chǔ)定時(shí)器和1 個(gè)低功耗定時(shí)器。以TIM1為例,該模塊主要由輸入單元、輸出單元、時(shí)基單元、捕獲/比較模塊、剎車(chē)單元等結(jié)構(gòu)組成,功能框圖如下:
這里以MM32F5270定時(shí)器應(yīng)用為例,介紹幾種常用的精準(zhǔn)輸出脈沖數(shù)量的方法:
1?中斷計(jì)數(shù)方式
定時(shí)器配置為PWM輸出模式,在PWM中斷程序中計(jì)數(shù),判斷PWM輸出次數(shù)達(dá)到設(shè)定值時(shí),停止PWM輸出。
中斷計(jì)數(shù)的方式實(shí)現(xiàn)起來(lái)簡(jiǎn)單,但也存在明顯的缺點(diǎn)。當(dāng)PWM頻率較高時(shí),頻繁的中斷將影響程序運(yùn)行的效率,占用大量的MCU資源,這在大多數(shù)情況下是不可接受的。以下幾種方式較為優(yōu)化。
2?定時(shí)器單脈沖重復(fù)計(jì)數(shù)
定時(shí)器單脈沖輸出是定時(shí)器比較輸出中的一種模式,在定時(shí)器比較輸出模式的基礎(chǔ)上進(jìn)行配置。單脈沖模式(OPM)下,計(jì)數(shù)器響應(yīng)一個(gè)激勵(lì),產(chǎn)生一個(gè)脈寬可調(diào)的脈沖。配置 TIMx_CR1 寄存器的OPM=1,選擇單脈沖模式。
單脈沖模式可以使定時(shí)器輸出1個(gè)脈沖,而重復(fù)計(jì)數(shù)器可以用來(lái)調(diào)整更新事件產(chǎn)生的頻率。
邊沿對(duì)齊模式下,向上計(jì)數(shù)時(shí),重復(fù)計(jì)數(shù)器在計(jì)數(shù)器每次上溢時(shí)遞減;向下計(jì)數(shù)時(shí),重復(fù)計(jì)數(shù)器在計(jì)數(shù)器每次下溢時(shí)遞減。中央對(duì)齊模式下,重復(fù)計(jì)數(shù)器在計(jì)數(shù)器上溢和下溢時(shí)皆遞減。通過(guò)配置 TIMx_RCR 寄存器的 REP 來(lái)調(diào)整更新事件產(chǎn)生的頻率,重復(fù)計(jì)數(shù)器在 REP+1 個(gè)計(jì)數(shù)周期后產(chǎn)生更新事件。
配置TIM1輸出PWM,使能單脈沖模式,配置REP(重復(fù)計(jì)數(shù)器的值)為9,即TIM1在輸出10個(gè)脈沖后發(fā)生更新事件,相關(guān)代碼如下:
voidTIM1_Monopulse_Init(u16arr,u16psc) { TIM_TimeBaseInitTypeDefTIM_TimeBaseStruct; TIM_OCInitTypeDefTIM_OCInitStruct; TIM_ICInitTypeDefTIM_ICInitStruct; RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1,ENABLE); TIM_DeInit(TIM1); TIM_TimeBaseStructInit(&TIM_TimeBaseStruct); TIM_TimeBaseStruct.TIM_Period=arr; TIM_TimeBaseStruct.TIM_Prescaler=psc; TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_RepetitionCounter=9; TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStruct); TIM_OCStructInit(&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2; TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse=arr/2; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; TIM_OCInitStruct.TIM_OCIdleState=TIM_OCIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1,ENABLE); TIM_SelectOnePulseMode(TIM1,TIM_OPMode_Single); TIM_SetCounter(TIM1,0); TIM_CtrlPWMOutputs(TIM1,ENABLE); TIM_Cmd(TIM1,ENABLE); }
邏輯分析儀接PA8(程序中配置PA8作為T(mén)IM1_CH1),觀測(cè)輸出波形如下:
由于REP只有8位,所以它最大是255,當(dāng)然也可以進(jìn)行一些判斷后再次賦值,目前只有高級(jí)定時(shí)器具有重復(fù)計(jì)數(shù)功能。
3?DMA方式
使用DMA功能更新PWM的輸出,DMA傳輸將數(shù)據(jù)從一個(gè)地址空間復(fù)制到另一個(gè)地址空間,提供在外設(shè)和存儲(chǔ)器之間或者存儲(chǔ)器和存儲(chǔ)器之間的高速數(shù)據(jù)傳輸。它允許不同速度的硬件裝置來(lái)溝通,而不需要依賴(lài)于MPU的大量中斷負(fù)載。該方式占用很少的MCU資源,實(shí)現(xiàn)脈沖發(fā)送的精確控制。
通過(guò)設(shè)置DMA傳輸數(shù)據(jù)的數(shù)量,可以控制發(fā)送的脈沖數(shù)。通過(guò)設(shè)置不同的裝載值和順序,可以使用不同頻率和脈寬。
TIMx_DCR 和 TIMx_DMAR 寄存器跟 DMA 模式相關(guān)。DMA 控制器的目標(biāo)是唯一的,必須指向TIMx_DMAR 寄存器。開(kāi)啟 DMA 使能后,在給定的 TIMx 事件發(fā)生時(shí), TIMx 會(huì)給 DMA 發(fā)送請(qǐng)求。對(duì)TIMx_DMAR 寄存器的每次寫(xiě)操作都被重定向到一個(gè) TIMx 寄存器。
TIMx_DMAR 連續(xù)模式 DMA 地址寄存器:
TIMx_DCR DMA 控制寄存器:
程序中配置TIM1的更新周期為10ms。
TIM1_PWM_Init(10000-1,SystemCoreClock/1000000-1);
定義一個(gè)數(shù)組,元素的數(shù)量表示可以控制發(fā)送的脈沖數(shù),元素的值表示脈寬。
staticu16data[10]={1000,2000,3000,4000,5000,6000,7000,8000,9000,0};
配置TIM1輸出PWM,相關(guān)代碼同上,使能COM的DMA請(qǐng)求,配置DMA初始化,使能DMA傳輸完成中斷,TIM1_CH1對(duì)應(yīng)DMA1_Channel2。
voidTIM1_DMA_Init(void) { DMA_InitTypeDefDMA_InitStruct; DMA_Channel_TypeDef*channel; channel=DMA1_Channel2; RCC_DMA_ClockCmd(DMA1,ENABLE); DMA_DeInit(channel); DMA_StructInit(&DMA_InitStruct); //Transferregisteraddress DMA_InitStruct.DMA_PeripheralBaseAddr=(u32)&(TIM1->CCR1); //Transfermemoryaddress DMA_InitStruct.DMA_MemoryBaseAddr=(u32)data; //Transferdirection,frommemorytoregister DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST; DMA_InitStruct.DMA_BufferSize=10; DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable; //Transfercompletedmemoryaddressincrement DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//DMA_Mode_Circular; DMA_InitStruct.DMA_Priority=DMA_Priority_High; DMA_InitStruct.DMA_M2M=DMA_M2M_Disable; DMA_InitStruct.DMA_Auto_reload=DMA_Auto_Reload_Disable; DMA_Init(channel,&DMA_InitStruct); DMA_ITConfig(channel,DMA_IT_TC,ENABLE); DMA_Cmd(DMA1_Channel2,ENABLE); }
DMA中斷服務(wù)子程序:
voidDMA1_Channel2_IRQHandler(void) { if(DMA_GetITStatus(DMA1_IT_TC2)){ DMA_ClearITPendingBit(DMA1_IT_TC2); TIM_Cmd(TIM1,DISABLE); } }
邏輯分析儀接PA8(程序中配置PA8作為T(mén)IM1_CH1),觀測(cè)輸出波形如下:
輸出9個(gè)脈沖,脈寬分別為10%、20%、30%......90%。
DMA方式算是一個(gè)很確定的方式,不會(huì)丟失脈沖。當(dāng)需要發(fā)送較多數(shù)量的脈沖時(shí),則可以使用DMA傳輸完成中斷中切換DMA傳輸?shù)臄?shù)據(jù)起始地址及發(fā)送數(shù)量。
4?主從模式
定時(shí)器同步功能可以配置多個(gè)定時(shí)器在內(nèi)部相連。
利用定時(shí)器的主從模式,即一個(gè)是主定時(shí)器,一個(gè)是從定時(shí)器,由主定時(shí)器輸出脈沖信號(hào),主定時(shí)器產(chǎn)生的更新觸發(fā)傳遞給從定時(shí)器進(jìn)行計(jì)數(shù),溢出時(shí)觸發(fā)從定時(shí)器的中斷服務(wù)函數(shù)。通過(guò)主從定時(shí)器進(jìn)行設(shè)定,不占用主程序時(shí)鐘,且能精準(zhǔn)控制。
主從關(guān)系要遵循參考手冊(cè)中所提供的配置,TIMx之間的互聯(lián):
參考TIMx_CR2和TIMx_SMCR寄存器配置主從模式。
TIMx_CR2 控制寄存器 2:
TIMx_SMCR 從模式控制寄存器:
配置TIM1為主模式,輸出PWM:
voidTIM1_Master_Init(u16arr,u16psc) { TIM_TimeBaseInitTypeDefTIM_TimeBaseStruct; TIM_OCInitTypeDefTIM_OCInitStruct; RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1,ENABLE); TIM_TimeBaseStructInit(&TIM_TimeBaseStruct); TIM_TimeBaseStruct.TIM_Period=arr; TIM_TimeBaseStruct.TIM_Prescaler=psc; TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_RepetitionCounter=0; TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStruct); TIM_OCStructInit(&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2; TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse=499; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; TIM_OC1Init(TIM1,&TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1,ENABLE); TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable); TIM_SelectOutputTrigger(TIM1,TIM_TRIGSource_Update); TIM_SetCounter(TIM1,0); TIM_CtrlPWMOutputs(TIM1,ENABLE); TIM_Cmd(TIM1,ENABLE); }
配置TIM3為從模式,選擇ITR0觸發(fā)(對(duì)應(yīng)內(nèi)部觸發(fā)源TIM1),使能更新中斷:
voidTIM3_Slave_Init(u16arr,u16psc) { TIM_TimeBaseInitTypeDefTIM_TimeBaseStruct; RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3,ENABLE); TIM_TimeBaseStructInit(&TIM_TimeBaseStruct); TIM_TimeBaseStruct.TIM_Period=arr; TIM_TimeBaseStruct.TIM_Prescaler=psc; TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_RepetitionCounter=0; TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct); TIM_ARRPreloadConfig(TIM3,DISABLE); TIM_SelectInputTrigger(TIM3,TIM_TS_ITR0); TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_External1); TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable); TIM_ClearFlag(TIM3,TIM_FLAG_Update); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); TIM_SetCounter(TIM3,0); TIM_Cmd(TIM3,ENABLE); }
TIM3控制脈沖數(shù)量,此處設(shè)置為10:
TIM3_Slave_Init(10,0);
TIM3中斷服務(wù)子程序:
voidTIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){ TIM_ClearITPendingBit(TIM3,TIM_IT_Update); TIM_CtrlPWMOutputs(TIM1,DISABLE); TIM_Cmd(TIM1,DISABLE); TIM_Cmd(TIM3,DISABLE); TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE); } }
邏輯分析儀接PA8(程序中配置PA8作為T(mén)IM1_CH1),觀測(cè)輸出波形如下:
TIM1輸出10個(gè)脈沖后停止。
以上簡(jiǎn)要列舉了幾種控制脈沖數(shù)量輸出的方式,以MM32F5270為例演示其實(shí)現(xiàn)的可行性。在實(shí)際應(yīng)用中,幾種方法各有優(yōu)缺點(diǎn),具體的方式還需要根據(jù)資源和需求進(jìn)行綜合考慮。
審核編輯:湯梓紅
-
PWM
+關(guān)注
關(guān)注
114文章
5201瀏覽量
214965 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3256瀏覽量
115445 -
Tim
+關(guān)注
關(guān)注
0文章
81瀏覽量
17970 -
脈沖信號(hào)
+關(guān)注
關(guān)注
6文章
400瀏覽量
37094
原文標(biāo)題:靈動(dòng)微課堂 (第239講)|MM32F5270 TIM 精準(zhǔn)脈沖數(shù)量輸出
文章出處:【微信號(hào):MindMotion-MMCU,微信公眾號(hào):靈動(dòng)MM32MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
MM32F5270平臺(tái)ADC注入通道的單周期采樣的實(shí)現(xiàn)
![<b class='flag-5'>MM32F5270</b>平臺(tái)ADC注入通道的單周期采樣的實(shí)現(xiàn)](https://file1.elecfans.com/web2/M00/89/17/wKgZomR4ZBCAKgPfAAPZJuEmMyI453.jpg)
一文解析MM32F5270開(kāi)發(fā)板+PWM測(cè)試與調(diào)制
MM32F5270是如何通過(guò)MindSwitch和CLU實(shí)現(xiàn)可任意編程外設(shè)間互聯(lián)系統(tǒng)的
介紹幾種MM32F5270定時(shí)器常用的精準(zhǔn)輸出脈沖數(shù)量的方法
MM32F5270總線(xiàn)架構(gòu)設(shè)計(jì)
![<b class='flag-5'>MM32F5270</b>總線(xiàn)架構(gòu)設(shè)計(jì)](https://file.elecfans.com/web2/M00/42/D8/poYBAGJ7Kb-AHokOAABMApjDKkU014.png)
基于MM32F5270控制器的I2S音頻播放
【MM32F5270】Keil開(kāi)發(fā)環(huán)境搭建
![【<b class='flag-5'>MM32F5270</b>】Keil開(kāi)發(fā)環(huán)境搭建](https://file.elecfans.com/web2/M00/7D/13/poYBAGN82HSASWKdAAAlb23yJds612.png)
MM32F5270平臺(tái)ADC注入通道的單周期采樣的實(shí)現(xiàn)
![<b class='flag-5'>MM32F5270</b>平臺(tái)ADC注入通道的單周期采樣的實(shí)現(xiàn)](https://file1.elecfans.com/web2/M00/88/B5/wKgZomRwDGeAdG4yAAAw0V-1LeM067.png)
評(píng)論