STM32 定時器TIM

定時器基礎知識

定時器就是用來定時的機器,是存在于STM32單片機中的一個外設。STM32總共有8個定時器,分別是2個高級定時器(TIM1、TIM8),4個通用定時器(TIM2、TIM3、TIM4、TIM5)和2個基本定時器(TIM6、TIM7),如下圖所示:

STM32F10X系列總共最多有八個定時器

三種STM32定時器的區別:

向上是指1234逐個遞增計數,向下是指逐個遞減計數,向上/向下是指中央對齊模式(基本定時器只能向上,上圖寫錯了)?,捕獲指的是輸入捕獲,比較指的是輸出比較

基本定時器

1. 時鐘源 2. 控制器 3. 時基單元

時鐘源

時鐘源來自RCC的TIMx_CLK(屬于內部的CK_INIT)

外設掛載在總線下的APB1對應的是時鐘2~時鐘7(所以我們的基本定時器TIM6 TIM7在APB1下的)

根據時鐘樹

因為AHB 72M,(AHB默認分頻是2)所以APB1是 36M,(APB1默認分頻是2)所以根據(如果APB1預分頻系數=1則頻率不變,否則頻率x2.)可知定時器的頻率 = 72M

時基(定時器的心臟)

????????定時器最重要的就是時基部分:包括預分頻器、計數器、自動重裝載寄存器 ?

????????預分頻器:1-16位預分頻器PSC對內部時鐘CK_PSC進行分頻之后,得到計數器時鐘CK_INT=CK_PSC/(PSC+1)

????????CNT在計數器時鐘的驅動下開始計數,計數一次的時間為1/CK_INT

? ? ? ??計數器、重裝在寄存器:定時器使能(CEN置1)后,計數器CNT在CK_CNT驅動 下計數,當CNT值與ARR的設定值相等時就自動生成事件并CNT自動清零,然后 自動重新開始計數,如此重復以上過程。

影子寄存器

1.PSC和ARR都有影子寄存器,功能框圖上有個影子

2.影子寄存器的存在起到一個緩沖的作用,用戶值->寄存器->影子寄存器->起作用, 如果不使用影子寄存器則用戶值在寫到寄存器之后則里面起作用,ARR影子, TIMx_CR1:APRE位控制。

?定時時間的計算

定時器時間=(PSC+1)*(ARR+1)/72M

因為我們的計數器是從0開始計數的,所以要加1

基本定時器的功能

1.計數器16bit,只能向上計數,只有TIM6和TIM7

2.沒有外部的GPIO,是內部資源,只能用來定時

3.時鐘來自PCKL1,為72M,可實現1~65536分頻

通用定時器

STM32 的通用定時器功能:

位于低速的APB1總線上(APB1)

16 位/32 位(僅 TIM2 和 TIM5)向上、向下、向上/向下自動裝載計數器 (TIMx_CNT),注意:TIM9~TIM14 只支持向上(遞增)計數方式

16 位可編程(可以實時修改)預分頻器(TIMx_PSC),計數器時鐘頻率的分頻系數為 1~ 65535 之間的任意數值

4 個獨立通道(TIMx_CH1~4,TIM9~TIM14 最多 2 個通道),這些通道可以用來作為:

????????????????輸入捕獲

????????????????輸出比較

????????????????PWM 生成(邊緣或中間對齊模式) ,注意:TIM9~TIM14 不支持中間對齊模式

????????????????單脈沖模式輸出

可使用外部信號(TIMx_ETR)控制定時器和定時器互連(可以用 1 個定時器控制另外 一個定時器)的同步電路。

????????如下事件發生時產生中斷/DMA(TIM9~TIM14 不支持 DMA):

????????????????更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)

????????????????觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)

????????????????輸入捕獲

????????????????輸出比較

????????????????支持針對定位的增量(正交)編碼器和霍爾傳感器電路(TIM9~TIM14 不支持)

????????????????觸發輸入作為外部時鐘或者按周期的電流管理(TIM9~TIM14 不支持)?

STM32的通用定時器可以被用于:測量輸入信號的脈沖長度(輸入捕獲)或者產生輸出波形(輸出比較和PWM)等

使用定時器分頻器和RCC時鐘控制分頻器,脈沖長度和波型周期可以在幾個微妙到幾個毫秒間調整,STM32的每個通用定時器都是完全獨立的,沒有互相共享的任何資源????????

計數器模式 ?

????????向上計數模式:計數器從0計數到自動加載值(TIMx_ARR),然后重新從0開始計數并且 產生一個計數器溢出事件

????????向下計數模式:計數器從自動裝入的值(TIMx_ARR)開始向下計數到0,然后從自動裝 入的值重新開始,并產生一個計數器向下溢出事件

????????中央對齊模式(向上/向下計數):計數器從0開始計數到自動裝入的值-1,產生一個 計數器溢出事件,然后向下計數到1并且產生一個計數器溢出事件;然后再從0開始重新計數

通用定時器框圖

框圖可以分為四個大部分,分別是:

時鐘產生部分

時基單元部分

輸入捕獲部分

輸出捕獲部分

時鐘產生部分?

內部時鐘(CKINT)
外部時鐘模式:外部觸發輸入(ETR)
內部觸發輸入(TRX):使用一個定時器作為另一個定時器的預分頻器,如可以配置一個定時器Timer1而作為另一個定時器Iimer2的預分頻器。
外部時鐘模式:外部輸入腳(TIx)

時機單元

時基單元就是定時器框圖的第二部分,它包括三個寄存器,分別是:計教器寄存器(TIMXCND、預分頻器寄存器(TIMXPSC)和自動裝載寄存器(TIMX ARR)。對這三個寄存器的介紹如下:
計數器寄存器(TIMx_CNT)
????????向上計數、向下計數或者中心對齊計數;
預分頻器寄存器(TIMx_PSC)
???????可將時鐘頻率按1到65535之間的任意值進行分頻,可在運行時改變其設置值;
自動裝載寄存器(TIMX ARR)
????????如果TIMx_CR1寄存器中的ARPE位為0,ARR寄存器的內容將直接寫入影子寄存器;如果ARPE為1,ARR寄存器的那日同將在每次的更新時間UEV發生時,傳送到影子寄存器;

輸入捕獲通道

1.IC1、2和IC3、4可以分別通過軟件設置將其映射到T11、TI2和TI3、TI4;
2.4個16位捕捉比較寄存器可以編程用于存放檢測到對應的每一次輸入捕捉時計數器的值,
3.當產生一次捕捉,相應的CCxIF標志位被置1;同時如果中斷或DMA請求使能,則產生中斷或DMA請求。
4.如果當CCxIF標志位已經為1,當又產生一個捕捉,則捕捉溢出標志位CCxOF將被置1。

輸出比較通道

PWM模式運行產生:
????????定時器2、3和4可以產生獨立的信號:頻率和占空比可以進行如下設定一個自動重載寄存器用于設定PWM的周期;每個PWM通道有一個
捕捉比較寄存器用于設定占空時間。

兩種可設置PWM模式:
????????邊沿對齊模式
????????中心對齊模式

常用庫函數

定時器參數初始化函數(第一個參數定時器幾,第二個參數結構體指針)

?void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

結構體內部成員

typedef struct
{uint16_t TIM_ClockDivision; ? ? //外部輸入時鐘分頻因子,基本定時器沒有uint16_t TIM_CounterMode; ? ? ? //計數模式,基本定時器只能向上計數uint16_t TIM_Period; ? ? ? ? ? //自動重裝載值 //注意重裝載值和分頻因子的數配置不能超過65535uint16_t TIM_Prescaler; ? ?//分頻因子 ? ? ?uint8_t TIM_RepetitionCounter;  //重復計數值,基本定時器沒有,高級定時器專用} TIM_TimeBaseInitTypeDef; ?
65535

?定時器控制LED燈軟件流程設計

初始化系統

? ? ? ? 初始化定時器和LED的IO時鐘、初始化LED的引腳IO

? ? ? ? 使能定時器時鐘、初始化定時器、開啟中斷配置、使能定時器、

編寫定時器中斷函數

定時器時間= (ARR+1)*(PSC+1)/TCLK(72M=72 000 000)

假如定時1秒 1= 72 00*10000/72M

#include "stm32f10x.h"
#include "tim.h"void Base_Tim_Init()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);TIM_TimeBaseInitTypeDef TIM_TimeIinitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeIinitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeIinitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeIinitStruct.TIM_Period = 7200 - 1;TIM_TimeIinitStruct.TIM_Prescaler = 10000 - 1;TIM_TimeIinitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_TimeIinitStruct);TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);TIM_Cmd(TIM2, ENABLE);NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStruct);}
  TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);
第二個參數
輸入捕獲輸出比較所用到的通道
如果我們只是想產生定時器的更新源中斷用第一個參數

#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "bear.h"
#include "key.h"
#include "relay.h"
#include "shake.h"
#include "usart.h"
#include "stdio.h"
#include "tim.h"void delay(uint16_t time) {uint16_t i = 0;while (time--) {i = 12000;while (i--);}
}int main() 
{Led_Init();Base_Tim_Init();while (1){       			}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){GPIO_ResetBits(GPIOA, GPIO_Pin_1);delay(1000);GPIO_SetBits(GPIOA, GPIO_Pin_1);delay(1000);}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}

定時器中斷應用?

超聲波模塊

? ? ? ? ? ? ? ? ? ? ? ? ?

?1.工作原理

首先單片機給Trig引腳,給至少10us(10微秒)的高電平信號。

模塊自動發送8個40KHz的方波,自動檢測是否有信號返回。

有信號返回,通過Echo引腳輸出高電平,高電平持續時間就是超聲波從發射到返回的時間

HC-SR04超聲波測距模塊提供2cm-400cm的測距功能,精度達3mm。

2.硬件接線

四根杜邦線,VCC連接單片機3.3-5V(推薦5V供電),GND接到板子的GND,Trig為外部觸發信號輸入,輸入一個10us的高電平即可觸發模塊測距,Echo(接收引腳)即為 回響信號輸出,測距結束時此管引腳輸出一個低電平,電平寬度反映超聲波往返時間之和。

3.控制超聲波測距步驟

初始化定時器時鐘和定時器中斷

初始化超聲波時鐘和超聲波引腳模式

編寫定時器中斷函數測距

先發送10us的高電平信號,發送了之后我的定時器就開始捕獲Echo的高電平的時間,什么時候低電平就什么時候關閉定時器,就開始算比如說我們產生了多少次定時器的中斷,比如是一次定時器中斷是1秒,多少個定時器中斷就是多少個秒,通過一系列公式就能知道距離是多少

1.?發送 10μs 的高電平信號(觸發信號)

  • 目的:啟動一次測距操作。
    這里的 “發送高電平” 通常是通過單片機的 IO 口輸出一個持續?10 微秒(μs)?的高電平脈沖(如 HC-SR04 模塊需要這樣的觸發信號)。

  • 為什么是 10μs?
    這是目標設備(如超聲波傳感器)的協議規定,用于告知傳感器 “開始發射信號”(例如超聲波傳感器會在接收到 10μs 高電平后,發射一束超聲波)。

2.?定時器開始捕獲 Echo 信號的高電平時間

  • Echo 信號是什么?
    Echo 是 “回波信號”,即目標設備接收到反射回來的信號后,輸出的電信號。例如:

    • 發送端發射超聲波后,Echo 信號保持低電平;

    • 當超聲波遇到障礙物反射回來被接收端檢測到,Echo 信號變為高電平;

    • 直到信號接收完畢,Echo 信號重新變為低電平。

  • 定時器的作用
    從觸發信號發送完成的時刻起,定時器開始記錄 Echo 信號?高電平的持續時間(即從 “收到回波” 到 “回波結束” 的時間)。

3.?檢測到低電平時關閉定時器

  • 何時關閉定時器?
    當 Echo 信號從高電平跳轉為低電平時(即回波接收完畢),立即停止定時器計數。

  • 本質
    定時器記錄的是?“回波信號高電平的持續時間 T”,這個時間 T 等于信號從發射到接收的?往返時間(即信號從發射端→障礙物→接收端的總時間)。

4.?通過定時器中斷次數計算時間 T

  • 定時器中斷機制
    定時器通常配置為按固定周期產生中斷(例如每 1μs、1ms 產生一次中斷),每次中斷時計數器加 1。

    • 假設定時器中斷周期為?1μs(即每 1 微秒產生一次中斷),中斷次數為 N 次,則總時間?T = N × 1μs

    • (原句中 “一次中斷是 1 秒” 是簡化舉例,實際應用中中斷周期遠小于 1 秒,通常為微秒或毫秒級,否則精度不足。)

  • 如何計算中斷次數?
    定時器啟動后,每當 Echo 為高電平時,中斷計數器持續累加,直到 Echo 變低時停止計數,此時計數器的值即為高電平期間的中斷次數。

5.?通過公式計算距離

  • 核心公式(以超聲波測距為例)
    距離 = (信號速度 × 時間 T) / 2

    • 除以 2 的原因:信號往返一次(發射→障礙物→接收),實際距離是單程距離。

    • 信號速度:超聲波在空氣中約為 340m/s(即 0.034cm/μs),光速約為 3×10?m/s(用于激光測距)。

  • 舉例計算
    若 T = 1000μs(1 毫秒),則距離 = (0.034cm/μs × 1000μs) / 2 = 17cm。

?超聲波代碼框架

只有收到回響信號的時候,我們的trigr,在信號發出的時候我的echo引腳輸入給我們的單片機,然后如果我們的單片機之前是低電平,檢測高電平的瞬間才開始打開定時器(怎么打開和關閉定時器呢)之前配置定時器的時候結構體配置和中斷的配置TIM_Cmd(TIM2, DISABLE);函數,先關閉

當收到信號的時候再打開,怎么計算高電平時間?首先要先判斷echo引腳什么時候變成高電平
用GPIO_ReadInputDataBit函數然后這里再打開定時器這時就開始我們的中斷函數,中斷函數去計數定時器進入的次數,因為我們用定時器的開啟的時候用定時器的中斷計算進入定時器的時間,注意? 這里定時器的配置TIM_Initstruct.TIM_Period = 1000 -1;? TIM_Initstruct.TIM_Prescaler = 72 -1;

所以定時器的定時周期的1毫秒,計數器每計1次代表1微秒?,中斷1次是1毫秒,因為我們對應的時間是高電平的時間等于中斷次數加上不足一個中斷的次數(不足一個中斷的次數是說不到1毫秒但有多少個微秒呢)打開定時器,就會跳到定時器中斷函數void TIM2_IRQHandler()讓mscount++;這里需要定義一個新變量,然后關閉定時器,計算總電平時間,定義一個變量uint16_t t=0;定義一個函數專門用來封裝總的高電平時間int Get_Echon_Time()(這里返回值是int)然后將總時間換算成距離以種種方式將t換算距離然后返回值length
?

#include "stm32f10x.h"
#include "tim.h"uint16_t mscount = 0;//定義一個變量專門用來記錄中斷的次數void delay_us(uint32_t us)
{us*= 8;while(us--);//延時微秒函數}	
void delay_ms(uint32_t ms)
{while(ms--){delay_us(1000);}	//延時毫秒函數}void Base_Tim_Init()
{TIM_TimeBaseInitTypeDef TIM_Initstruct;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_TIM_Initstruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_Initstruct.TIM_ClockDivision =TIM_CKD_DIV1;TIM_Initstruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_Initstruct.TIM_Period = 1000 -1;TIM_Initstruct.TIM_Prescaler = 72 -1;TIM_Initstruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_Initstruct);TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);TIM_Cmd(TIM2, DISABLE);NVIC_TIM_Initstruct.NVIC_IRQChannel =  TIM2_IRQn;NVIC_TIM_Initstruct.NVIC_IRQChannelCmd = ENABLE;NVIC_TIM_Initstruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_TIM_Initstruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_TIM_Initstruct);}
void HC04_Iint()
{GPIO_InitTypeDef GPIO_Initstruction;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);//Tring B11GPIO_Initstruction.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Initstruction.GPIO_Pin = GPIO_Pin_11;GPIO_Initstruction.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(GPIOB, &GPIO_Initstruction);//Echo B10GPIO_Initstruction.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Initstruction.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOB, &GPIO_Initstruction);}void Open_Tim()
{TIM_SetCounter(TIM2, 0);mscount = 0;TIM_Cmd(TIM2, ENABLE);}
void Close_Tim()
{TIM_Cmd(TIM2, DISABLE);}
//獲取定時器中斷的次數
void TIM2_IRQHandler()
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){mscount++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}}//獲取總的高電平時間
int Get_Echon_Time()
{uint16_t t = 0;t = mscount * 1000;t = t +TIM_GetCounter(TIM2);delay_ms(50);TIM_SetCounter(TIM2, 0);return t;}float Get_Length()
{float sum = 0;uint16_t t=0;float length = 0;int i = 0;while(i != 5){//1.hc04開始工作 Tring引腳輸出高電平20usGPIO_SetBits(GPIOB,  GPIO_Pin_11)delay_us(20);//延時20微秒GPIO_ResetBits(GPIOB,  GPIO_Pin_11);//然后關閉//2.定時器計算高電平時間while(GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_10) == 0);//當GPIO 10引腳高電平時 會卡在這Open_Tim();//打開定時器while(GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_10) == 1);//當高電平跳成低電平時Close_Tim();//關閉定時器t = Get_Echon_Time();//3.將時間換算成距離length = ((float)t/58.0);sum = sum+length;}length = sum/5.0;return length;}
int main() 
{float length = 0;my_usart_init();Ch04_Init();Led_Init();Base_Tim_Init();while (1){length = Get_Length();printf("%f\r\n",length);}
}

?通用定時輸出PWM

第一步內部時鐘的選擇,第二步是預分頻器,計數器,去配置輸出 捕獲和比較

定時器3的通道2?

TIM3為例,STM32的通用定時器氛圍TIM2,TIM3,TIM4,TIM5,每個定時器都有獨立的四個通道可以用來作為: 輸入捕獲,輸出比較,PWM輸出,單脈沖模式輸出等。

STM32的定時器除了TIM6TIM7(基本定時器)之外,其他的定時器都可以產生PWM波輸出,高級定時器TIM1,TIM8可以同時產生7PWM輸出,而通用定時器可以同時產生4PWM輸出,這樣STM32可以最多同時輸出30PWM輸出。

?PWM的工作原理

以向上計數為例,講述PWM原理:

①在PWM輸出模式下除了CNT(計數器當前值)ARR(自動重裝載值)CCRx(捕獲/比較寄存器值)

②當CNT小于CCRx時,TIMx_CHx通道輸出低電平

③當CNT等于或大于CCRx時,TIMx_CHx通道輸出高電平

假設ARR設置是100CRRX是80,在0加到80過程中都屬于低電平,在80加到100都屬于高電平,這就是一個周期,所以占空比為百分之二十,

????????? 所謂脈寬調制信號(PWM),就是一個TIMx_ARR自動重裝載寄存器確定頻率=周期的導數(由它決定PWM周期),TIM_CCRx寄存器確定占空比信號。

占空比=高電平占低電平的時間

?PWM的內部運作機制

CCR1:設置捕獲比較寄存器,設置比較值。??????

CCMR1寄存區:設置PWM模式1 或者PWM模式2

CCER:? P位:輸出/捕獲?? :設置極性: 0 高電平有效,1 低電平有效

???????????? E位:輸出/捕獲?? : 使能端口

PWM的模式?

模式一??? 邊沿對齊模式

向上計數時: 當TIMx_CNT<TIMx_CCRx時通道1為有效電平,否則為無效電平(計數值小于有效值是有效電平)

向下計數時:?? 一旦TIMx_CNT>TIMx_CCRx,CCR1通道1為無效電平,否則為有效電平(計數值大于比較值為無效電平)

但是這里的有效電平是高電平還是低電平有極性( 0 高電平有效,1 低電平有效)去選擇

模式二??? 中央對齊模式

向上計數時: 當TIMx_CNT<TIMx_CCRx時通道1為無效電平,否則為無效電平;

向下計數時:?? 一旦TIMx_CNT>TIMx_CCRx,CCR1通道1為有效電平,否則為無效電平。

和模式一相反

?但是這里的有效電平是高電平還是低電平有極性( 0 高電平有效,1 低電平有效)去選擇

?自動加載的預加載寄存器

?

簡單的說:

APER =1 ,ARR立即生效

APER =0,ARR下個周期生效

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

?定時器輸出PWM 結構體

typedef struct
{uint16_t TIM_OCMode;            //配置PWM模式1還是模式2uint16_t TIM_OutputState;       //配置輸出使能/ OR失能uint16_t TIM_OutputNState;     uint16_t TIM_Pulse;                  //配置比較值,CCRxuint16_t TIM_OCPolarity;         //比較輸出極性uint16_t TIM_OCNPolarity;   uint16_t TIM_OCIdleState;  uint16_t TIM_OCNIdleState;  
} TIM_OCInitTypeDef;

定時器輸出PWM 庫函數

void TIM_OCxInit                      //結構體初始化
(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_SetCompare1            //設置比較值函數
(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_OC1PreloadConfig     //使能輸入比較預裝載
(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_Cmd                            //開啟定時器(TIM_TypeDef* TIMx, FunctionalState NewState)
void TIM_ARRPreloadConfig     //使能自動重裝載的預裝載寄存器允許位
(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PolarityConfig      //配置修改極性
(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

定時器輸出PWM 庫函數

TIM3 PWM輸出? 驅動SG90電機??? 配置過程:

1.GPIO結構體

2.配置通用定時器結構體

3.配置定時去輸出PWM結構體

4.打開時鐘? ---> GPIO時鐘,TIM定時器時鐘,部分重映射時鐘

5.配置PWM比較值

void motor_config(void)
{GPIO_InitTypeDef GPIO_MotorInitStruct;TIM_TimeBaseInitTypeDef TIM_MotorInit;TIM_OCInitTypeDef TIMPWM_MotorInit;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//部分重映射配置GPIO_MotorInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_MotorInitStruct.GPIO_Pin = GPIO_Pin_5;GPIO_MotorInitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_MotorInitStruct);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);TIM_MotorInit.TIM_ClockDivision = TIM_CKD_DIV1;       //設置時鐘分割TIM_MotorInit.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上計數模式TIM_MotorInit.TIM_Period = 200-1;//設置下一個更新事件裝入活動的自動重裝載值TIM_MotorInit.TIM_Prescaler = 7200 -1;	//分頻周期TIM_TimeBaseInit(TIM3, &TIM_MotorInit);TIMPWM_MotorInit.TIM_OCMode = TIM_OCMode_PWM1;//選擇定時器模式1TIMPWM_MotorInit.TIM_OutputState = TIM_OutputState_Enable;//比較輸出使能TIMPWM_MotorInit.TIM_OCNPolarity = TIM_OCPolarity_Low;//選擇有效輸出極性TIM_OC2Init(TIM3, &TIMPWM_MotorInit);//因為選擇的是定時器3的通道2 所以選OC2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);TIM_Cmd(TIM3, ENABLE);}
int main() 
{uint16_t pwmval = 155;motor_config();while(1){for(pwmval = 195;pwmval >= 175;pwmval-=5){TIM_SetCompare2(TIM2,  pwmval);delay(500);}}}

垃圾桶項目?

int main() 
{int  pwmval =195;float Length =0;Ch04_Init();	my_usart_init();motor_config();while(1){pwmval =155;Length= Get_Length();printf("%.3f\r\n",Length);if(Length<5){for(pwmval=195;pwmval>=155;pwmval-=15){TIM_SetCompare2(TIM3, pwmval);delay(500);	}}else if(Length>5){TIM_SetCompare2(TIM3, pwmval-20);}}}

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

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

相關文章

OpenObserve API Usage Guide for Log Management

OpenObserve API Usage Guide for Audit Log Management 1. 概述 1.1 目標 本文檔旨在詳細介紹 OpenObserve 的 API 使用方法&#xff0c;幫助用戶通過 API 實現日志管理功能&#xff0c;包括日志攝入、查詢、模糊匹配&#xff08;類似 SQL 的 LIKE&#xff09;、stream 管理…

消防崗位技能競賽流程方案策劃

一、比賽目的&#xff1a; 為大力倡導“11.9”全國消防安全活動月&#xff0c;緊緊圍繞“人人參與消防&#xff0c;共創平安和諧”的活動主題&#xff0c;結合公司實際情況&#xff0c;特開展一次消防技能競賽活動。開展一場比思想、比工作作風、比消防業務技能、比業余文化生…

DAY9-USF4.0技術文檔筆記

目錄 1.概述 2.參考協議標準 3.術語與定義 4.引言 5.UFS架構 6.UFS電氣特性&#xff1a;時鐘、復位、信號與電源 7.復位、加電升壓和斷電降壓 8. M-PHY 9.UniPro 10.UTP 11.SCSI 12.UFS安全 13.UFS功能描述 14.描述符、標志與屬性 15.UFS機械標準 SCSI 查詢命令 1.重要產品…

安裝kubernetes 1.33版本

一、環境準備 1、內核升級 #升級內核&#xff1a; yum -y install kernel-ml-5.10.3-1.el7.elrepo.x86_64.rpm kernel-ml-devel-5.10.3-1.el7.elrepo.x86_64.rpm# 查詢可用內核版本 # awk -F\ $1"menuentry " {print i " : " $2} /etc/grub2.cfg# 調整默…

【IPMV】圖像處理與機器視覺:Lec8 Image Pyramid 圖像金字塔

【IPMV】圖像處理與機器視覺 本系列為2025年同濟大學自動化專業**圖像處理與機器視覺**課程筆記 Lecturer: Rui Fan、Yanchao Dong Lec0 Course Description Lec3 Perspective Transformation Lec7 Image Filtering Lec8 Image Pyramid 持續更新中 文章目錄 【IPMV】圖像處…

產品經理.產品設計.產品設計工具

一、 產品經理常用工具 1. 業務流程圖---系統流程圖 業務流程圖&#xff0c;面向用戶調研&#xff0c;描述業務的流轉和數據的處理要求&#xff0c;跟用戶和業務方確認&#xff1b;---業務角色的泳道流程圖。 系統流程圖&#xff0c;面向產品需求設計&#xff0c; prd系描述各…

6軸、智能、低功耗慣性測量單元BMI270及其OIS接口

BOSCH慣性傳感器IMUs 芯片代碼 通過00寄存器讀回的芯片編碼可以判斷芯片型號,BMI270為(0x24) &#xff0c;如不是該值&#xff0c;則說明不是BMI270。 型號芯片代碼BMI085CHIP_ID ( 0x1F)BMI088CHIP_ID ( 0x1E)BMI160CHIP_ID (0xD1)BMI270CHIP_ID (0x24)BMI323CHIP_ID (0x004…

【文獻速遞】鄰位連接技術(PLA)在細胞器相互作用中的應用

在神經科學研究領域&#xff0c;細胞死亡機制一直是關注的重點&#xff0c;尤其是與神經退行性疾病相關的細胞死亡形式。荷蘭格羅寧根大學的研究人員在2025年發表了“Regulation of calcium signaling prevents neuronal death mediated by NIST DEP in xenoferroptotic cell d…

六.割草機技術總結--6.RTK定位精度分析

六.割草機技術總結–6.RTK定位精度分析 6.1 1cm+1ppm 中的ppm是什么意思? 精度 RTK 位置精度(在 RTK 時)1 cm + 1 ppm ( 水 平 ) 1 . 5 cm + 1 ppm ( 垂 直 ),其中的ppm是什么意思? 在RTK(實時動態定位)技術中,ppm表示 Parts Per Million(百萬分之一),是一種與距離…

MCP的基礎知識

一、了解MCP的基礎知識 1.函數調用Function Calling Function Calling是openai在2023年推出的一個非常重要的概念&#xff1a;Function Calling&#xff08;函數調用&#xff09;本質上就是提供了大模型與外部系統的交互能力&#xff0c;類似于給大模型安裝了一個“外掛工具箱…

量化交易之數學與統計學基礎2.4——線性代數與矩陣運算 | 矩陣分解

量化交易之數學與統計學基礎2.4——線性代數與矩陣運算 | 矩陣分解 第二部分&#xff1a;線性代數與矩陣運算 第4節&#xff1a;矩陣分解&#xff1a;奇異值分解&#xff08;SVD&#xff09;在數據壓縮和風險分解的應用 一、奇異值分解&#xff08;SVD&#xff09;基礎&#xf…

極簡主義在 UI 設計中的應用與實踐:打造簡潔高效界面

極簡主義理念&#xff1a;簡潔不簡單? 極簡主義起源于 20 世紀初的包豪斯運動&#xff0c;它不僅是一種設計風格&#xff0c;更代表著一種生活態度與價值觀。其核心理念 “少即是多”&#xff0c;并非簡單地削減元素&#xff0c;而是在精簡中追求極致&#xff0c;將設計簡化到…

2025年“深圳杯”數學建模挑戰賽C題-分布式能源接入配電網的風險分析

布式能源接入配電網的風險分析 小驢數模 背景知識&#xff1a; 隨著我國雙碳目標的推進&#xff0c;可再生分布式能源在配電網中的大規模應用不可避免&#xff0c;這對傳統配電網運行提出挑戰。為了量化分析配電網中接入分布式能源的風險&#xff0c;需要對其進行建模與分析…

《解鎖LibTorch:開啟C++深度學習新征程》

《解鎖LibTorch:開啟C++深度學習新征程》 深度學習與 LibTorch 在當今數字化時代,深度學習已成為人工智能領域的核心驅動力,廣泛應用于計算機視覺、自然語言處理、語音識別等諸多領域,深刻改變著我們的生活和工作方式。它的發展歷程充滿了創新與突破,從最初的理論探索到如…

理想藥用植物的特征綜述-理想中藥材”的系統定義-文獻精讀125

Decoding and designing: Promising routes to tailor-made herbs 解碼與設計&#xff1a;定制化草藥的潛力路徑 摘要 理想藥用植物的特征可歸納為高次生代謝產物含量、高抗逆性、理想的形態以及高產量。本研究提出了兩種策略&#xff0c;用于解析中藥活性成分的生物合成與質…

如何在Dify沙盒中安裝運行pandas、numpy

如何在Dify沙盒中安裝運行pandas、numpy 1. 創建python-requirements.txt文件2. 創建config.yaml文件3. 重啟 docker-sandbox-14. 為什么要這樣改的一些代碼解析&#xff08;Youtube視頻截圖&#xff09; 1. 創建python-requirements.txt文件 在 Dify 的 Docker 目錄下面&…

深度卷積模型:案例研究

1 為什么要進行案例研究&#xff1f; 過去&#xff0c;計算機視覺中的大量研究都集中在如何將卷積層、池化層以及全連接層這些基本組件組合起來&#xff0c;形成有效的卷積神經網絡。 找感覺的最好方法之一就是去看一些示例&#xff0c;就像很多人通過看別人的代碼來學習編程一…

RabbitMQ Linux 安裝教程詳解

RabbitMQ Linux 安裝教程詳解 在 Linux 系統上安裝 RabbitMQ 并確保其穩定運行&#xff0c;對于構建可靠的分布式消息系統至關重要。本文將詳細介紹如何在 Linux 系統上安裝 RabbitMQ&#xff0c;并提供關鍵的注意事項&#xff0c;幫助您避免常見的坑點&#xff0c;確保安裝過…

Godot筆記:入門索引

文章目錄 前言游戲引擎軟件界面關鍵概念GDScript導出成品創建非游戲應用后記 前言 最近對游戲引擎這塊感興趣&#xff0c;特別是因為游戲引擎自帶的很多工具&#xff0c;作為圖形化軟件的開發應該也不錯。 Godot 是一款這幾年比較流行的開源游戲引擎。這里記錄下入門學習使用 …

[C語言]猜數字游戲

文章目錄 一、游戲思路揭秘二、隨機數生成大法1、初探隨機數&#xff1a;rand函數的魔力2、隨機數種子&#xff1a;時間的魔法3、抓住時間的精髓&#xff1a;time函數 三、完善程序四、游戲成果1、游戲效果2、源代碼 一、游戲思路揭秘 猜數字游戲&#xff0c;這個聽起來就讓人…