STM32入門學習之定時器輸入捕獲

1.定時器的輸入捕獲可以用來測量脈沖寬度或者測量頻率。輸入捕獲的原理圖如下:

?假設定時器是向上計數。在圖中,t1~t2之間的便是我們要測量的高電平的時間(脈沖寬度)。首先,設置定時器為上升沿捕獲,如此一來,在t1時刻可以捕獲到當前定時器的計數值CNT。然后,清零CNT,并設置定時器為下降沿捕獲,這樣,在t2時刻,又會發生捕獲事件,得到此時CNT的值,記為CCRx2。最后,根據定時器的計數頻率,便可以計數出t1~t2的時間,從而得到高電平的脈沖寬度。

這里的上升沿捕獲是指,當定時器復用的IO口,被輸入高電平時,即t1時刻產生捕獲。下降沿捕獲同理。

此外,在t1~t2之間,可能產生N次的定時器溢出。為了使數據準確,需要對定時器的溢出做出處理,防止高電平的時間過長。本次實驗中的處理方式為,當溢出的次數達到一定值時,強制認為已經捕獲完成(捕獲到上升沿、捕獲到下降沿)。

CNT的計數次數:N*ARR+CRRx2。

用CNT的計數次數乘以計數周期,便可以得到t1~t2的時間長度,即高電平持續的時間。

2.修改寄存器介紹:TIMx_ARRTIMx_PSCTIMx_CCMR1TIMx_CCERTIMx_DIERTIMx_CR1TIMx_CCR1等寄存器的介紹可以在前面的博客中定時器介紹部分查看。此處只介紹TIMx_CCMR1寄存器和TIMx_CCER寄存器。

(1)捕獲/比較寄存器(TIMx_CCMR1):

?當在輸入捕獲模式下使用時,對于著圖中的第二行。低八位[7:0]用于捕獲/比較寄存器通道1的控制。高八位[15:8]用于捕獲/比較寄存器通道2的控制。本次實驗中使用的通道1,因此,只介紹TIMx_CCMR1的低八位。

[7:0]各位的描述如下:

?(2)捕獲/比較使能寄存器(TIMx_CCER):

?要想使能輸入捕獲,必須設置CC1E為1。

3.設計思路:

(1)使能TIM2時鐘,配置PA0為下拉輸入。(開發版中PA0與TIM2_CH1復用,并外接了按鍵。)

(2)初始化TIM2,設置TIM2的ARR和PSC。

(3)設置TIM2的輸入比較參數,開啟輸入捕獲。

4.代碼:通過按鍵的狀態獲取高低電平的時間,并將時間通過串口打印。同時,使用到了定時器2的中斷服務函數。

(1)usart:

#ifndef __USART_H
#define __USART_H#include "stm32f10x.h"
#include <stdio.h>#define RX_LEN 100						//?ü1??óêüμ?×?′ó×??úêyextern u8 RX_BUF[RX_LEN];
extern int len;
extern u8 RX_FLAG;void usart_init(u32 bound);#endif
#include "USART.h"int len = 0;
u8 data;
u8 RX_BUF[RX_LEN];
u8 RX_FLAG = 0;//′??ú3?ê??ˉoˉêy
void usart_init(u32 bound)
{//1.?¨ò?òy???¢USART?¢?D???á11ì?£oGPIO_InitTypeDef GPIO_Initstruct;USART_InitTypeDef USART_Initstruct;NVIC_InitTypeDef NVIC_Initstruct;//2.ê1?ü???úoíUSARTμ?ê±?ó£oRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO,ENABLE);//3.????òy??£o//PA9£oGPIO_Initstruct.GPIO_Pin = GPIO_Pin_9;GPIO_Initstruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_Initstruct);//PA10:GPIO_Initstruct.GPIO_Pin = GPIO_Pin_10;GPIO_Initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_Initstruct);//4.????USART1:USART_Initstruct.USART_BaudRate = bound;USART_Initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_Initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Initstruct.USART_Parity = USART_Parity_No;USART_Initstruct.USART_StopBits = USART_StopBits_1;USART_Initstruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART1,&USART_Initstruct);		//???à1?êy?YD′è?USARTμ???′??÷USART_Cmd(USART1,ENABLE);								//ê1?üUSART??′??÷USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);		//ê1?ü?óê??D??//5.?????D??£oNVIC_Initstruct.NVIC_IRQChannel = USART1_IRQn;NVIC_Initstruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority = 3;NVIC_Initstruct.NVIC_IRQChannelSubPriority = 3;NVIC_Init(&NVIC_Initstruct);}//void USART1_IRQHandler(void)
//{
//	//uint16_t x[] = {1,2,3};
//	//?D??ê?·?2úéú′??úêy?Y?óêü?D??
//	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
//	{
//		data = USART_ReceiveData(USART1);
//		RX_BUF[len++] = data;
//		RX_FLAG = 1;
//	}
//}//???¨?òfputcoˉêy£o
//int fputc(int ch,FILE *f)
//{
//	//1.?D??′??úê?·?·¢?ííê3é£o
//	while((USART1->SR & 0x40) == 0);
//	
//	//2.·¢?íò???×??ú£???êy?YD′è?μ???′??÷£o
//	USART1->DR = (u8) ch;
//	return ch;
//}
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//?-?··¢?í,?±μ?·¢?ííê±?   USART1->DR = (u8) ch;      return ch;
}

(2)delay:

#ifndef __DELAY_H
#define __DELAY_H#include "stm32f10x.h"void delay_us(uint32_t us);									//?óê±?¢??
void delay_ms(uint32_t ms);									//?óê±oá??#endif
#include "delay.h"void delay_us(uint32_t us)
{uint32_t i;//1.????HCLKê±?ó£?2¢éè??μ?′eê±?ó??êy?μSysTick_Config(72);for(i = 0;i < us;i++){while(!((SysTick->CTRL) & (1 << 16)));		//μè′y??êyíê3é}SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;	//????STCLKê±?ó?′£?2¢ê§?ü?¨ê±?÷
}void delay_ms(uint32_t ms)
{uint32_t i;//1.????HCLKê±?ó?′£?2¢éè??μ?′eê±?ó??êy?μSysTick_Config(72000);for(i = 0;i < ms;i++){while(!((SysTick->CTRL) & (1 << 16)));		//μè′y??êyíê3é}SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;	//????STCLKê±?ó?′£?2¢ê§?ü?¨ê±?÷
}

(3)?? time_capture:

#ifndef __TIME_CAPTURE_H
#define __TIME_CAPTURE_H#include "stm32f10x.h"extern u8 TIM2_CAPTURE_STATU;					//ê?è?2???×′ì?
extern u16 TIM2_CAPTURE_VALUE;void TIME_CAPTURE_Init(u16 arr,u16 psc);#endif
#include "time_capture.h"/*TIM2_CAPTURE_STATUμ?μú7?a2???íê3é±ê??£?
μú6???a2???μ???μ???±ê??£?
μú0-5????2?????μ???oó?¨ê±?÷μ?ò?3?′?êy*/
u8 TIM2_CAPTURE_STATU = 0;					//ê?è?2???×′ì?
u16 TIM2_CAPTURE_VALUE = 0;					//ê?è?2????μvoid TIME_CAPTURE_Init(u16 arr,u16 psc)
{//?¨ò??à1??á11ì?£oGPIO_InitTypeDef GPIO_InitStrcture;TIM_TimeBaseInitTypeDef TIME_TimeBaseStructure;TIM_ICInitTypeDef TIM2_ICInitStructure;NVIC_InitTypeDef NVIC_InitStructure;//1.ê1?üê±?ó£oRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//2.?????à1?μ??á11ì?D??¢£oGPIO_InitStrcture.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStrcture.GPIO_Pin = GPIO_Pin_0;GPIO_InitStrcture.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStrcture);GPIO_ResetBits(GPIOA,GPIO_Pin_0);		//3?ê?ê±??PA0???a0//3.?????¨ê±?÷2£oTIME_TimeBaseStructure.TIM_Period = arr;TIME_TimeBaseStructure.TIM_Prescaler = psc;TIME_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//éè??ê±?ó·???TIME_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;TIM_TimeBaseInit(TIM2,&TIME_TimeBaseStructure);//4.?????¨ê±?÷2μ?ê?è?2???2?êy£oTIM2_ICInitStructure.TIM_Channel = TIM_Channel_1;			//éè??ê?è?í¨μàTIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;		//éè??é?éy??2???TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;	//ó3é?μ?TI1é?TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	//éè??ê?è?·??μTIM2_ICInitStructure.TIM_ICFilter = 0;			//éè????2¨?÷TIM_ICInit(TIM2,&TIM2_ICInitStructure);//5.?D??1üàí????£oNVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStructure);//6.ê1?ü?¨ê±?÷μ??üD??D???¢2????D??oí?¨ê±?÷£oTIM_ITConfig(TIM2,TIM_IT_Update | TIM_IT_CC1,ENABLE);TIM_Cmd(TIM2,ENABLE);}//??D′?¨ê±?÷2μ??D??·t??oˉêy£o
void TIM2_IRQHandler(void)
{if((TIM2_CAPTURE_STATU & 0x80) ==0)				//?1?′2???íê3é{if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET){if(TIM2_CAPTURE_STATU & 0x40)					//2???μ???μ???{//′?′|ê?μ±á?D?2???μ???μ???μ?′?êy>= 0x3Fê±£?????è??a2???3é1|if((TIM2_CAPTURE_STATU & 0x3F) == 0x3F)//??μ???ì?3¤{TIM2_CAPTURE_STATU |= 0x80;			//±ê??2???3é1|TIM2_CAPTURE_VALUE = 0xFFFF;}else{TIM2_CAPTURE_STATU ++;}}}}if(TIM_GetITStatus(TIM2,TIM_IT_CC1) != RESET)	//·¢éú2???ê??t{if(TIM2_CAPTURE_STATU & 0x40)					//2???μ?ò??????μ??{TIM2_CAPTURE_STATU |= 0X80;					//±ê??2???3é1|TIM2_CAPTURE_VALUE = TIM_GetCapture1(TIM2);			//??è???êycnt?μTIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);	//??′?2?×?é?éy??}else{TIM2_CAPTURE_STATU = 0;TIM2_CAPTURE_VALUE = 0;TIM_SetCounter(TIM2,0);						//éè????êy??′??÷μ??μTIM2_CAPTURE_STATU |= 0x40;				//±ê??2?×?μ?á?é?éy??	TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);		//éè????′?2?×????μ??}}TIM_ClearITPendingBit(TIM2,TIM_IT_CC1 | TIM_IT_Update);		//??3y?D??±ê????
}

(4)?? main:

#include "stm32f10x.h"
#include "USART.h"
#include "led.h"
#include "delay.h"
#include "time_capture.h"
#include <stdio.h>extern u8 data;int main(void)
{int i;u32 temp = 0;//?D??ó??è??·?×é£oNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//3?ê??ˉ′??úUSART1:usart_init(9600);//LED_Init();//KEY_Init();TIME_CAPTURE_Init(0xFFFF,72 - 1);//GPIO_ResetBits(GPIOA,GPIO_Pin_8);//GPIO_ResetBits(GPIOD,GPIO_Pin_2);printf("?óêüμ?μ?êy?Y:\r\n");delay_ms(10);while(1){//printf("test\r\n");delay_ms(10);if(TIM2_CAPTURE_STATU & 0X80)					//2?×?μ???μ???{//printf("test2.0\r\n");temp = TIM2_CAPTURE_VALUE & 0x3F;temp *= 65536;temp += TIM2_CAPTURE_VALUE;printf("high = %d us\r\n",temp);TIM2_CAPTURE_STATU = 0;						//?a????ò?′?2???}}
}

5.運行結果:根據按鍵按鍵的時間,計數高電平的時間。

?6.總結:通過定時器捕獲可以測量脈沖寬度或者測量頻率。定時器的捕獲配置,主要是配置相關的寄存器,并重寫定時器中斷服務函數,在中斷服務函數中書寫數據捕獲的邏輯。

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

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

相關文章

使用Cinemachine制作固定路徑動畫

固定路徑配置 選擇一個游戲對象添加CinemachineSmoothPath腳本選擇添加腳本的對象。路徑腳本需要是展開狀態&#xff0c;才可以看到路徑添加點&#xff0c;使用移動工具&#xff0c;調節路徑 對象在路徑上移動 移動對象添加CinemachineDollyCart腳本設置移動路徑(帶有Path腳…

AI 繪畫Stable Diffusion 研究(九)sd圖生圖功能詳解-老照片高清修復放大

大家好&#xff0c;我是風雨無阻。 通過前面幾篇文章的介紹&#xff0c;相信各位小伙伴&#xff0c;對 Stable Diffusion 這款強大的AI 繪圖系統有了全新的認知。我們見識到了借助 Stable Diffusion的文生圖功能&#xff0c;利用簡單的幾個單詞&#xff0c;就可以生成完美的圖片…

阿里云OSS對象存儲的核心概念與購買應用

文章目錄 1.OSS對象存儲基本介紹1.1.OSS對象存儲概念1.2.NAS與OSS存儲的不同1.3.OSS的應用場景1.4.OSS術語對應表 2.購買OSS存儲資源包3.KodCloud云盤接入OSS對象存儲3.1.創建Bucket存儲空間3.2.創建子用戶用于管理Bucket3.3.獲取用戶的AccessKey3.3.為用戶設置權限3.4.將Bucke…

MySQL和Redis如何保證數據一致性

MySQL與Redis都是常用的數據存儲和緩存系統。為了提高應用程序的性能和可伸縮性&#xff0c;很多應用程序將MySQL和Redis一起使用&#xff0c;其中MySQL作為主要的持久存儲&#xff0c;而Redis作為主要的緩存。在這種情況下&#xff0c;應用程序需要確保MySQL和Redis中的數據是…

軟件測試常用工具總結(測試管理、單元測試、接口測試、自動化測試、性能測試、負載測試等)

前言 在軟件測試的過程中&#xff0c;多多少少都是會接觸到一些測試工具&#xff0c;作為輔助測試用的&#xff0c;以提高測試工作的效率&#xff0c;使用好了測試工具&#xff0c;能對測試起到一個很好的作用&#xff0c;同時&#xff0c;有些公司&#xff0c;也會要求掌握一…

__ob__: Observer 后綴的數組的取值方式

開發中&#xff0c;經常從接口、父組件中&#xff0c;拿到數組然后給新的數組使用&#xff0c; 但是&#xff0c;有時候會發現帶有 __ob__: Observer 后綴的數組&#xff0c;對這種數組來說&#xff0c;你是無法取到這個數組的值的&#xff0c; 而且&#xff0c;離譜的是consol…

【深度學習--RNN 循環神經網絡--附LSTM情感文本分類】

deep learning 系列 --RNN 循環神經網絡 什么是序列模型 包括了RNN LSTM GRU等網絡模型&#xff0c;主要用途是自然語言處理、語音識別等方面&#xff0c;比如生成樂曲&#xff0c;音頻轉換為文字&#xff0c;文本情感分類&#xff0c;機器翻譯等等 標準模型的缺陷 以往的標…

flutter 常見的狀態管理器

flutter 常見的狀態管理器 前言一、Provider二、Bloc三、Redux四、GetX總結 前言 當我們構建復雜的移動應用時&#xff0c;有效的狀態管理是至關重要的&#xff0c;因為應用的不同部分可能需要共享數據、相應用戶交互并保持一致的狀態。Flutter 中有多種狀態管理解決方案&#…

0143 串

目錄 4.串 4.1串的定義和實現 4.2串的模式匹配 部分習題 4.串 4.1串的定義和實現 4.2串的模式匹配 部分習題 1.設有兩個串S1和S2&#xff0c;求S2在S1中首次出現的位置的運算稱為&#xff08;&#xff09; A.求字串 B.判斷是否相等 C.模式匹配 D.連…

Vue2(組件開發)

目錄 前言一&#xff0c;組件的使用二&#xff0c;插槽slot三&#xff0c;refs和parent四&#xff0c;父子組件間的通信4.1&#xff0c;父傳子 &#xff1a;父傳子的時候&#xff0c;通過屬性傳遞4.2&#xff0c;父組件監聽自定義事件 五&#xff0c;非父子組件的通信六&#x…

麥肯錫發布《2023年度科技報告》!

在經歷了 2022 年技術投資和人才的動蕩之后&#xff0c;2023 年上半年&#xff0c;人們對技術促進商業和社會進步的潛力重新燃起了熱情。生成式人工智能&#xff08;Generative AI&#xff09;在這一復興過程中功不可沒&#xff0c;但它只是眾多進步中的一個&#xff0c;可以推…

總說綠幕直播摳像摳不干凈?很有可能是你不知道這個神器!

在綠幕直播的時候&#xff0c;你是不是座位、綠幕、燈光都擺對了&#xff0c;但主播輪廓仍然有綠邊和虛化的情況發生&#xff1f;這種很大可能就是你使用的直播摳像軟件有問題。今天小編把市面上的常見直播軟件來和vLive虛擬直播的摳像做一個對比&#xff0c;讓你直觀感受下他們…

機器學習筆記 - 基于PyTorch + 類似ResNet的單目標檢測

一、獲取并了解數據 我們將處理年齡相關性黃斑變性 (AMD) 患者的眼部圖像。 數據集下載地址,從下面的地址中,找到iChallenge-AMD,然后下載。 Baidu Research Open-Access Dataset - DownloadDownload Baidu Research Open-Access Datasethttps://ai.baidu.com/bro…

Docker入門使用

用一個hello world的小例子來入門docker 在 Docker 容器中部署 Python Flask 的簡單 Hello World 項目&#xff0c;需要遵循以下流程&#xff1a; 編寫應用程序 首先&#xff0c;在本地計算機上編寫一個簡單的 PythonFlask 應用程序&#xff0c;例如&#xff1a; # hello.…

基于ACF,AMDF算法的語音編碼matlab仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 1.算法運行效果圖預覽 2.算法運行軟件版本 matlab2022a 3.部分核心程序 .......................................................................... plotFlag …

函數遞歸專題(案例超詳解一篇講通透)

函數遞歸 前言1.遞歸案例:案例一&#xff1a;取球問題案例二&#xff1a;求斐波那契額數列案例三&#xff1a;函數實現n的k次方案例四&#xff1a;輸入一個非負整數&#xff0c;返回組成它的數字之和案例五&#xff1a;元素逆置案例六&#xff1a;實現strlen案例七&#xff1a;…

服務器遭受攻擊之后的常見思路

哈嘍大家好&#xff0c;我是咸魚 不知道大家有沒有看過這么一部電影&#xff1a; 這部電影講述了男主是一個電腦極客&#xff0c;在計算機方面有著不可思議的天賦&#xff0c;男主所在的黑客組織憑借著超高的黑客技術去入侵各種國家機構的系統&#xff0c;并引起了德國秘密警察…

Mac如何打開隱藏文件中Redis的配置文件redis.conf

Redis下載(通過??博客下載的Redis默認路徑為&#xff1a;/usr/local/etc) Redis下載 1.打開終端進入/usr文件夾 cd /usr 2.打開/local/文件夾 open local 3.找到redis.conf并打開,即可修改配置信息

訊飛星火認知大模型全新升級,全新版本、多模交互—測評結果超預期

寫在前面 版本新功能 1 體驗介紹 登錄注冊 申請體驗 2 具體使用 2.1 多模態能力 2.1.1 多模理解 2.1.2 視覺問答 2.1.3 多模生成 2.2 代碼能力 2.2.1 代碼生成 2.2.2 代碼解釋 2.2.3 代碼糾錯 2.2.4 單元測試 2.3 插件功能 2.3.1 PPT生成 2.3.2 簡歷生成 2.3.4 文檔問答 3 其他…

算法練習(6):牛客在線編程06 遞歸/回溯

package jz.bm;import java.io.PushbackInputStream; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays;public class bm6 {/*** BM55 沒有重復項數字的全排列*/ArrayList<ArrayList<Integer>> res new ArrayList<>()…