全國熱線電話:

0519-8918 1758
產(chǎn)品中心PRODUCT SHOW
聯(lián)系我們CONTACT US

    聯(lián)系人:聶經(jīng)理

    手機:18605199068  18602586200

    電話:0519-89181758  83700750  

    Q Q:710285815

    郵箱:18605199068@126.com

    地址:江蘇省常州市武進區(qū)大通西路200號。

直流無刷電機和無刷直流電機信息智能網(wǎng)

電機控制基礎(chǔ)知識1—定時器基礎(chǔ)知識與PWM輸出原理
2022-06-20

單片機開發(fā)中,電機的控制與定時器有著密不可分的關(guān)系,無論是直流電機,步進電機還是舵機,都會用到定時器,比如最常用的有刷直流電機,會使用定時器產(chǎn)生PWM波來調(diào)節(jié)轉(zhuǎn)速,通過定時器的正交編碼器接口來測量轉(zhuǎn)速等。 本篇先介紹定時器的基礎(chǔ)知識,然后對照這些知識介紹一下定時器輸出PWM的基本原理,以及編程實現(xiàn)與代碼分析。 首先來看一下定時器的基礎(chǔ)介紹。 1 定時器基礎(chǔ)知識 1.1 定時器種類 以STM32F4為例,一共有14個定時器: 高級定時器(TIM1、TIM8) 通用定時器(TIM2~TIM5,TIM9~TIM14) TIM2~TIM5(通用定時器里功能較多的) TIM9/TIM12 TIM10/TIM11和TIM13/TIM14 基本定時器 (TIM6、TIM7) 1.2 各種定時器的特性 1.2.1 高級定時器與通用定時器 這里列舉高級定時器的特性,在此基礎(chǔ)上,對比添加其與通用定時器的不同之處: 16 位遞增、遞減、遞增/遞減自動重載計數(shù)器(TIM2 和 TIM5為32位) 16 位可編程預(yù)分頻器,用于對計數(shù)器時鐘頻率進行分頻(即運行時修改),分頻系數(shù)介于 1 到 65536 之間。 多達 4 個獨立通道(TIM9/TIM12有2個,TIM10/TIM11,TIM13/TIM14只有1個),可用于: 輸入捕獲 輸出比較 PWM 生成(邊沿和中心對齊模式)(高級定時器和TIM2~TIM5特有,其它是只有邊沿對齊模式) 單脈沖模式輸出 帶可編程死區(qū)的互補輸出(高級定時器特有)。 使用外部信號控制定時器且可實現(xiàn)多個定時器互連的同步電路(TIM10/TIM11,TIM13/TIM14沒有)。 重復(fù)計數(shù)器,用于僅在給定數(shù)目的計數(shù)器周期后更新定時器寄存器(高級定時器特有)。 用于將定時器的輸出信號置于復(fù)位狀態(tài)或已知狀態(tài)的斷路輸入(高級定時器特有)。 發(fā)生如下事件時生成中斷/DMA 請求: 更新:計數(shù)器上溢/下溢、計數(shù)器初始化(通過軟件或內(nèi)部/外部觸發(fā)) 觸發(fā)事件(計數(shù)器啟動、停止、初始化或通過內(nèi)部/外部觸發(fā)計數(shù))(TIM10/TIM11和TIM13/TIM14沒有此功能) 輸入捕獲 輸出比較 斷路輸入(高級定時器特有) 支持定位用增量(正交)編碼器和霍爾傳感器電路(高級定時器和TIM2~TIM5特有)。 外部時鐘觸發(fā)輸入或逐周期電流管理(高級定時器和TIM2~TIM5特有)。 1.2.2 基本定時器 基本定時器 (TIM6、TIM7)的功能比較單一,所具有的功能如下: 16 位自動重載遞增計數(shù)器 只能定時,沒有外部 IO 16 位可編程預(yù)分頻器,用于對計數(shù)器時鐘頻率進行分頻(即運行時修改),分頻系數(shù) 介于 1 和 65536 之間 用于觸發(fā) DAC 的同步電路 發(fā)生如下更新事件時會生成中斷/DMA 請求:計數(shù)器上溢 1.3 定時器使用配置 使用定時器,一般需要配置如下: 時基:也就是計數(shù)器的計數(shù)時鐘 自動重裝載值:每次計數(shù)的最大值 輸出通道:當(dāng)需要使用定時器輸出某種波形時(如PWM) 輸入通道:當(dāng)需要使用定時器接收某種波形時(如電機編碼器信號) 先來看一下定時器的原理框圖,對定時器的內(nèi)部原理有一個整體直觀的感受: 1.3.1 時鐘源 從上圖可以看出,計數(shù)器的時鐘源可以為: 由RCC的內(nèi)部時鐘分頻得到 由定時器的TIMx_ETR引腳得到 由其他定時器通過TRGO輸出得到 一般使用RCC的內(nèi)部時鐘CK_INT,也即定時器時鐘TIMxCLK,經(jīng)APB1或APB2預(yù)分頻器后分頻提供。 關(guān)于定時器時鐘源的具體細(xì)節(jié),可以來看一下STM32F4的時鐘樹: 從STM32F4的內(nèi)部時鐘樹可知: 高級定時器timer1, timer8以及通用定時器timer9, timer10, timer11的時鐘來源是APB2總線(84MHZ) 通用定時器timer2~timer5,通用定時器timer12~timer14以及基本定時器timer6,timer7的時鐘來源是APB1總線(42MHZ) 另外: 當(dāng)APB1和APB2分頻數(shù)為1的時候,各定時器的時鐘就是對應(yīng)的APB1或APB2的時鐘; 如果APB1和APB2分頻數(shù)不為1,那么各定時器的時鐘就是對應(yīng)的APB1或APB2的時鐘的2倍; 由于庫函數(shù)中 APB1 預(yù)分頻的系數(shù)默認(rèn)是 2,所以,所以TIM1、TIM8~TIM11的時鐘為APB2時鐘的兩倍即168MHz,TIM2~TIM7、TIM12~TIM14的時鐘為APB1的時鐘的兩倍即84MHz。 1.3.2 計數(shù)器時鐘 由于定時器時鐘的提供的可以頻率較高,計數(shù)器不需要這么高的頻率來計數(shù),所以會進行降頻,使用一個合適的低頻時鐘來計數(shù)。 定時器時鐘經(jīng)過PSC 預(yù)分頻器之后,即 CK_CNT,用來驅(qū)動計數(shù)器計數(shù)。PSC 是一個16 位的預(yù)分頻器,可以對定時器時鐘TIMxCLK 進行 1~65536 之間的任何一個數(shù)進行分頻。 具體計算方式為:CK_CNT=TIMxCLK/(PSC+1)。 比如,使用STM32F4的通用定時器2(TIM2CLK為APB1的時鐘的兩倍即84MHz),PSC設(shè)置為83,則計數(shù)時鐘為84MHz/(83+1)=1MHz,即1ms計一個數(shù)。 1.3.3 計數(shù)器 計數(shù)器 CNT 是一個 16 位的計數(shù)器,只能往上計數(shù),最大計數(shù)值為 65535。當(dāng)計數(shù)達到自動重裝載寄存器的時候產(chǎn)生更新事件,并清零從頭開始計數(shù)。 1.3.4 自動重裝載寄存器 自動重裝載寄存器 ARR 是一個 16 位的寄存器,這里面裝著計數(shù)器能計數(shù)的最大數(shù)值。當(dāng)計數(shù)到這個值的時候,如果使能了中斷的,定時器就產(chǎn)生溢出中斷。 2 定時器輸出PWM原理 如下圖是PWM輸出的原理示意圖: 假設(shè)定時器工作模式設(shè)置為向上計數(shù) PWM模式,且當(dāng) CNT=CCRx 時輸出 0,則: 當(dāng) CNT 值小于 CCRx 的時候, IO 輸出高電平 (1) 當(dāng) CNT 值大于等于 CCRx 的時候,IO 輸出低電平 (0) 當(dāng) CNT 達到 ARR 值的時候,重新歸零,然后重新向上計數(shù),依次循環(huán)。 因此,改變 CCRx 的值,就可以改變 PWM 輸出的占空比,改變 ARR 的值,就可以改變 PWM 輸出的周期(頻率),這就是利用定時器輸出PWM 的基本原理。 3 定時器常用的寄存器 使用定時器來輸出PWM時,需要對其寄存器進行相應(yīng)的設(shè)置。定時器的寄存器有好多個,這里先介紹幾個與輸出PWM相關(guān)的幾個寄存器,其它是寄存器以后用到時再介紹。 3.1 控制寄存器CR1 控制寄存器,就是來設(shè)置定時的工作模式: 位 15:10 保留,必須保持復(fù)位值。 位 9:8 CKD:時鐘分頻 (Clock division) 此位域指示定時器時鐘 (CK_INT) 頻率與數(shù)字濾波器所使用的采樣時鐘(ETR、TIx)之間的分頻比, 位 7 ARPE:自動重載預(yù)裝載使能 (Auto-reload preload enable) 0:TIMx_ARR 寄存器不進行緩沖 1:TIMx_ARR 寄存器進行緩沖 位 6:5 CMS:中心對齊模式選擇 (Center-aligned mode selection),包括1種邊沿對齊模式與3種中心對齊模式 位 4 DIR:計數(shù)器方向 (Direction),0為遞增計數(shù),1為遞減計數(shù)。 注: 當(dāng)定時器配置為中心對齊模式或編碼器模式時,該位為只讀狀態(tài)。 位 3 OPM:單脈沖模式 (One-pulse mode) 位 2 URS:更新請求源 (Update request source) 此位由軟件置 1 和清零,用以選擇 UEV 事件源。 位 1 UDIS:更新禁止 (Update disable) 此位由軟件置 1 和清零,用以使能/禁止 UEV 事件生成。 位 0 CEN:計數(shù)器使能 (Counter enable),0為禁止計數(shù)器,1為使能計數(shù)器 只有事先通過軟件將 CEN 位置 1,才可以使用外部時鐘、門控模式和編碼器模式。而觸發(fā)模式可通過硬件自動將 CEN 位置 1。在單脈沖模式下,當(dāng)發(fā)生更新事件時會自動將 CEN 位清零。 3.2 捕獲/比較模式寄存器CCMR1 這些通道可用于輸入(捕獲模式)或輸出(比較模式)模式。通道方向通過配置相應(yīng)的 CCxS 位進行定義。此寄存器的所有其它位在輸入模式和輸出模式下的功能均不同。對于任一給定位 OCxx 用于說明通道配置為輸出時該位對應(yīng)的功能 ICxx 則用于說明通道配置為輸入時 該位對應(yīng)的功能 因此,必須注意同一個位在輸入階段和輸出階段具有不同的含義。 這里僅先介紹輸出模式下的功能: 位 15 OC2CE:輸出比較 2 清零使能 (Output compare 3 clear enable) 位 14:12 OC2M[2:0]:輸出比較 2 模式 (Output compare 2 mode) 位 11 OC2PE:輸出比較 2 預(yù)裝載使能 (Output compare 2 preload enable) 位 10 OC2FE:輸出比較 2 快速使能 (Output compare 2 fast enable) 位 9:8 CC2S[1:0]:捕獲/比較 2 選擇 (Capture/Compare 2 selection) 參考下面的CC1S通道1 位 7 OC1CE:輸出比較 1 清零使能 (Output compare 3 clear enable) OC1CE:輸出比較 1 清零使能 (Output Compare 1 Clear Enable) 0:OC1Ref 不受 ETRF 輸入影響 1:ETRF 輸入上檢測到高電平時, OC1Ref 立即清零。 位 6:4 OC1M:輸出比較 1 模式 (Output compare 1 mode) 一共可配置位7種模式,這里僅介紹2種: 110:PWM 模式 1––在遞增計數(shù)模式下,只要 TIMx_CNTTIMx_CCR1,通道 1 便為無效狀態(tài) (OC1REF=0),否則為有效狀態(tài) (OC1REF=1)。 111:PPWM 模式 2––在遞增計數(shù)模式下,只要 TIMx_CNTTIMx_CCR1,通道 1 便為有效狀態(tài),否則為無效狀態(tài)。 位 3 OC1PE:輸出比較 1 預(yù)裝載使能 (Output compare 1 preload enable) 0:禁止與 TIMx_CCR1 相關(guān)的預(yù)裝載寄存器??呻S時向 TIMx_CCR1 寫入數(shù)據(jù),寫入后將立即使用新值。 1:使能與 TIMx_CCR1 相關(guān)的預(yù)裝載寄存器。可讀/寫訪問預(yù)裝載寄存器。TIMx_CCR1 預(yù)裝載值在每次生成更新事件時都會裝載到活動寄存器中。 位 2 OC1FE:輸出比較 1 快速使能 (Output compare 1 fast enable) 此位用于加快觸發(fā)輸入事件對 CC 輸出的影響(僅當(dāng)通道配置為 PWM1 或 PWM2 模式時,OCFE 才會起作用)。 0:即使觸發(fā)開啟,CC1 也將根據(jù)計數(shù)器和 CCR1 值正常工作。觸發(fā)輸入出現(xiàn)邊沿時,激活CC1 輸出的最短延遲時間為 5 個時鐘周期。 1:觸發(fā)輸入上出現(xiàn)有效邊沿相當(dāng)于 CC1 輸出上的比較匹配。隨后,無論比較結(jié)果如何,OC 都設(shè)置為比較電平。采樣觸發(fā)輸入和激活 CC1 輸出的延遲時間縮短為 3 個時鐘周期。 位 1:0 CC1S[1:0]:捕獲/比較 1 選擇 (Capture/Compare 1 selection) 此位域定義通道方向(輸入/輸出)以及所使用的輸入。 00:CC1 通道配置為輸出。 01:CC1 通道配置為輸入,IC1 映射到 TI1 上。 10:CC1 通道配置為輸入,IC1 映射到 TI2 上。 11:CC1 通道配置為輸入,IC1 映射到 TRC 上。此模式僅在通過 TS 位(TIMx_SMCR 寄存器)選擇內(nèi)部觸發(fā)輸入時有效 注: 僅當(dāng)通道關(guān)閉時(TIMx_CCER 中的 CC1E = 0),才可向 CC1S 位寫入數(shù)據(jù)。 3.3 計數(shù)器CNT 計數(shù)器的功能很單一,就是計數(shù): 位 15:0 CNT[15:0]:計數(shù)器值 (Counter value) 3.4 預(yù)分頻器PSC 預(yù)分頻器的功能也很單一,就是分頻: 位 15:0 PSC[15:0]:預(yù)分頻器值 (Prescaler value) 計數(shù)器時鐘頻率 CK_CNT 等于 fCK_PSC / (PSC[15:0] + 1)。 PSC 包含在每次發(fā)生更新事件時要裝載到實際預(yù)分頻器寄存器的值。 3.5 自動重裝載寄存器ARR 自動重裝載寄存器的功能也很單一,就是保存一個數(shù),在計數(shù)滿的時候,重新開始計數(shù) 位 15:0 ARR[15:0]:自動重載值 (Auto-reload value) ARR 為要裝載到實際自動重載寄存器的值。 當(dāng)自動重載值為空時,計數(shù)器不工作。 3.6 捕獲/比較寄存器CCR 自動重裝載寄存器的功能也很單一,也是保存一個數(shù),用于與當(dāng)前的CNT進行比較,注意 TIM2 和 TIM5是32位計數(shù)。 以CCR1寄存器(一共有CCR1~CCR4這4個通道)為例: 位31:16 CCR1[31:16]:捕獲/比較 1 的高 16 位(對于 TIM2 和 TIM5)。 位15:0 CCR1[15:0]:捕獲/比較 1 的低 16 位 (Low Capture/Compare 1 value) 如果通道 CC1 配置為輸出: CCR1 是捕獲/比較寄存器 1 的預(yù)裝載值。 如果沒有通過 TIMx_CCMR寄存器中的OC1PE 位來使能預(yù)裝載功能,寫入的數(shù)值會被直接傳輸至當(dāng)前寄存器中。否則只在發(fā)生更新事件時生效(拷貝到實際起作用的捕獲/ 比較寄存器1)。 實際捕獲/比較寄存器中包含要與計數(shù)器 TIMx_CNT進行比較并在 OC1 輸出上發(fā)出信號的值。 如果通道 CC1 配置為輸入: CCR1 為上一個輸入捕獲 1 事件 (IC1) 發(fā)生時的計數(shù)器值。 4 代碼實現(xiàn)與分析 上面介紹了定時器的基礎(chǔ)知識與PWM的輸出原理,下面就來實際看一下,如何編寫對應(yīng)的代碼(以STM32F407為例)。 4.1 定時器初始化 定時器的初始化,因為需要用到對應(yīng)的引腳輸出PWM,因此要先初始化GPIO引腳,然后,還要初始化定時器的時基(計數(shù)的時鐘)以及輸出通道(用于配置PWM的輸出模式)。 4.1.1 復(fù)用引腳初始化 這里用到的是定時器3,根據(jù)STM32F407的數(shù)據(jù)手冊“3 Pinouts and pin description”中的“Table 9. Alternate function mapping”復(fù)用引腳說明表,可以看到定時器3通道1對應(yīng)的引腳位A6: 因此程序中對A6引腳可以這樣配置,注意一定要配置引腳的復(fù)用功能: GPIO_InitTypeDef GPIO_InitStructure; /*引腳配置 結(jié)構(gòu)體*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA時鐘 GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); /*GPIOA6復(fù)用為定時器3*/ /*復(fù)用引腳配置*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //GPIOA6 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /*復(fù)用功能*/ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復(fù)用輸出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA6 4.1.2 時基初始化 時基初始化,主要是配置定時器的計數(shù)頻率(psc)和自動重裝置值(每次計數(shù)的周期,arr),比如TIM3_PWM_Init(500-1,84-1); (關(guān)于psc與arr的知識點,可以再回顧一下上面1.3節(jié)的知識) 這里將arr的值設(shè)置為500,即計數(shù)器每計夠500個數(shù)就會重新從0開始計數(shù),這個500再乘以計數(shù)器計數(shù)的周期,就是PWM真正的周期,那計數(shù)器計數(shù)的頻率是多少呢(頻率的倒數(shù)為周期)? 這里將psc的值設(shè)置為84-1,即TIM3的輸入頻率為84MHz再將頻率降低1/84,即使用1MHz的頻率計數(shù)(1s能計1,000,000個數(shù),也即1us計1個數(shù)),那么PWM的真正周期就是500*1us=500us(0.5ms),通過改變占空比的值(ccr),就可以調(diào)節(jié)PWM的輸出占空比。 時基初始化配置如下: TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /*時基 結(jié)構(gòu)體*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3時鐘使能 /*時基初始化*/ TIM_TimeBaseStructure.TIM_Period=arr; /*ARR 自動重裝載值(周期),例如500*/ TIM_TimeBaseStructure.TIM_Prescaler=psc; /*PSC 定時器分頻,例如84*/ TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; /*時鐘分割*/ TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /*向上計數(shù)模式*/ TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); /*初始化定時器3*/ 最后一句的時基初始化,起始就是對定時的寄存器進行配置,該函數(shù)的內(nèi)部實現(xiàn)如下: void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { uint16_t tmpcr1 = 0; tmpcr1 = TIMx->CR1; if((TIMx == TIM1) || (TIMx == TIM8)|| /*高級定時器TIM和TIM8*/ (TIMx == TIM2) || (TIMx == TIM3)||(TIMx == TIM4) || (TIMx == TIM5)) /*通用定時器中的TIM2~TIM5*/ { /* 設(shè)置為計數(shù)器模式 */ tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS)); tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; } if((TIMx != TIM6) && (TIMx != TIM7)) /*基本定時器TIM6和TIM7無此功能*/ { /* 設(shè)置時鐘分頻 */ tmpcr1 &= (uint16_t)(~TIM_CR1_CKD); tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; } /* 配置CR1寄存器 */ TIMx->CR1 = tmpcr1; /* 配置ARR寄存器,設(shè)置自動重轉(zhuǎn)載值 */ TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; /* 配置PSC寄存器,設(shè)置預(yù)分頻值 */ TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; if ((TIMx == TIM1) || (TIMx == TIM8)) /*高級定時器TIM和TIM8*/ { /* 配置RCR寄存器,設(shè)置重復(fù)計數(shù)值 */ TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; } /* 生成一個更新事件來立即重新加載預(yù)分頻器和重復(fù)計數(shù)器(僅針對高級定時器TIM1和TIM8)值 */ TIMx->EGR = TIM_PSCReloadMode_Immediate; } 4.1.3 輸出通道初始化 輸出通道初始化,主要是配置輸出的一些參數(shù),這里主要關(guān)注TIM_OCMode(模式)與TIM_OCPolarity(極性),這兩個參數(shù)是配合使用的: PWM模式1 向上計數(shù)時,一旦TIMx_CNT時通道1為有效電平,否則為無效電平; 向下計數(shù)時,一旦TIMx_CNT>TIMx_CCR1時通道1為無效電平,否則為有效電平。 PWM模式2 向上計數(shù)時,一旦TIMx_CNT時通道1為無效電平,否則為有效電平; 向下計數(shù)時,一旦TIMx_CNT>TIMx_CCR1時通道1為有效電平,否則為無效電平。 這里的有效電平又是什么意思呢?怎么算有效電平?它就是通過極性來配置的: 輸出High模式:有效電平為高電平 輸出Low模式:有效電平為低電平 對比著再來看這張圖: 當(dāng)CNT的計數(shù)值小于CCR時,即t1這個時間段,輸出有效電平(TIM_OCMode_PWM1模式),而有效電平是高電平(極性為TIM_OCPolarity_High),所以PWM的IO邏輯在t1這個時間段輸出了高電平。 輸出通道的配置如下: TIM_OCInitTypeDef TIM_OCInitStructure; /*輸出通道 結(jié)構(gòu)體*/ /*輸出通道初始化,初始化TIM3 Channel1 PWM模式*/ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; /*選擇定時器模式:TIM脈沖寬度調(diào)制模式1*/ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; /*輸出極性:TIM輸出比較極性高*/ TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根據(jù)指定的參數(shù)初始化外設(shè)TIM3 OC1 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /*使能TIM3在CCR1上的預(yù)裝載寄存器*/ TIM_ARRPreloadConfig(TIM3,ENABLE);/*ARPE使能:使能控制寄存器CR的第8位:ARPR, Auto-reload preload enable*/ TIM_Cmd(TIM3, ENABLE); /*使能TIM3:使能控制寄存器CR的第0位:CEN, counter enable*/ 關(guān)于配置CCMR1、CCER寄存器 CCMR1: CCER: TIM_OC1Init函數(shù)對應(yīng)于輸入通道的初始化,其實就是操作CCMR1、CCER等寄存器: void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) { uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E;/* 關(guān)閉通道1: 復(fù)位CC1E位 */ tmpccer = TIMx->CCER;/* 獲取 TIMx CCER 寄存器的值 */ tmpcr2 = TIMx->CR2; /* 獲取 TIMx CR2 寄存器的值 */ tmpccmrx = TIMx->CCMR1;/* 獲取TIMx CCMR1 寄存器的值 */ tmpccmrx &= (uint16_t)~TIM_CCMR1_OC1M; /* 復(fù)位輸出比較模式OC1M位 */ tmpccmrx &= (uint16_t)~TIM_CCMR1_CC1S; tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;/* 設(shè)置為輸出比較模式 */ tmpccer &= (uint16_t)~TIM_CCER_CC1P; /* 復(fù)位輸出極性CC1P */ tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; /* 設(shè)置輸出極性 */ tmpccer |= TIM_OCInitStruct->TIM_OutputState; /* 設(shè)置輸出狀態(tài) */ if((TIMx == TIM1) || (TIMx == TIM8)) /*高級定時器的特殊配置*/ { //省略。。。 } TIMx->CR2 = tmpcr2; /* 寫數(shù)據(jù)到TIMx的CR2寄存器 */ TIMx->CCMR1 = tmpccmrx; /* 寫數(shù)據(jù)到TIMx的CCMR1寄存器 */ TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse;/* 設(shè)置CCR1寄存器 */ TIMx->CCER = tmpccer; /* 寫數(shù)據(jù)到TIMx的CCER寄存器 */ } 4.2 動態(tài)改變占空比 占空比是通過修改CCR寄存器的值進行修改的,如果定時器初始化時只設(shè)置了1次CCR的值,那么會輸出恒定占空比的PWM波;如果在定時器運行的時候,動態(tài)修改CCR的值,則可以實現(xiàn)PWM占空比的動態(tài)調(diào)整。 如下程序,實現(xiàn)了每隔10ms對占空比進行一次修改,每次將高電平計數(shù)值增加5,當(dāng)增大道500(占空比100%)時,再逐漸減小到0(占空比0%),不斷循環(huán)。 u16 led0pwmval=0; u8 dir=1; TIM3_PWM_Init(500-1,84-1); //84M/84=1Mhz的計數(shù)頻率,重裝載值500,所以PWM頻率為 1M/500=2Khz. while(1) //實現(xiàn)比較值從0-500遞增,到500后從500-0遞減,循環(huán) { delay_ms(10); if(dir) { led0pwmval+=5; //dir==1 led0pwmval遞增 } else { led0pwmval-=5; //dir==0 led0pwmval遞減 } if(led0pwmval>500) { dir=0; //led0pwmval到達500后,方向為遞減 } if(led0pwmval==0) { dir=1; //led0pwmval遞減到0后,方向改為遞增 } TIM_SetCompare1(TIM3,led0pwmval); /*CCR 修改比較值(占空比)*/ } 5 測試效果 將程序下載到板子,我用的一塊STM32F407的板,A6引腳上接了一個LED燈,實際效果的LED逐漸變涼,在逐漸變暗,依次循環(huán)。 再通過邏輯分析儀來查看實際的輸出波形,如下圖,測得的pwm周期0.5ms(頻率2kHz),與軟件中設(shè)定的一致。 在某一時刻,脈寬55us。 在另一時刻,脈寬0.365ms,即實現(xiàn)了PWM脈寬的動態(tài)調(diào)整。

0519-8918 1758
聯(lián)系人:聶經(jīng)理 郵箱:niejli@126.com 地址:江蘇省常州市武進區(qū)大通西路200號。 電話:0519-8918 1758

版權(quán)所有 ? 常州永沛機電技術(shù)有限公司 直流無刷電機|無刷直流電機|直流防爆電機|常州永沛機電技術(shù)有限公司|電動平車電機|電動船電機|直流減速電機


蘇ICP備13004000號