通用定時器(TIMx)
4.1 使得PB5-TIM3通道2產(chǎn)生頻率為12.5Hz的方波,該方波控制LED1的閃爍 4.2 周期控制通用定時器3的2通道,實現(xiàn)1KHz的不同占空比波形,控制LED實現(xiàn)呼吸燈 通用定時器是一個通過可編程預分頻器驅動的16位自動裝載計數(shù)器構成。它適用于多種場合,包括測量輸入信號的脈沖長度(輸入捕獲)或者產(chǎn)生輸出波形(輸出比較和PWM)。使用定時器預分頻器和RCC時鐘控制器預分頻器,脈沖長度和波形周期可以在幾個微秒到幾個毫秒間調整。每個定時器都是完全獨立的,沒有互相共享任何資源。它們可以一起同步操作。[正版請搜索:beautifulzzzz(看樓主博客園官方博客,享高質量生活)嘻嘻!??!]
通用TIMx (TIM2、 TIM3、 TIM4和TIM5)定時器功能包括: ● 16位向上、向下、向上/向下自動裝載計數(shù)器 圖1 通用定時器框圖
可編程通用定時器的主要部分是一個16位計數(shù)器和與其相關的自動裝載寄存器。這個計數(shù)器可以向上計數(shù)、向下計數(shù)或者向上向下雙向計數(shù)。此計數(shù)器時鐘由預分頻器分頻得到。計數(shù)器、自動裝載寄存器和預分頻器寄存器可以由軟件讀寫,在計數(shù)器運行時仍可以讀寫。 時基單元包含: 自動裝載寄存器是預先裝載的,寫或讀自動重裝載寄存器將訪問預裝載寄存器。根據(jù)在TIMx_CR1 寄存器中的自動裝載預裝載使能位(ARPE)的設置,預裝載寄存器的內容被立即或在每次的更新事件UEV時傳送到影子寄存器。當計數(shù)器達到溢出條件(向下計數(shù)時的下溢條件)并當TIMx_CR1 寄存器中的UDIS位等于’0’時,產(chǎn)生更新事件。更新事件也可以由軟件產(chǎn)生。隨后會詳細描述每一種配置下更新事件的產(chǎn)生。 計數(shù)器由預分頻器的時鐘輸出CK_CNT驅動,僅當設置了計數(shù)器TIMx_CR1 寄存器中的計數(shù)器使能位(CEN)時, CK_CNT才有效。 預分頻器可以將計數(shù)器的時鐘頻率按1 到65536之間的任意值分頻。它是基于一個(在TIMx_PSC寄存器中的)16位寄存器控制的16位計數(shù)器。這個控制寄存器帶有緩沖器,它能夠在工作時被改變。新的預分頻器參數(shù)在下一次更新事件到來時被采用。(圖2和圖3給出了在預分頻器運行時,更改計數(shù)器參數(shù)的例子。) 圖2 當預分頻器的參數(shù)從1 變到2時,計數(shù)器的時序圖 圖3 當預分頻器的參數(shù)從1 變到4時,計數(shù)器的時序圖
3.2.1 向上計數(shù)模式 在向上計數(shù)模式中,計數(shù)器從0計數(shù)到自動加載值(TIMx_ARR計數(shù)器的內容),然后重新從0開始計數(shù)并且產(chǎn)生一個計數(shù)器溢出事件。 圖4 計數(shù)器時序圖,內部時鐘分頻因子為1 圖5 計數(shù)器時序圖,內部時鐘分頻因子為2 圖6 計數(shù)器時序圖,內部時鐘分頻因子為4 圖7 計數(shù)器時序圖,內部時鐘分頻因子為N 圖8 計數(shù)器時序圖,當ARPE=0時的更新事件(TIMx_ARR沒有預裝入) 圖9 計數(shù)器時序圖,當ARPE=1 時的更新事件(預裝入了TIMx_ARR)
3.2.2 向下計數(shù)模式 在向下模式中,計數(shù)器從自動裝入的值(TIMx_ARR計數(shù)器的值)開始向下計數(shù)到0,然后從自動裝入的值重新開始并且產(chǎn)生一個計數(shù)器向下溢出事件。 ● 預分頻器的緩存器被置入預裝載寄存器的值(TIMx_PSC寄存器的值)。 注:自動裝載在計數(shù)器重載入之前被更新,因此下一個周期將是預期的值。 以下是一些當TIMx_ARR=0x36時,計數(shù)器在不同時鐘頻率下的操作例子。 圖10 計數(shù)器時序圖,內部時鐘分頻因子為1 圖11 計數(shù)器時序圖,內部時鐘分頻因子為2 圖12 計數(shù)器時序圖,內部時鐘分頻因子為4 圖13 計數(shù)器時序圖,內部時鐘分頻因子為N 圖14 計數(shù)器時序圖,當沒有使用重復計數(shù)器時的更新事件
3.2.3 中央對齊模式(向上/向下計數(shù)) 在中央對齊模式,計數(shù)器從0開始計數(shù)到自動加載的值(TIMx_ARR寄存器)?1 ,產(chǎn)生一個計數(shù)器溢出事件,然后向下計數(shù)到1 并且產(chǎn)生一個計數(shù)器下溢事件;然后再從0開始重新計數(shù)。 ● 預分頻器的緩存器被加載為預裝載(TIMx_PSC寄存器)的值。 注:如果因為計數(shù)器溢出而產(chǎn)生更新,自動重裝載將在計數(shù)器重載入之前被更新,因此下一個周期將是預期的值(計數(shù)器被裝載為新的值)。 以下是一些計數(shù)器在不同時鐘頻率下的操作的例子:
圖15 計數(shù)器時序圖,內部時鐘分頻因子為1 , TIMx_ARR=0x6
圖16 計數(shù)器時序圖,內部時鐘分頻因子為2
圖17 計數(shù)器時序圖,內部時鐘分頻因子為4, TIMx_ARR=0x36
圖18 計數(shù)器時序圖,內部時鐘分頻因子為N
圖19 計數(shù)器時序圖, ARPE=1 時的更新事件(計數(shù)器下溢)
圖20 計數(shù)器時序圖, ARPE=1 時的更新事件(計數(shù)器溢出)
計數(shù)器時鐘可由下列時鐘源提供: ● 內部時鐘(CK_INT) 3.3.1 內部時鐘源(CK_INT) 如果禁止了從模式控制器(TIMx_SMCR寄存器的SMS=000),則CEN、 DIR(TIMx_CR1 寄存器)和UG位(TIMx_EGR寄存器)是事實上的控制位,并且只能被軟件修改(UG位仍被自動清除)。只 下圖顯示了控制電路和向上計數(shù)器在一般模式下,不帶預分頻器時的操作。
圖21 一般模式下的控制電路,內部時鐘分頻因子為1
3.3.2 外部時鐘源模式1 當TIMx_SMCR寄存器的SMS=111 時,此模式被選中。計數(shù)器可以在選定輸入端的每個上升沿或下降沿計數(shù)。
圖22 TI2外部時鐘連接例子 例如,要配置向上計數(shù)器在T12輸入端的上升沿計數(shù),使用下列步驟: 1. 配置TIMx_CCMR1 寄存器CC2S=’01’,配置通道2檢測TI2輸入的上升沿 當上升沿出現(xiàn)在TI2,計數(shù)器計數(shù)一次,且TIF標志被設置。在TI2的上升沿和計數(shù)器實際時鐘之間的延時,取決于在TI2輸入端的重新同步電路。 圖23 外部時鐘模式1 下的控制電路
3.3.3 外部時鐘源模式2 選定此模式的方法為:令TIMx_SMCR寄存器中的ECE=1
圖24 外部觸發(fā)輸入框圖 例如,要配置在ETR下每2個上升沿計數(shù)一次的向上計數(shù)器,使用下列步驟: 計數(shù)器在每2個ETR上升沿計數(shù)一次。
圖25 外部時鐘模式2下的控制電路
每一個捕獲/比較通道都是圍繞著一個捕獲/比較寄存器(包含影子寄存器),包括捕獲的輸入部分(數(shù)字濾波、多路復用和預分頻器),和輸出部分(比較器和輸出控制)。(下面幾張圖是一個捕獲/比較通道概覽。)
圖26 捕獲/比較通道(如:通道1 輸入部分) 輸出部分產(chǎn)生一個中間波形OCxRef(高有效)作為基準,鏈的末端決定最終輸出信號的極性。
圖27 捕獲/比較通道1 的主電路
圖28 捕獲/比較通道的輸出部分(通道1) 捕獲/比較模塊由一個預裝載寄存器和一個影子寄存器組成。讀寫過程僅操作預裝載寄存器。
在輸入捕獲模式下,當檢測到ICx信號上相應的邊沿后,計數(shù)器的當前值被鎖存到捕獲/比較寄存器(TIMx_CCRx)中。當捕獲事件發(fā)生時,相應的CCxIF標志(TIMx_SR寄存器)被置’1’,如果使能了中斷或者DMA操作,則將產(chǎn)生中斷或者DMA操作。如果捕獲事件發(fā)生時CCxIF標志已經(jīng)為高,那么重復捕獲標志CCxOF(TIMx_SR寄存器)被置’1’。寫CCxIF=0可清除CCxIF,或讀取存儲在TIMx_CCRx寄存器中的捕獲數(shù)據(jù)也可清除CCxIF。寫CCxOF=0可清除CCxOF。 以下例子說明如何在TI1 輸入的上升沿時捕獲計數(shù)器的值到TIMx_CCR1 寄存器中,步驟如下: ● 選擇有效輸入端: TIMx_CCR1 必須連接到TI1 輸入,所以寫入TIMx_CCR1 寄存器中的CC1S=01 ,只要CC1S不為’00’,通道被配置為輸入,并且TM1_CCR1 寄存器變?yōu)橹蛔x。 為了處理捕獲溢出,建議在讀出捕獲溢出標志之前讀取數(shù)據(jù),這是為了避免丟失在讀出捕獲溢出標志之后和讀取數(shù)據(jù)之前可能產(chǎn)生的捕獲溢出信息。 注:設置TIMx_EGR寄存器中相應的CCxG位,可以通過軟件產(chǎn)生輸入捕獲中斷和/或DMA請求。
● 兩個ICx信號被映射至同一個TIx輸入。
圖29 PWM輸入模式時序 由于只有 TI1FP1 和 TI2FP2 連到了從模式控制器,所以 PWM 輸入模式只能使用 TIMx_CH1/TIMx_CH2信號。
在輸出模式(TIMx_CCMRx寄存器中 CCxS=00)下,輸出比較信號(OCxREF和相應的OCx)能夠直接由軟件強置為有效或無效狀態(tài),而不依賴于輸出比較寄存器和計數(shù)器間的比較結果。
此項功能是用來控制一個輸出波形,或者指示一段給定的的時間已經(jīng)到時。 當計數(shù)器與捕獲/比較寄存器的內容相同時,輸出比較功能做如下操作: ● 將輸出比較模式(TIMx_CCMRx寄存器中的OCxM位)和輸出極性(TIMx_CCER寄存器中的CCxP位)定義的值輸出到對應的引腳上。在比較匹配時,輸出引腳可以保持它的電平(OCxM=000)、被設置成有效電平(OCxM=001)、被設置成無效電平(OCxM=010)或進行翻轉(OCxM=011)。 TIMx_CCMRx中的OCxPE位選擇TIMx_CCRx寄存器是否需要使用預裝載寄存器。 1. 選擇計數(shù)器時鐘(內部,外部,預分頻器) TIMx_CCRx寄存器能夠在任何時候通過軟件進行更新以控制輸出波形,條件是未使用預裝載寄存器(OCxPE=’0’,否則TIMx_CCRx影子寄存器只能在發(fā)生下一次更新事件時被更新)。下圖給
脈沖寬度調制模式可以產(chǎn)生一個由TIMx_ARR寄存器確定頻率、由TIMx_CCRx寄存器確定占空比的信號。 在TIMx_CCMRx寄存器中的OCxM位寫入’110’(PWM模式1)或’111’(PWM模式2),能夠獨立地設置每個OCx輸出通道產(chǎn)生一路PWM。必須設置TIMx_CCMRx寄存器OCxPE位以使能相應的預裝載寄存器,最后還要設置TIMx_CR1 寄存器的ARPE位, (在向上計數(shù)或中心對稱模式中)使能自動重裝載的預裝載寄存器。 僅當發(fā)生一個更新事件的時候,預裝載寄存器才能被傳送到影子寄存器,因此在計數(shù)器開始計數(shù)之前,必須通過設置TIMx_EGR寄存器中的UG位來初始化所有的寄存器。 在PWM模式(模式1 或模式2)下, TIMx_CNT和TIMx_CCRx始終在進行比較, (依據(jù)計數(shù)器的計數(shù)方向 ) 以確 定是否符合 TIMx_CCRx≤ TIMx_CNT 或者 TIMx_CNT ≤ TIMx_CCRx 。然而為了與 ● 當比較的結果改變 這樣在運行中可以通過軟件強置PWM輸出。根據(jù)TIMx_CR1 寄存器中 CMS位的狀態(tài),定時器能夠產(chǎn)生邊沿對齊的PWM信號或中央對齊的PWM信號。 >_<" PWM 邊沿對齊模式 (向上計數(shù)配置當TIMx_CR1 寄存器中的DIR位為低的時候執(zhí)行向上計數(shù)。) 下面是一個PWM模式1 的例子。當TIMx_CNT<TIMx_CCRx時PWM信號參考OCxREF為高,否則為低。如果TIMx_CCRx中的比較值大于自動重裝載值(TIMx_ARR),則OCxREF保持為’1’。 圖31 邊沿對齊的PWM波形(ARR=8) >_<" 向下計數(shù)的配置(當TIMx_CR1 寄存器的DIR位為高時執(zhí)行向下計數(shù)。) 在PWM模式1,當TIMx_CNT>TIMx_CCRx時參考信號OCxREF為低,否則為高。如果TIMx_CCRx中的比較值大于TIMx_ARR中的自動重裝載值,則OCxREF保持為’1’。該模式下不能產(chǎn)生0%的PWM波形。 >_<" PWM 中央對齊模式(當TIMx_CR1 寄存器中的CMS位不為’00’時,為中央對齊模式(所有其他的配置對OCxREF/OCx信號都有相同的作用)。) 根據(jù)不同的CMS位設置,比較標志可以在計數(shù)器向上計數(shù)時被置’1’、在計數(shù)器向下計數(shù)時被置’1’、或在計數(shù)器向上和向下計數(shù)時被置’1’。 TIMx_CR1 寄存器中的計數(shù)方向位(DIR)由硬件更新,不要用軟件修改它。 ● TIMx_ARR=8
圖32 中央對齊的PWM波形(APR=8) 使用中央對齊模式的提示: ● 進入中央對齊模式時,使用當前的向上/向下計數(shù)配置;這就意味著計數(shù)器向上還是向下計數(shù)取決于TIMx_CR1 寄存器中DIR位的當前值。此外,軟件不能同時修改DIR和CMS位。
單脈沖模式(OPM)是前述眾多模式的一個特例。這種模式允許計數(shù)器響應一個激勵,并在一個程序可控的延時之后,產(chǎn)生一個脈寬可程序控制的脈沖。 向上計數(shù)方式: CNT < CCRx ≤ ARR (特別地, 0 < CCRx) 圖33 單脈沖模式的例子 例如,你需要在從TI2輸入腳上檢測到一個上升沿開始,延遲tDELAY之后,在OC1 上產(chǎn)生一個長度為tPULSE的正脈沖。
4.1 使得PB5-TIM3通道2產(chǎn)生頻率為12.5Hz的方波,該方波控制LED1的閃爍 >_<" 主函數(shù)為: 1 int main(void) 2 { 3 RCC_Configuration(); //系統(tǒng)時鐘設置及外設時鐘使能 4 NVIC_Configuration(); //中斷源配置 5 time_ini(); //定時器3的初始化 6 while(1); 7 } >_<" 配置各外設的時鐘和系統(tǒng)時鐘:(有些是多余的) 1 /**************************************************************************** 2 * 名 稱:void RCC_Configuration(void) 3 * 功 能:系統(tǒng)時鐘配置為72MHZ, 外設時鐘配置 4 ****************************************************************************/ 5 void RCC_Configuration(void){ 6 7 SystemInit(); 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 9 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC 10 | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE); 11 } >_<" 配置中斷向量:(因為這里用到了TIM3,所以要配置其中斷向量) 1 /**************************************************************************** 2 * 名 稱:void NVIC_Configuration(void) 3 * 功 能:中斷源配置 4 ****************************************************************************/ 5 void NVIC_Configuration(void) 6 { 7 NVIC_InitTypeDef NVIC_InitStructure; 8 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 9 10 NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQn ; //配置定時器中斷 11 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 12 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 13 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 14 NVIC_Init(&NVIC_InitStructure); 15 } >_<" TIM3的2通道配置:(下面首先配置GPIO PB5(為Tim3的2通道),PB5引腳默認是作為通用IO口使用,為了產(chǎn)生特定頻率,利用了該引腳可以復用為TIM3_CH2,根據(jù)手冊,需要用到局部復用映射,才能將TIM3_CH2映射到PB5。) 在定時器3的初始化中,用到了輸出比較2模式的翻轉設置。也就是當TIM3_CCR2=TIM3_CNT時,翻轉輸出的電平。以產(chǎn)生需要的頻率,TIM3_CCR2的值決定了翻轉的頻率。當TIM3_CCR2=TIM3_CNT時,產(chǎn)生一次電平翻轉,并在中斷服務程序里重新完成對TIM3_CCR2的裝載。依次往復,產(chǎn)生了所需要的12.5Hz的頻率。(注意注釋的第15~17行介紹如何控制輸出頻率,CCR2_Val=45000) 1 void time_ini(void){ 2 GPIO_InitTypeDef GPIO_InitStructure; 3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //定時器3 時鐘使能 4 5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5復用為TIM3的通道2 6 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 7 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 8 GPIO_Init(GPIOB, &GPIO_InitStructure); 9 10 /* TIM3局部復用功能開啟 在TIM3的局部復用開啟時,PB5會被復用為TIM3_CH2*/ 11 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE); 12 13 /* Time Base configuration */ 14 /*------------------------------------------------------------------- 15 TIM3CLK=72MHz 預分頻系數(shù)Prescaler=63 經(jīng)過分頻 定時器時鐘為1.125MHz 16 捕獲/比較寄存器2 TIM3_CCR2= CCR2_Val 17 2通道產(chǎn)生的更新頻率是=1.125MHz/CCR2_Val=25Hz 18 19 -------------------------------------------------------------------*/ 20 TIM3_TimeBaseStructure.TIM_Prescaler = 63; //預分頻器TIM3_PSC=63 21 TIM3_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器向上計數(shù)模式 TIM3_CR1[4]=0 22 TIM3_TimeBaseStructure.TIM_Period =0xffff; //自動重裝載寄存器TIM3_APR 23 TIM3_TimeBaseStructure.TIM_ClockDivision = 0x0; //時鐘分頻因子 TIM3_CR1[9:8]=00 24 25 TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseStructure); //寫TIM3各寄存器參數(shù) 26 27 TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle ; //TIM3_CCMR1[14:12]=011 翻轉 當TIM3_CCR2=TIM3_CNT時,翻轉OC2REF的電平 28 TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //輸入/捕獲2輸出允許 OC2信號輸出到對應的輸出引腳PB5 29 TIM3_OCInitStructure.TIM_Pulse =CCR2_Val; //若CC1通道配置為輸出:CCR2是裝入當前捕獲/比較2 TIM3_CCR2寄存器的值(預裝載值)。 30 //當前捕獲/比較寄存器包含了與計數(shù)器TIM3_CNT比較的值,并且在OC端口上輸出信號 31 TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性 低電平有效 TIM3_CCER[5]=1; 32 33 TIM_OC2Init(TIM3, &TIM3_OCInitStructure); 34 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); //TIM3_CCMR1[1]=0 禁止TIM3_CCR2寄存器的預裝載功能,可隨時寫入TIM3_CCR2 35 //且新值馬上起作用 36 37 TIM_Cmd(TIM3,ENABLE); //啟動定時器3 TIM3_CR1[0]=1; 38 TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE); //TIM3_DIER[2]=1 允許捕獲/比較2中斷 39 } >_<" TIM3的中斷服務子程序(每次TIM3_CCR2=TIM3_CNT產(chǎn)生一次中斷,在中斷子程序中取出上一次的TIM3_CCR2加上CCR2_Val作為新的TIM3_CCR2,這樣等TIM3_CNT加到和TIM3_CCR2相等時又會觸發(fā)一次中斷) 1 void TIM3_IRQHandler(void) 2 { 3 4 if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET) //判斷狀態(tài)寄存器 TIM3_SR[2] 是否發(fā)生了捕獲/比較2 中斷 5 { 6 TIM_ClearITPendingBit(TIM3, TIM_IT_CC2); //軟件清除狀態(tài)寄存器 TIM3_SR[2] 捕獲/比較2 中斷中斷標志 7 8 capture1 = TIM_GetCapture2(TIM3); //獲取TIM3_CCR2的預裝值 9 TIM_SetCompare2(TIM3, capture1+ CCR2_Val); //和CCR2_Val累加后裝入TIM3_CCR2 這是為了配合計數(shù)器值的遞增。以在下一次作出比較。 10 11 } 12 }
4.2 周期控制通用定時器3的2通道,實現(xiàn)1KHz的不同占空比波形,控制LED實現(xiàn)呼吸燈 >_<" 主函數(shù)為:(不同于上面固定的頻率定時方法,這里在while里不斷更改CCR2_Val的值來改變占空比) 1 int main(void) 2 { 3 unsigned char a=0; 4 TIM_OCInitTypeDef TIM3_OCInitStructure; 5 RCC_Configuration(); 6 time_ini(); 7 SysTick_Config(72000); //配置SYSTICK時鐘節(jié)拍為1ms一次 8 while(1){ 9 Delay(1); //延時1ms 10 TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 11 TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //輸出禁止 12 TIM3_OCInitStructure.TIM_Pulse = CCR2_Val; //確定占空比 13 TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 14 TIM_OC2Init(TIM3, &TIM3_OCInitStructure); 15 16 /*調整CCR2_Val的值來改變占空比,逐步的控制LED1的亮度, 占空比大過一定值時, 17 亮度的變化就不明顯了,所以CCR2_VAL最大設定到17000*/ 18 if(a==0) CCR2_Val=CCR2_Val+10; 19 else CCR2_Val=CCR2_Val-10; 20 if(CCR2_Val>17000){ CCR2_Val=17000; a=1;} 21 else if(CCR2_Val<200){ CCR2_Val=200; a=0;} 22 } 23 } >_<" 配置各外設的時鐘和系統(tǒng)時鐘:(同4.1有些是多余的) 1 /**************************************************************************** 2 * 名 稱:void RCC_Configuration(void) 3 * 功 能:系統(tǒng)時鐘配置為72MHZ, 外設時鐘配置 4 ****************************************************************************/ 5 void RCC_Configuration(void){ 6 7 SystemInit(); 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 9 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC 10 | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE , ENABLE); 11 } >_<" TIM3的2通道配置:(注意,這里沒有用到中斷向量和中斷子程序?。。∠旅媸紫扰渲肎PIO PB5(為Tim3的2通道),PB5引腳默認是作為通用IO口使用,為了產(chǎn)生特定頻率,利用了該引腳可以復用為TIM3_CH2,根據(jù)手冊,需要用到局部復用映射,才能將TIM3_CH2映射到PB5。) 由于TIM3計數(shù)器的時鐘頻率是72MHz,希望各通道輸出頻率為1KHZ,根據(jù)3倍預分頻后,時鐘頻率為24MHz,根據(jù)公式ftim3=TIM3CLK/(TIM3_Period+1),可得到TIM3預分頻的值為24000, 根據(jù)公式根據(jù)公式 通道輸出占空比=TIM3_CCR2/(TIM_Period+1),可以得到TIM_Pulse的計數(shù)值,逐步改變這個值,可以控制占空比, 從而獲得LED1 亮度明暗漸變的效果。(所以在main函數(shù)的while中不斷重置CCR2_Val值來控制不同占空比) 1 /**************************************************************************** 2 * 名 稱:void time_ini(void) 3 * 功 能:TIM3初始化 4 ****************************************************************************/ 5 void time_ini(void){ 6 GPIO_InitTypeDef GPIO_InitStructure; 7 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 8 9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5復用為TIM3的通道2 10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 11 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 12 GPIO_Init(GPIOB, &GPIO_InitStructure); 13 /*TIM3局部復用功能開啟 在TIM3的局部復用開啟時,PB5會被復用為TIM3_CH2*/ 14 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE); 15 16 /*------------------------------------------------------------------- 17 TIM3CLK=72MHz 預分頻系數(shù)Prescaler=2 經(jīng)過分頻 定時器時鐘為24MHz 18 根據(jù)公式 通道輸出占空比=TIM3_CCR2/(TIM_Period+1),可以得到TIM_Pulse的計數(shù)值 19 捕獲/比較寄存器2 TIM3_CCR2= CCR2_Val 20 -------------------------------------------------------------------*/ 21 TIM3_TimeBaseStructure.TIM_Prescaler = 2; //預分頻器TIM3_PSC=3 22 TIM3_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器向上計數(shù)模式 TIM3_CR1[4]=0 23 TIM3_TimeBaseStructure.TIM_Period =24000; //自動重裝載寄存器TIM3_APR 確定頻率為1KHz 24 TIM3_TimeBaseStructure.TIM_ClockDivision = 0x0; //時鐘分頻因子 TIM3_CR1[9:8]=00 25 TIM3_TimeBaseStructure.TIM_RepetitionCounter = 0x0; 26 27 TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseStructure); //寫TIM3各寄存器參數(shù) 28 29 TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM3_CCMR1[14:12]=111 在向上計數(shù)時, 30 //一旦TIMx_CNT<TIMx_CCR1時通道1為無效電平,否則為有效電平 31 TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //輸入/捕獲2輸出允許 OC2信號輸出到對應的輸出引腳PB5 32 TIM3_OCInitStructure.TIM_Pulse = CCR2_Val; //確定占空比,這個值決定了有效電平的時間。 33 TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性 低電平有效 TIM3_CCER[5]=1; 34 35 TIM_OC2Init(TIM3, &TIM3_OCInitStructure); 36 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); 37 TIM_Cmd(TIM3,ENABLE); //啟動定時器3 TIM3_CR1[0]=1; 38 }
|
|