STM32標準庫通用定時器輸入捕獲

来源:https://www.cnblogs.com/tqht7h/p/18067071
-Advertisement-
Play Games

STM32標準庫定時器輸入捕獲 1.輸入捕獲介紹 輸入捕獲為STM32定時器的一個功能,可以用來測量輸入信號的頻率和占空比。 具體原理:當輸入信號經過比較捕獲通道時,STM32會依據通道的極性設置決定是否觸發捕獲中斷TIM_IT_CCx。此時定時器會將當前計數值TIMx->CNT的值保存在TIMx- ...


STM32標準庫定時器輸入捕獲

1.輸入捕獲介紹

輸入捕獲為STM32定時器的一個功能,可以用來測量輸入信號的頻率和占空比。

具體原理:當輸入信號經過比較捕獲通道時,STM32會依據通道的極性設置決定是否觸發捕獲中斷TIM_IT_CCx。此時定時器會將當前計數值TIMx->CNT的值保存在TIMx->CCRx中,通過計算兩次捕獲中斷的時間差便可計算出捕獲的電平時長,由此可計算出輸入信號的頻率、周期、占空比等信息。

在本文中,使用野火指南者開發板,配置TIM2定時器的通道4為輸入通道,TIM3定時器的通道1為輸出通道。

2. 輸入捕獲通道與定時器初始化

需要引用頭文件

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_tim.h"
void TIM2_Init()                                            // 定時器2初始化
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);     // 使能定時器2的時鐘
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);    // 使能GPIOA的時鐘
	
	GPIO_InitTypeDef GPIO_InitStructure;                    // 定義GPIO_InitTypeDef類型的結構體
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;      // 定義TIM_TimeBaseInitTypeDef類型的結構體
	TIM_ICInitTypeDef TIM_IC_nitStructure;                  // 定義TIM_ICInitTypeDef類型的結構體
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ;              // 選擇通道4的引腳
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   // 設置通道4為浮空輸入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       // 設置引腳速度為50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure);                   // 初始化GPIOA
	
	TIM_TimeBaseInitStructure.TIM_Period = 1000-1;          // 設置定時器2的自動重裝值,計數到1000-1
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720-1;	    // 設置定時器2的預分頻值,分頻720-1
	TIM_TimeBaseInitStructure.TIM_ClockDivision  = TIM_CKD_DIV1;    // 設置時鐘分割
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 設置計數器模式為向上計數
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);      // 初始化定時器2
	
	TIM_IC_nitStructure.TIM_Channel = TIM_Channel_4;        // 選擇通道4
	TIM_IC_nitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;     // 設置通道4的上升沿觸發
	TIM_IC_nitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;   // 設置通道4的輸入分頻器
	TIM_IC_nitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // 設置通道4映射到TI4
	TIM_IC_nitStructure.TIM_ICFilter = 0x00;                // 設置通道4的濾波器
	TIM_ICInit(TIM2,&TIM_IC_nitStructure);                  // 初始化定時器2的通道4
	
	NVIC_InitTypeDef NVIC_InitStructure;                    // 定義NVIC_InitTypeDef結構體變數
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;         // 選擇定時器2的中斷通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;       // 設置中斷優先順序
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;      // 設置中斷子優先順序
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         // 使能中斷通道
	
	NVIC_Init(&NVIC_InitStructure);                         // 初始化NVIC_InitTypeDef結構體變數
	
	TIM_ITConfig(TIM2,TIM_IT_CC4 | TIM_IT_Update ,ENABLE);  // 使能定時器2的通道4的中斷和更新中斷
	
	TIM_Cmd(TIM2,ENABLE);                                   // 使能定時器2
}

需要註意輸入通道引腳為GPIO_Mode_IN_FLOATING模式,TIM_Period為定時器溢出值。

  • TIM_ICInitTypeDef:輸入捕獲通道配置結構體。

    • TIM_Channel:輸入通道,可選參數為TIM_Channel_x。

    • TIM_ICPolarity:輸入通道極性設置,可選參數為TIM_ICSelection_DirectTI、TIM_ICSelection_IndirectTI、TIM_ICSelection_TRC。

      • TIM_ICSelection_DirectTI:將定時器輸入通道1、2、3、4依次映射到IC1、IC2、IC3、IC4。

      • TIM_ICSelection_IndirectTI:將定時器輸入通道1、2、3、4依次映射到IC2、IC1、IC4、IC3。

      • TIM_ICSelection_TRC:將定時器輸入通道1、2、3、4連接至TRC我暫時也不知道這個TRC是啥

    • TIM_ICFilter:輸入通道濾波器設置,可選參數為0x0~0xF。決定了多少次邊沿變換會觸發一次輸入捕獲。

3. 中斷函數編寫

輸入捕獲中斷與定時器中斷共用一個中斷NVIC。

uint16_t Up_Capture_Cnt,Down_Capture_Cnt,Up_Capture,Up_Capture_Cnt_Temp,Down_Capture;
uint16_t timer_cnt2,timer_cnt1 = 0;
uint16_t Get_State = 0,Get_State1 = 0;

void TIM2_IRQHandler()                              // 定時器2中斷函數
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)  // 定時器2更新中斷
	{
		timer_cnt1++;                               // 定時器計數標誌量1每溢出一次加一
		timer_cnt2++;                               // 定時器計數標誌量2每溢出一次加一
		if(timer_cnt1 == 10000)                     // 定時器計數標誌量1溢出時清零
		{
			timer_cnt1 = 0;                         // 定時器計數標誌量1清零
		}
		if(timer_cnt2 == 10000)                     // 定時器計數標誌量2溢出時清零
		{
			timer_cnt2 = 0;                         // 定時器計數標誌量2清零
		}
	}
	if(TIM_GetITStatus(TIM2,TIM_IT_CC4) == SET)     // 定時器2輸入捕獲中斷
	{
		switch(Get_State)                           // 判斷輸入捕獲狀態
		{
			case 0 :            
				Up_Capture_Cnt_Temp = Up_Capture_Cnt;       // 保存上一次輸入捕獲通道的值
				Down_Capture_Cnt =  TIM_GetCapture4(TIM2);  // 獲取當前輸入捕獲通道的值
				Down_Capture = Down_Capture_Cnt + (timer_cnt2 * 1000) - Up_Capture_Cnt_Temp;    // 計算脈衝寬度
				timer_cnt1 = 0;                             // 定時器計數標誌量1清零
				timer_cnt2 = 0;                             // 定時器計數標誌量2清零
				TIM_ClearITPendingBit(TIM2,TIM_IT_CC4);     // 清除輸入捕獲通道的中斷標誌位
				TIM_OC4PolarityConfig(TIM2,TIM_ICPolarity_Falling); // 設置輸入捕獲通道的極性為下降沿
				Get_State = 1;                              // 設置輸入捕獲通道的狀態為1
				break;                                      // 跳出switch語句
			case 1:         
				Up_Capture_Cnt =  TIM_GetCapture4(TIM2);    // 獲取當前輸入捕獲通道的值
				Up_Capture = Up_Capture_Cnt + (timer_cnt1 * 1000) - Down_Capture_Cnt;           // 計算脈衝寬度
				timer_cnt1 = 0;                             // 定時器計數標誌量1清零
				timer_cnt2 = 0;                             // 定時器計數標誌量2清零
				TIM_ClearITPendingBit(TIM2,TIM_IT_CC4);     // 清除輸入捕獲通道的中斷標誌位
				TIM_OC4PolarityConfig(TIM2,TIM_ICPolarity_Rising);  // 設置輸入捕獲通道的極性為上升沿
				Get_State = 0;                              // 設置輸入捕獲通道的狀態為0
				break;                                      // 跳出switch語句
		}
	}
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);              // 清除定時器溢出中斷標誌位
}

4. 中斷函數代碼具體邏輯解釋

光看代碼可能捋不清先後關係,來看下圖就知道了,如圖1所示:

alt text

圖1.採集輸入捕獲信號矢量圖
在圖中可以看到,當輸入捕獲通道的信號周期要長於輸入捕獲的通道時鐘周期時,會導致第二次讀取的值比第一次讀取的值小,如果不使用定時器溢出次數進行輔助運算會導致算出來的是負數。之後第一次讀取的值+溢出時間-第二次讀取的值,得到的結果就是脈衝寬度,第二次讀取的值+溢出時間-第一次讀取的值,得到的就是周期中另一部分的寬度。有了這些信息,就可以得到頻率、周期和占空比了。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Playwright 是一個由 Microsoft 開發的開源工具,用於自動化 Web 瀏覽器的測試和操作。它提供了一種跨瀏覽器、跨平臺的自動化解決方案,可以在 Chromium、Firefox 和 WebKit(Safari)等多種瀏覽器上進行測試和操作。本篇隨筆介紹Playwright的一些特點... ...
  • 概述:在.NET Core中,通過創建RequestCountMiddleware中間件,結合MemoryCache,實現了記錄最近5分鐘請求次數的功能。該中間件在每個請求中更新計數,並使用緩存存儲,為簡單而實用的請求監控提供了一個示例。 要實現一個在.NET Core中記錄最近5分鐘請求次數的Re ...
  • 人大金倉優點 人大金倉是國產最主流資料庫之一 具有和PgSql一樣強悍的性能,同時人大金倉支持了四種資料庫模式 : Oracle、PgSql、MySql和SqlServer ,假如你們系統有多種資料庫開發 有國產化要求,那麼你們切換到人大金倉就會很方便了 Nuget安裝 C# ORM 搜索人大金倉安 ...
  • 介紹FastWiki FastWiki是一個高性能、基於最新技術棧的知識庫系統,旨在為大規模信息檢索和智能搜索提供解決方案。它採用微軟Semantic Kernel進行深度學習和自然語言處理,在後端使用MasaFramework,前端採用MasaBlazor框架,實現了一個高效、易用、可擴展的智能向 ...
  • 通過引入分散式冪等性框架,可以有效處理分散式系統中的重覆操作問題,確保系統穩定運行並保持數據的一致性。 ...
  • 前言 雖然已經正式轉JAVA了,但最近發現一個特別好的開源項目masuit,不僅提供很多簡便的功能,還有圖像的一些特殊操作功能。 之前我們比較圖片應該都是使用的openCV,不過這個masuit,看上去也不錯,而且代碼使用簡單,因此強烈推薦。 下麵就實現一個簡單圖像對比。 實現對比 首先添加引用ma ...
  • 前一段時間我用 WPF 開發了一個查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由於最近我使用 macOS 系統比較多,我想能在 macOS 系統上也能使用這個工具。於是我嘗試將 WPF 應用遷移到 Electron 框架,感覺這個框架很強 ...
  • node-exporter常用監控指標 CPU相關指標: node_cpu_seconds_total{mode="idle"}:CPU空閑時間(秒)的總和。這是評估CPU使用率的重要指標之一。 node_cpu_seconds_total{mode="system"}、node_cpu_secon ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...