定時器輸入捕獲實驗

輸入捕獲簡介:
輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。STM32 的定時器,除了 TIM6 和 TIM7,其他定時器都有輸入捕獲功能。STM32 的輸入捕獲,簡單的說就是通過檢測 TIMx_CHx 上的邊沿信號,在邊沿信號發生跳變(比如上升沿/下降沿)的時候,將當前定時器的值(TIMx_CNT)存放到對應的通道的捕獲/比較寄存器(TIMx_CCRx)里面,完成一次捕獲。同時還可以配置捕獲時是否觸發中斷/DMA 等。
STM32 PWM工作過程:
在這里插入圖片描述
STM32 輸入捕獲工作過程(通道1為例):
在這里插入圖片描述
一句話總結工作過程:通過檢測TIMx_CHx上的邊沿信號,在邊沿信號發生跳變(比如上升沿/下降沿)的時候,將當前定時器的值(TIMx_CNT)存放到對應的捕獲/比較寄存器(TIMx_CCRx)里面,完成一次捕獲。

  • 步驟1:設置輸入捕獲濾波器(通道1為例)

在這里插入圖片描述
在這里插入圖片描述

  • 步驟2:設置輸入捕獲極性(通道1為例)

在這里插入圖片描述在這里插入圖片描述

  • 步驟三:設置輸入捕獲映射通道(通道1為例)
    在這里插入圖片描述在這里插入圖片描述
  • 步驟四:設置輸入捕獲分頻器(通道1為例)

在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述

  • 步驟五:捕獲到有效信號可以開啟中斷

在這里插入圖片描述

  • 最后:看看定時器通道對應引腳TIM5為例

在這里插入圖片描述
輸入捕獲通道初始化函數:

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);ypedef struct
{uint16_t TIM_Channel; //捕獲通道1-4   uint16_t TIM_ICPolarity; //捕獲極性uint16_t TIM_ICSelection; //映射關系uint16_t TIM_ICPrescaler; //分頻系數uint16_t TIM_ICFilter;  //濾波器
} TIM_ICInitTypeDef;TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //選擇輸入端 IC1 
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
TIM5_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM5, &TIM5_ICInitStructure); //初始化 TIM5 輸入捕獲通道 1

通道極性設置獨立函數:

void TIM_OCxPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)

獲取通道捕獲值

uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx)

輸入捕獲的一般配置步驟:

1、初始化定時器和通道對應IO的時鐘

  • 初始化IO口,模式為輸入:
GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 輸入
  • 初始化定時器ARR,PSC
TIM_TimeBaseInit();

2、初始化輸入捕獲通道

TIM_ICInit();

3、如果要開啟捕獲中斷

 TIM_ITConfig();NVIC_Init();

4、使能定時器:

TIM_Cmd();

5、編寫中斷服務函數:

TIMx_IRQHandler();

更新中斷和捕獲中斷

u8  TIM5CH1_CAPTURE_STA=0;	//輸入捕獲狀態		    				
u16	TIM5CH1_CAPTURE_VAL;	//輸入捕獲值//定時器5中斷服務程序	 
void TIM5_IRQHandler(void)
{ if((TIM5CH1_CAPTURE_STA&0X80)==0)//還未成功捕獲	{	  if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){	    if(TIM5CH1_CAPTURE_STA&0X40)//已經捕獲到高電平了{if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高電平太長了{TIM5CH1_CAPTURE_STA|=0X80;//標記成功捕獲了一次TIM5CH1_CAPTURE_VAL=0XFFFF;//計數器的最大值}else TIM5CH1_CAPTURE_STA++;//標記有幾次更新事件}	 }if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕獲1發生捕獲事件{	if(TIM5CH1_CAPTURE_STA&0X40)		//捕獲到一個下降沿 		{	  			TIM5CH1_CAPTURE_STA|=0X80;		TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//標記成功捕獲到一次高電平脈寬TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 設置為上升沿捕獲}else  								//還未開始,第一次捕獲上升沿{TIM5CH1_CAPTURE_STA=0;			//清空TIM5CH1_CAPTURE_VAL=0;TIM_SetCounter(TIM5,0);TIM5CH1_CAPTURE_STA|=0X40;		//標記捕獲到了上升沿TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);		//CC1P=1 設置為下降沿捕獲}		    }			     	    					   }TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中斷標志位}

main.c部分代碼:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"extern u8  TIM5CH1_CAPTURE_STA;		//輸入捕獲狀態		    				
extern u16	TIM5CH1_CAPTURE_VAL;	//輸入捕獲值	int main(void){		u32 temp=0; delay_init();	    	 //延時函數初始化	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級uart_init(115200);	 //串口初始化為115200LED_Init();			     //LED端口初始化TIM3_PWM_Init(899,0); 		//不分頻。PWM頻率=72000/(899+1)=80KhzTIM5_Cap_Init(0XFFFF,72-1);	//以1Mhz的頻率計數 while(1){delay_ms(10);TIM_SetCompare2(TIM3,TIM_GetCapture2(TIM3)+1);if(TIM_GetCapture2(TIM3)==300)TIM_SetCompare2(TIM3,0);	if(TIM5CH1_CAPTURE_STA&0X80)//成功捕獲到了一次上升沿{temp=TIM5CH1_CAPTURE_STA&0X3F;temp*=65536;//溢出時間總和temp+=TIM5CH1_CAPTURE_VAL;//得到總的高電平時間printf("HIGH:%d us\r\n",temp);//打印總的高點平時間TIM5CH1_CAPTURE_STA=0;//開啟下一次捕獲}}}

看中斷部分代碼時建議從下向上看,從else向上看,最開始初始化設置的就是上升沿捕獲,所以先執行最后一個else然后再進行下降沿的捕獲進入if語句,從而完成了一次高電平脈寬的測量,若脈寬比較長在計時器溢出后還沒有變為低電平,則在判斷是否發生更新事件,若發生,則執行TIM5CH1_CAPTURE_STA++,記錄溢出的次數,最大為2的6次方,若TIM5CH1_CAPTURE_STA&0x3f==0x3f,說明已達到TIM5CH1_CAPTURE_STA所能記錄的最大溢出次數,所以就結束捕獲,然后就會進入main函數進行計算高電平的脈寬。

(以上是個人理解,若有錯誤請指正)

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

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

相關文章

黑馬程序員—————— 多線程

java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。每個線程的作用是完成一定的任務,實際上就是執行一段程序流(一段順序執行的代碼)。java使用線程執行體來代表這段程序流。 繼承Thread類創建線程類 通過…

Linux查看內置命令和非內置命令幫助的幾種方法(man、help、info)

??作者主頁:IT技術分享社區 ??作者簡介:大家好,我是IT技術分享社區的博主,從事C#、Java開發九年,對數據庫、C#、Java、前端、運維、電腦技巧等經驗豐富。 ??個人榮譽: 數據庫領域優質創作者🏆&#x…

電容觸摸按鍵 實驗

RC充放電電路原理: RC電路充放電公式: Vt V0(V1-V0)* [1-exp(-t/RC)]V0 為電容上的初始電壓值; V1 為電容最終可充到或放到的電壓值; Vt 為t時刻電容上的電壓值。如果V0為0,也就是從0V開始充…

tomcat調優方案Maximum number of threads (200) created for connector with address null and port 8091...

1.tomcat6大并發出現:INFO: Maximum number of threads (200) created for connector with address null and port 8091 說明:最大線程數錯誤 解決方案:使用線程池,用較少的線程處理較多的訪問,可以提高tomcat處理請…

SFTP是什么?與FTP之間有什么區別

什么是SFTP? SFTP是一種安全的文件傳輸協議,一種通過網絡傳輸文件的安全方法;它確保使用私有和安全的數據流來安全地傳輸數據。 SFTP要求客戶端用戶必須由服務器進行身份驗證,并且數據傳輸必須通過安全通道(SSH&#x…

C++基礎( C++初識、數據類型、運算符、程序流程結構、)

前言&#xff1a; C專欄筆記來源于觀看視頻筆記 配套視頻&#xff1a; https://www.bilibili.com/video/BV1et411b73Z?p16 基本代碼框架&#xff1a; #include <iostream> using namespace std; int main() {system("pause");//等待程序return 0; }輸出Hell…

C#判斷某天是否是周末或者節假日示例

/// <summary> /// 判斷是不是周末/節假日 /// </summary> /// <param name"date">日期</param> /// <returns>周末和節假日返回true&#xff0c;工作日返回false</returns> public static async Task<bool> IsHolidayByD…

查看docker版本命令docker version

查看docker版本 docker version

spring security原理

spring security通過一系列過濾器實現其功能&#xff0c;入口過濾器如下&#xff08;web.xml&#xff09;&#xff1a; <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilt…

程序員太牛了 公司年會整成代碼討論會

作者丨前端小喬 https://blog.csdn.net/weixin_44330260/article/details/86478512 公司年底年會&#xff0c;被程序員開成代碼討論大會&#xff0c;是一種什么樣的體驗&#xff01;最近某公司舉行了一場年會&#xff0c;本來熱熱鬧鬧&#xff0c;結果被程序員給攪煳了&#xf…

嵌入式C語言基礎(一)

嵌入式C語言基礎&#xff1a; system函數&#xff1a;功能是運行windows命令 #include <stdio.h> #include <stdlib.h> int main() {//main是程序的入口&#xff0c;操作系統運行程序先找mainsystem("ipconfig");//在windows下ipconfig查看本地的網絡狀…

docker info 顯示 Docker 系統信息

docker info : 顯示 Docker 系統信息&#xff0c;包括鏡像和容器數

如何通過session控制單點登錄

web服務器為每一個瀏覽器實例對應一個session。這個session有自己的一個獨立id,這個id保存在瀏覽器的cookie中&#xff08;這個cookie貌似隨著這個瀏覽器實例的關閉而清除&#xff09;&#xff0c;訪問web服務器的時候&#xff0c;web服務會根據你cookie中的sessionId來決定重新…

Syncd - 開源自動化部署工具

官網地址&#xff1a;https://gitee.com/dreamans/syncd/issues syncd是一款開源的代碼部署工具&#xff0c;它具有簡單、高效、易用等特點&#xff0c;可以提高團隊的工作效率. 目前只支持類Linux系統. 特性 Go語言開發&#xff0c;編譯簡單、運行高效 Web界面訪問&#xff0…

嵌入式C語言基礎(二)

指針是分類型的&#xff1a; 指針根據類型不同&#xff0c;偏移值也不同。指針和數組&#xff0c;如何讓指針指向數組&#xff1f; ①用數組名 &#xff1a;int array[10],int* p,parray ②用第一個元素的地址&#xff1a;int array[10],int* p,p&array[0] 注意&#xff1a…

Linus中幫助命令man

使用方法&#xff1a;man 可以查看想要使用命令的詳細使用方法 man 命令

大牛是怎么思考設計SQL優化方案的?

作者&#xff1a;慘綠少年https://www.cnblogs.com/clsn/p/8214048.html在進行MySQL的優化之前&#xff0c;必須要了解的就是MySQL的查詢過程&#xff0c;很多查詢優化工作實際上就是遵循一些原則&#xff0c;讓MySQL的優化器能夠按照預想的合理方式運行而已。圖-MySQL查詢過程…

嵌入式C語言基礎(三)

字符串的定義方式及輸出&#xff1a; #include <stdio.h> #include <stdlib.h> void strPrint(char* data,int size) {int i;for(i0;i<size;i){printf("函數打印數組&#xff1a;%c\n",*data);}putchar(\n); } int main() {int i0;int a[3]{1,2,3};c…