通過定時器和脈沖控制LED

目錄

一、定時器

(一)定時器簡介

(二)定時器類型

1、常見定時器

2、定時器的主要功能

3、常規定時器

(三)定時器配置

1、定時器標準外設庫接口函數

2、定時器標準外設庫配置

二、PWM

(一)PWM簡介

1、介紹及其功能

2、占空比

(二)PWM的工作原理

1、產生PWM的定時器:

2、產生PWM的原因:

3、PWM的工作原理解釋

(三)PWM標準外設庫輸出配置過程

三、實際應用

(一)關于定時器的題目

1、題目要求

2、代碼

3、實物效果

(二)關于PWM的題目

1、題目要求

2、代碼

3、Keil波形圖?編輯

4、實物效果

四、總結


一、定時器

(一)定時器簡介

????????STM32定時器是STM32微控制器中的重要塊,用于生成精確的時間基準。它可以用于測量時間間隔、產生脈沖、實現定時中斷等功能。通過配置寄存器,用戶可以靈活地控制定時器的工作模式和參數,實現各種實時控制和定時任務。????????

(二)定時器類型

5d258fe9f7374c88abc6da56332f3977.png

1、常見定時器

  • SysTick定時器:

SysTick系統時鐘位于Cortex-M3內核,是一個24位的遞減計數器,主要用于:

1)精確延時,在多任務操作系統中為系統提供時間基準(時基);

2)任務切換,為每個任務分配時間片。

  • WatchDog定時器:

1)作用:當微控制器受到外部干擾或程序中出現不可預知的邏輯故障導致應用程序脫離正常的執行流程時(俗稱程序跑飛),在一定的時間間隔內使系統復位,回到初始狀態;

2)看門狗設計是用來監視MCU程序運行狀態的,是確保系統可靠穩定運行的一種有效措施。

WatchDog又可以分為獨立看門狗和窗口看門狗,區別如下:

54ec0a7c42a141e8ad49c9720bb3799b.png

獨立看門狗:采用獨立時鐘,不受其他時鐘和總線影響,可在停機和待機模式下工作。適用于獨立于主程序之外、能夠獨立工作且對時間精度要求不高的場合。

窗口看門狗:計數值有一個上限時間和下限時間,低于下限時間或高于上限時間都會觸發MCU復位。適用于精確計時窗口起作用的應用程序。

f726f9e0d36e4e3c8d5cd90b3b016898.png

  • 基本定時器(下方重點介紹):TIM6和TIM7。
  • 通用定時器(下方重點介紹):TIM2、TIM3、TIM4和TIM5。
  • 高級定時器(下方重點介紹):TIM1和TIM8。

2、定時器的主要功能

  • 計數:脈沖計數,使用使用微控制器內部的外部時鐘(PCLK)來計數,是對固定周期的脈沖信號計數。
  • 定時:時間控制,通過對微控制器內部的時鐘脈沖進行計數實現定時功能。
  • 輸入捕獲:對輸入信號進行捕獲,實現對脈沖的頻率測量,可用于對外部輸入信號脈沖寬度的測量,比如測量電機轉速。
  • 輸出比較:將計數器計數值和設定值進行比較,根據比較結果輸出不同電平,用于控制輸出波形,比如直流電機的調速。

3、常規定時器

STM32定時器分類比較表

533a0baefd454f488c122e02a0c37abf.png

(1)基本定時器

簡介:

STM32有2個基本定時器TIM6和TIM7,可用作: 通用的16位計數或者 產生DAC觸發信號,基本定時器的計數模式只有向上計數模式。

d0086469e2254f9fb9b92dfe4bfd4014.png

(2)通用定時器

簡介:

????????TIM2、TIM3、TIM4、TIM5為STM32的4個獨立的16位通用定時器,具有定時、測量輸入信號的脈沖長度(輸入捕獲)、輸出所需波形(輸出比較、產生PWM、單脈沖輸出等)等功能。如下圖為通用定時器內部結構框圖。

e148772884ec4b50af51995cdff293de.png

????????STM32F103系列微控制器的定時器功能十分強大,內部結構也比較復雜,STM32通用定時器TIMx(x=2,3,4,5)主要由時鐘源、時鐘單元、捕獲和比較通道等構成,核心是可編程預分頻驅動的16位自動裝載計數器。通過對通用定時器內部結構進一步簡化得到如下圖所示的內部簡化圖:

cd68a59684d84fd78a4ccfbe1dd67814.png

通用定時器相關參數:

1)通用定時器的時鐘源:

如下圖為通用定時器框圖中有關時鐘源的部分:

6209c84251ff4715b72003be0ed5e385.png

當定時器使用內部時鐘時,定時器的時鐘源統稱為TIMxCLK。雖然在系統默認的配置中,TIMxCLK的時鐘頻率都是72MHz,但其時鐘來源并不相同。

  • 定時器TIM2~TIM7掛接在APB1上
  • 定時器TIM1和TIM8掛接在APB2上

若外部晶振的頻率為8MHz,則系統默認的時鐘頻率為72MHz

  • APB1預分頻器的分頻系數設置為2,則PCLK1=36MHz;
  • APB2預分頻系數設置為1,則PCLK2=72MHz,TIM1和TIM8的時鐘頻率TIMxCLK=72MHz;
  • Cortex系統時鐘由AHB時鐘(HCLK)8分頻得到,即SysTick的頻率為9MHz。

2)預分頻器PSC:

如圖為預分頻器時序圖:

24cb1e974d45489d9c6c87f928c3e85c.png

簡介:

PSC參數代表預分頻器(Prescaler)。預分頻器用于將定時器的時鐘頻率分頻,以便獲得所需的計數頻率。在定時器工作時,計數器將以預分頻器所設定的頻率遞增,直到達到設定的自動重載值(ARR,Auto-Reload Register)為止,然后重新開始計數。

限制:可以以1~65535之間的任意數值對時鐘源CK_PSC的時鐘頻率進行分頻,輸出CK_CNT脈沖供計數器CNT進行計數。

計數器計數頻率計算公式:CK_CNT = CK_PSC / (PSC + 1)

3)計數器CNT:

如圖為計數器時序圖:

398f6d02cd1440d3a705cfbc35b5cd31.png

簡介:

  • TIMxCNT是一個16位的寄存器,計數范圍為1~65535,可以向上計數、向下計數或向下向上雙向計數。
  • 要得到想要的計數值,需要對輸入時鐘頻率進行分頻。
  • 當計數值達到設定值時,便產生溢出事件,溢出時產生中斷或DMA請求,然后再由自動裝載寄存器進行重新加載或更新。
  • 計數器溢出中斷屬于軟件中斷,執行相應的定時器中斷服務程序。、

計數器溢出頻率計算公式:CK_CNT_OV = CK_CNT / (ARR + 1) ?? ??? ??? ??? ??? ? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = CK_PSC / (PSC + 1) / (ARR + 1)

4)自動裝載寄存器ARR

定時器的定時時間主要取決于定時周期和預分頻因子,這里ARR+1是因為計數器都是從0開始計數的。計算公式為:

定時時間=(ARR+1)×(預分頻值PSC+1)/輸入時鐘頻率? 或者??

T=(TIM_Period +1)*(TIM_Prescaler +1)/TIMxCLK

例如下方實踐中要求延時2秒閃爍及定時器設為2s,假設系統時鐘為72MHz,通用定時器時鐘TIMxCLK為72MHz,設置如下:

預分頻系數PSC=6000-1;?? ?ARR=4000-1;

則,定時時間=4000×36000/72000000=2s。

(3)高級定時器

92acfc2ca40c40c0b29a97a6dfe3e808.png

簡介:TIM1和TIM8是STM32的2個16位的高級定時器,高級定時器相比基本定時器、通用定時器,功能更為強大? ?

功能: 高級定時器除了通用定時器的功能外,還支持更高級的特性,如相位鎖定回路(PLL)、編碼器接口、三角波生成等。

用途場景: 適用于需要更高級、復雜計時功能的應用,例如音頻處理、電機控制、編碼器接口等。重復計數器、死區生成、互補輸出、剎車輸入等功能。

(三)定時器配置

1、定時器標準外設庫接口函數

簡介:

STM32F103系列微控制器的定時器庫函數存放在STM32標準外設庫的stm32f10x_tim.c和stm32f10x_tim.h文件中,stm32f10x_tim.h頭文件中聲明了定時器有關的庫函數以及相關的宏定義、結構體等。由于STM32的定時器功能較為強大,其庫函數也較多,如下圖所示:

ff07e9dcb6f94526a7fa396892bc0146.png

TIM_TimeBaseInit()庫函數

用于定時器TIMx的參數初始化,函數原型:

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);typedef struct
{uint16_t TIM_Prescaler;   uint16_t TIM_CounterMode;      uint16_t TIM_Period;          uint16_t TIM_ClockDivision;   uint8_t TIM_RepetitionCounter; 
} TIM_TimeBaseInitTypeDef;  

其中

(1)typedef struct(第二行)是被定義在定義在stm32f10x_tim.h頭文件中。

(2)uint16_t TIM_Prescaler(第四行),TIMx預分頻寄存器TIMx_PSC的值,數值上等于TIMx計數器TIMxCNT的預分頻系數減1

(3)uint8_t TIM_RepetitionCounter(第八行),為TIM1和TIM8高級定時器所特有。

(4)TIM_CounterMode(第五行):TIMx計數器TIMxCNT的計數模式分為向上計數和向下計數以及三種中央對其模式計數。

  • TIM_CounterMode_Up:向上計數模式,從0遞增,計到TIMx_ARR計數器的自動裝載值,并產生計數溢出脈沖
  • TIM_CounterMode_Down:向下計數模式,從TIMx_ARR計數器的自動裝載值遞減,計到0,并產生計數溢出脈沖
  • TIM_CounterMode_CenterAligned1:中央對齊模式1計數器交替地向上和向下計數,輸出比較中斷標志位,只在計數器向下計數時被設置;
  • TIM_CounterMode_CenterAligned2:中央對齊模式2計數器交替地向上和向下計數,輸出比較中斷標志位,只在計數器向上計數時被設置;
  • TIM_CounterMode_CenterAligned3:中央對齊模式3計數器交替地向上和向下計數,輸出比較中斷標志位,在計數器向下和向上計數時均可被設置。

(5)?uint16_t TIM_Period(第六行); ?下一個更新事件時裝入自動重裝載寄存器TIMx_ARR的周期值,數值上等于TIMx計數器TIMxCNT的計數周期減1。

  • ? TIM_Period是一個16位無符號整型數據,取值范圍為0~65535。 ? ?
  • ?定時器定時時間主要取決于預分頻因子TIM_Prescaler和定時周期TIM_Period

T=(TIM_Prescaler+1)*(TIM_Period+1)/TIMxCLK ? ?

  • TIMxCLK為定時器TIMx的時鐘頻率,STM32F103的TIMxCLK默認設置為72MHz。

(6)?uint16_t TIM_ClockDivision(第七行);?與TIMx_CR寄存器中bit[9:8]的CKD[1:0]對應,用于計數器工作模式時濾除高頻干擾,有如下選擇:

  • “00”——采樣頻率基準fDTS=定時器輸入頻率fCK_INT;
  • “01”——fDTS=fCK_INT/2;
  • “10”——fDTS=fCK_INT/4。

2、定時器標準外設庫配置

3ca08e81ee7d4874a4bf2e8368af4da1.png

(1)步驟一:TIM2時鐘使能

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

(2)步驟二:初始化定時器參數,設置自動重裝值,分頻系數,計數方式

定時器初始化使用TIM_TimeBaseInit()函數,如下所示:

void TIM_TimeBaseInit(TIM_TypeDef*TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
  • 第一個參數TIMx是具體定時器,x可為2~4
  • 第二個參數為TimeBaseInitStruct結構體指針。

下面以初始化通用定時器TIM2為例,進行以下配置:

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定義TIM初始化類型結構體變量
TIM_TimeBaseStructure.TIM_Period = (36000-1); //設置自動重載計數周期值
TIM_TimeBaseStructure.TIM_Prescaler = (4000-1); //設置分頻系數
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分頻因子
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設置為向上計數方式
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //初始化定時器TIM2
TIM_Cmd(TIM2,ENABLE); //使能TIM2定時器

(3)步驟三:設置TIM2允許更新中斷

為了避免在初始化定時器時進入中斷,需要在初始化過程中清除中斷標志。中斷在使用前必須先使能再使用,如使能定時器TIM2的更新模式中斷,則調用庫函數TIM_ITConfig(),函數原型為:

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

其中:

  • 第一個參數TIMx是具體定時器,x可為2~4。
  • 第二個參數用來指明所使能定時器的中斷類型。
  • 第三個參數為TIMx中斷的狀態,該參數可取值為ENABLE(使能)或者DISABLE(失能)。

(4)步驟四:TIM2中斷優先級設置

如圖為定時中斷基本結構

de9bf9bcaabb4cbb812aa5b81c5fafc4.png

結合先前學習的中斷編程,參考博客:中斷編程入門-CSDN博客??????

對TIM2中斷做如下所示的配置:

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

(5)步驟五:使能TIM2

使用TIM_Cmd()函數使能相應的定時器,其函數原型為:

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) ;

其中:

  • 第一個參數TIMx是具體定時器,x可為2~4
  • 第二個參數為TIMx的狀態,該參數可取值為ENABLE(使能)或者DISABLE(失能)

例如,使能定時器TIM2的更新中斷,配置如下:? ? ? ? ? ? ??

?TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

(6)步驟六:編寫中斷服務函數

STM32標準外設庫函數中用來讀取中斷狀態的庫函數為:

ITStatus TIM_GetITStatus (TIM_TypeDef* TIMx, uint16_t) ;

清除定時器相應中斷標志位的函數為:

void TIM_ClearITPendingBit (TIM_TypeDef* TIMx, uint16_t TIM_IT) ;

?例如想要通過定時器設定某時間后GPIOA5引腳的燈反轉,則中斷服務函數如下所示:

void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){GPIO_WriteBit(GPIOA,GPIO_Pin_5,(BitAction)((1- GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_5))));TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

因此我們可以得到一個TIM2中斷服務函數的模板以便以后使用時可以直接填入。

/* 定時器中斷函數,可以復制到使用它的地方
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
*/

二、PWM

(一)PWM簡介

PWM基本結構

473941e810a7467695cdc39a9054c6ac.png

1、介紹及其功能

????????PWM(Pulse Width Modulation,脈沖寬度調制)是一種利用脈沖寬度即占空比實現對模擬信號進行控制的技術,即是對模擬信號電平進行數字表示的方法。

????????廣泛應用于電力電子技術中,比如PWM控制技術在逆變電路中的應用;PWM還應用于直流電機調速,如變頻空調的交直流變頻調速,除實現調速外,還具有節能等特性。

下圖是一個周期為10ms(頻率為100Hz)的PWM波形圖

6d433b0f1d934e8080b5f94804e95270.png

2、占空比

占空比(Duty Cycle),是指在一個周期內,高電平時間占整個信號周期的百分比,即高電平時間與周期的比值: 占空比=Tp/T。

09bedc414b9e4f23bc2918b7171175c2.png87a2d36ed19e4563ba03a978d413ea3a.png

(二)PWM的工作原理

1、產生PWM的定時器:

  • 在STM32的定時器中除了TIM6和TIM7,其他定時器都可以用來產生PWM輸出;
  • 高級定時器TIM1和TIM8可以同時產生多達7路的PWM輸出;
  • 通用定時器能同時產生多達4路的PWM輸出

2、產生PWM的原因:

  • STM32中每個定時器有4個輸入通道:TIMx_CH1~TIMx_CH4;
  • 每個通道對應1個捕獲/比較寄存器TIMx_CRRx,將寄存器值和計數器值相比較,通過比較結果輸出高低電平,從而得到PWM信號;
  • 脈沖寬度調制模式可以產生一個由TIMx_ARR寄存器確定頻率、由TIMx_CCRx寄存器確定占空比的信號。

3、PWM的工作原理解釋

e4bb10d81e884372a36ff9bcfde2ea41.png

  • 在PWM的一個周期內,定時器從0開始向上計數,在0-t1時間段,定時器計數器TIMx_CNT值小于TIMx_CCRx值,輸出低電平;
  • 在t1-t2時間段,定時器計數器TIMx_CNT值大于TIMx_CCRx值,輸出高電平;
  • 當定時器計數器的值TIMx_CNT達到ARR時,定時器溢出,重新從0開始向上計數,如此循環。

(三)PWM標準外設庫輸出配置過程

8c009a89bdfa4bc3a9fd8a2c7c4505c1.png

(1)步驟一:配置PWM輸出通道,開啟TIM2時鐘

STM32規定了具體的引腳作為PWM輸出引腳,選擇不同的引腳時,還必須使用重定向功能(Remap)。

定時器TIM1的引腳復用功能映像:

048dc1dbe69544118087bea056f99172.png

?定時器TIM2的引腳復用功能映像:

2873e8d3cca34f3d9c9e3b8424237112.png

定時器TIM3的引腳復用功能映像:

59a941b8cd5f4f819af60dcaed901952.png

  • 使用定時器3的通道2(TIM2_CH1)作為PWM的輸出引腳;
  • 對PA0引腳進行配置,配置PA0為復用推挽輸出模式(GPIO_Mode_AF_PP)代碼如下所示:
/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//開啟TIM2的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//開啟GPIOA的時鐘/*GPIO重映射*/
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);			//開啟AFIO的時鐘,重映射必須先開啟AFIO的時鐘
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);			//將TIM2的引腳部分重映射,具體的映射方案需查看參考手冊
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);		//將JTAG引腳失能,作為普通GPIO引腳使用/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);	

(2)步驟二:初始化定時器TIM2

設置預分頻系數PSC、自動重載計數值ARR、計數模式、時鐘分割等,代碼如下所示。下方實驗中要求呼吸燈的周期為1~2s,且設置為向上計數法則如下配置。

	/*配置時鐘源*/TIM_InternalClockConfig(TIM2);		//選擇TIM2為內部時鐘,若不調用此函數,TIM默認也為內部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //時鐘分頻,選擇不分頻,此參數用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數器模式,選擇向上計數TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;					//計數周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;				//預分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重復計數器,高級定時器才會用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);             //將結構體變量交給TIM_TimeBaseInit,配置TIM2的時基單元

(3)步驟三:設置TIM2_CH1的PWM模式,使能TIM2的CH1輸出

如下配置TIM2_CH1的PWM模式使能TIM2的CH1能夠正常輸出,配置情況如下所示:

    TIM_OCInitTypeDef TIM_OCInitStructure;							//定義結構體變量TIM_OCStructInit(&TIM_OCInitStructure);							//結構體初始化,若結構體沒有完整賦值//則最好執行此函數,給結構體所有成員都賦一個默認值//避免結構體初值不確定的問題TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//輸出比較模式,選擇PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//輸出極性,選擇為高,若選擇極性為低,則輸出高低電平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//輸出使能TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure);						//將結構體變量交給TIM_OC1Init,配置TIM2的輸出比較通道1

(4)步驟四:使能定時器TIM2

?最后使能TIM2,定時器開始運行:

TIM_Cmd(TIM2, ENABLE);

三、實際應用

(一)關于定時器的題目

1、題目要求

使用STM32F103的 Tim2~Tim5其一定時器的某一個通道pin(與GPIOx管腳復用,見下圖),連接一個LED,用定時器計數方式,控制LED以2s的頻率周期性地亮-滅。

2、代碼

(1)Timer.c

#include "stm32f10x.h"                  // Device header/*** 函    數:定時中斷初始化* 參    數:無* 返 回 值:無*/
void Timer_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//開啟TIM2的時鐘/*配置時鐘源*/TIM_InternalClockConfig(TIM2);		//選擇TIM2為內部時鐘,若不調用此函數,TIM默認也為內部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//時鐘分頻,選擇不分頻,此參數用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//計數器模式,選擇向上計數TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;				//計數周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;				//預分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;			//重復計數器,高級定時器才會用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);				//將結構體變量交給TIM_TimeBaseInit,配置TIM2的時基單元	/*中斷輸出配置*/TIM_ClearFlag(TIM2, TIM_FLAG_Update);						//清除定時器更新標志位//TIM_TimeBaseInit函數末尾,手動產生了更新事件//若不清除此標志位,則開啟中斷后,會立刻進入一次中斷//如果不介意此問題,則不清除此標志位也可TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);					//開啟TIM2的更新中斷/*NVIC中斷分組*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);				//配置NVIC為分組2//即搶占優先級范圍:0~3,響應優先級范圍:0~3//此分組配置在整個工程中僅需調用一次//若有多個中斷,可以把此代碼放在main函數內,while循環之前//若調用多次配置分組的代碼,則后執行的配置會覆蓋先執行的配置/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure;						//定義結構體變量NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;				//選擇配置NVIC的TIM2線NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//指定NVIC線路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//指定NVIC線路的搶占優先級為2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//指定NVIC線路的響應優先級為1NVIC_Init(&NVIC_InitStructure);								//將結構體變量交給NVIC_Init,配置NVIC外設/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定時器開始運行
}/* 定時器中斷函數,可以復制到使用它的地方
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
*/

(2)LED.c

#include "stm32f10x.h"                  // Device headervoid LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);
}

?(3)main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "LED.h"int main(void)
{LED_Init();Timer_Init();	while (1){}
}void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){GPIO_WriteBit(GPIOA,GPIO_Pin_5,(BitAction)((1- GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_5))));TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

3、實物效果

定時器控制LED

(二)關于PWM的題目

1、題目要求

采用定時器PWM模式,讓 LED 以呼吸燈方式漸亮漸滅,周期為1~2秒,自己調整占空比變化到一個滿意效果;使用Keil虛擬示波器,觀察 PWM輸出波形。

2、代碼

(1)PWM.c

#include "stm32f10x.h"                  // Device header/*** 函    數:PWM初始化* 參    數:無* 返 回 值:無*/
void PWM_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//開啟TIM2的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//開啟GPIOA的時鐘/*GPIO重映射*/
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);			//開啟AFIO的時鐘,重映射必須先開啟AFIO的時鐘
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);			//將TIM2的引腳部分重映射,具體的映射方案需查看參考手冊
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);		//將JTAG引腳失能,作為普通GPIO引腳使用/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//將PA0引腳初始化為復用推挽輸出	//受外設控制的引腳,均需要配置為復用模式		/*配置時鐘源*/TIM_InternalClockConfig(TIM2);		//選擇TIM2為內部時鐘,若不調用此函數,TIM默認也為內部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //時鐘分頻,選擇不分頻,此參數用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數器模式,選擇向上計數TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;					//計數周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;				//預分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重復計數器,高級定時器才會用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);             //將結構體變量交給TIM_TimeBaseInit,配置TIM2的時基單元/*輸出比較初始化*/TIM_OCInitTypeDef TIM_OCInitStructure;							//定義結構體變量TIM_OCStructInit(&TIM_OCInitStructure);							//結構體初始化,若結構體沒有完整賦值//則最好執行此函數,給結構體所有成員都賦一個默認值//避免結構體初值不確定的問題TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//輸出比較模式,選擇PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//輸出極性,選擇為高,若選擇極性為低,則輸出高低電平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//輸出使能TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure);						//將結構體變量交給TIM_OC1Init,配置TIM2的輸出比較通道1/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定時器開始運行
}/*** 函    數:PWM設置CCR* 參    數:Compare 要寫入的CCR的值,范圍:0~100* 返 回 值:無* 注意事項:CCR和ARR共同決定占空比,此函數僅設置CCR的值,并不直接是占空比*           占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare);		//設置CCR1的值
}

(2)main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "PWM.h"uint8_t i;			//定義for循環的變量int main(void)
{/*模塊初始化*/PWM_Init();			//PWM初始化while (1){for (i = 0; i <= 100; i++){PWM_SetCompare1(i);			//依次將定時器的CCR寄存器設置為0~100,PWM占空比逐漸增大,LED逐漸變亮Delay_ms(15);			//延時500ms}for (i = 0; i <= 100; i++){PWM_SetCompare1(100 - i);	//依次將定時器的CCR寄存器設置為100~0,PWM占空比逐漸減小,LED逐漸變暗Delay_ms(15);		//延時500ms}}
}

3、Keil波形圖dc479b7fcc764dfe8437bfbd654dda3f.png

4、實物效果

呼吸燈

四、總結

學習完定時器相關內容,就像掌握了一個鬧鐘。通過自己設定時間,當時間走完則自動運行預先選擇做出的行動,為以后的單片機開發提供了一個新的思路。在學習了PWM之后,發現原來點燈也變得有趣起來了,可以通過賦予脈沖使得燈逐亮逐滅,為后續學習舵機等外設打好了基礎。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/19926.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19926.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19926.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

匿名函數(lambda)

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 匿名函數是指沒有名字的函數&#xff0c;應用在需要一個函數&#xff0c;但是又不想費神去命名這個函數的場合。通常情況下&#xff0c;這樣的函數只…

【Qt】Qt界面美化指南:深入理解QSS樣式表的應用與實踐

文章目錄 前言&#xff1a;1. 背景介紹2. 基本語法3. QSS 設置方式3.1. 設置全局樣式3.2. 從文件加載樣式表3.3. 使用 Qt Designer 編輯樣式 總結&#xff1a; 前言&#xff1a; 在當今這個視覺至上的時代&#xff0c;用戶界面&#xff08;UI&#xff09;的設計對于任何軟件產…

智能制造案例專題|與MongoDB一起解鎖工業4.0轉型與增長的無限潛力!

MongoDB 智能制造 數字化技術的洪流在各個產業鏈的主干和枝節涌現。在工業制造領域&#xff0c;能否通過數字化技術實現各生產要素、生產環節之間的緊密配合&#xff0c;高效規劃、管理整個生產流程&#xff0c;是企業提升韌性、贏得競爭的關鍵。隨著工業4.0的深入發展和智能…

高級Java開發者的自我修養:深入剖析JVM垃圾回收機制及面試要點

在探索Java虛擬機&#xff08;JVM&#xff09;的奧秘過程中&#xff0c;垃圾回收機制&#xff08;GC&#xff09;是一個不可或缺的話題&#xff0c;尤其在面對大型應用和系統優化時顯得尤為重要。JVM的自動內存管理是Java編程語言中一項革命性的特性&#xff0c;它大大簡化了程…

測試記錄2:Ubuntu工程直接添加使用Eigen3源文件

直接將Eigen3源文件放入到工程目錄下使用&#xff0c;免安裝 1.新建空文件夾Test_eigen 2.創建將eigen下載的文件夾解壓&#xff0c;重命名為eigen3放入到Test_eigen 3.進入Test_eigen&#xff0c;創建main.cpp #include <iostream> #include <Eigen/Eigen>int m…

AI盒子在智慧加油站的應用

方案背景 為規范加油站作業&#xff0c;保障人民生命財產安全&#xff0c;《加油站作業安全規范》&#xff08;AQ 3010-2007&#xff09;中第五條規定&#xff1a;卸油作業基本要求&#xff0c;明確防靜電、防雷電、防火、人員值守、禁止其他車輛及非工作人員進入卸油區。 痛點…

數據結構基礎篇(4)

十六.循環鏈表 概念 循環鏈表是一種頭尾相接的鏈表&#xff08;最后一個結點的指針域指向頭結點&#xff0c;整個鏈表形成一個環&#xff09;優點 從表任一結點出發均可找到表中其他結點判斷終止 由于循環鏈表中沒有NULL指針&#xff0c;所以涉及遍歷操作時&#xff0c;終止條…

RocketMQ學習(2) 深入學習

RokcetMQ的介紹和基礎知識見這篇博客——RocketMQ學習(1) 快速入門 本篇為上一篇的深入學習&#xff0c;很多基礎知識不再贅述。 目錄 消息重復消費問題(去重;冪等)布隆過濾器 重試機制死信消息 SpringBoot集成RocketMQ集成SpringBoot發送不同消息模式(同步消息)異步消息單向消…

python下載指定URL的文件

import requests # 圖片的URL地址 url https://book.pep.com.cn/1212001402143/files/mobile/1.jpg?240301113921 # 發送HTTP GET請求 response requests.get(url) # 檢查請求是否成功 if response.status_code 200: # 打開一個文件用于寫入 with open(download…

實習碰到的問題w1

1.vueelementUI在輸入框中按回車鍵會刷新頁面 當一個 form 元素中只有一個輸入框時&#xff0c;在該輸入框中按下回車應提交該表單。如果希望阻止這一默認 行為&#xff0c;可以在 <el-form> 標簽上添加 submit.native.prevent 。 參考&#xff1a;element-ui 表單 form …

使用el-tab,el-tab-pane循環使用循環后不顯示下劃線問題

在vue項目中使用element-UI el-tab里的el-tab-pane是循環出來的&#xff0c;但是循環出來后選中tab不顯示下劃線了 文章目錄 問題問題展示效果問題代碼問題原因 解決方案解決后效果解決方案1代碼 解決方案2代碼 問題 問題展示效果 問題代碼 <el-tabs v-model"activeNa…

音量的對數表示與浮點數表示

音量用浮點數&#xff08;float&#xff09;和對數&#xff08;logarithmic scale&#xff09;表示各有特點和應用場景 浮點數&#xff1a;直接使用線性刻度表示音量&#xff0c;例如在0.0&#xff08;最小音量&#xff09;到1.0&#xff08;最大音量&#xff09;的范圍內。對…

『 Linux 』緩沖區(萬字)

文章目錄 &#x1f9a6; 什么是緩沖區&#x1f9a6; 格式化輸入/輸出&#x1f9a6; 刷新策略&#x1fab6; 塊緩沖(fully buffered)&#x1fab6; 無緩沖(unbuffered)&#x1fab6; 行緩沖(line buffered) &#x1f9a6; 現象解釋&#x1f9a6; exit()與_exit()&#x1f9a6; 進…

list 的實現

目錄 list 結點類 結點類的構造函數 list的尾插尾刪 list的頭插頭刪 迭代器 運算符重載 --運算符重載 和! 運算符重載 * 和 -> 運算符重載 list 的insert list的erase list list實際上是一個帶頭雙向循環鏈表,要實現list,則首先需要實現一個結點類,而一個結點需要…

【代碼隨想錄——回溯算法——四周目】

1.重新安排行程 1.1 我的代碼&#xff0c;超時通不過 var (used []boolpath []stringres []stringisFind bool )func findItinerary(tickets [][]string) []string {sortTickets(tickets)res make([]string, len(tickets)1)path make([]string, 0)used make([]bool,…

JSON Web Token

JWT 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一種用于在各方之間作為JSON對象安全地傳輸信息的開放標準&#xff08;RFC 7519&#xff09;。該信息經過數字簽名&#xff0c;因此是可驗證和可信的。JWT 可以使用HMAC算法或使用RSA的公鑰/私鑰對進行簽名 JWT的…

微信小程序 vant Picker組件default-index不生效的解決辦法

1、原始的寫法以及問題 <van-popup show"{{ showPopup && cellClick Freq }}" position"bottom" bind:close"onPopupClose"><van-picker value-key"Spec" show-toolbar title"{{cellClick Freq ? showPcCha…

win10鍵盤按亂了,如何恢復?

今天鍵盤被寶寶給按亂了&#xff0c;好不容易給重新調整回來&#xff0c;記錄備忘&#xff1a; 1、win10的asdf和方向鍵互換了&#xff1a; 使用Fnw鍵來回切換&#xff0c;OK&#xff01; 2、鍵盤的win鍵失效&#xff0c;例如&#xff1a;按winD無法顯示桌面。此時&#xf…

Day30

Day30 CSS CSS常用樣式 font-family:“微軟雅黑” -設置字體 font-size: 50px -設置字體大小 font-style : italic-設置字體風格 font-weight:bolder -設置字體粗細 color: white-設置字體顏色 letter-spacing: 20px-設置文本內容的間隔 text-decoration :underline - 設置劃…

電動汽車電子系統架構

電動汽車的普及正在穩步發展&#xff0c;供應鏈的各個環節也在發生變化。它涵蓋了制造電動汽車零件的原材料、化學品、電池和各種組件。與此同時&#xff0c;汽車充電基礎設施也參與其中&#xff0c;它們正經歷一個歷史性的階段&#xff0c;經過徹底的重新設計。它們的電氣化以…