【STM32】输入捕获实验代码详解
生活随笔
收集整理的這篇文章主要介紹了
【STM32】输入捕获实验代码详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- main.c
- timer.c
- timer.h
main.c
#include "led.h" #include "delay.h" #include "sys.h" #include "timer.h" #include "usart.h"extern u8 TIM2CH1_CAPTURE_STA; //輸入捕獲狀態 extern u16 TIM2CH1_CAPTURE_VAL; //輸入捕獲值int main(void){ u32 temp=0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 設置中斷優先級分組2delay_init(); //延時函數初始化 uart_init(9600); //9600 LED_Init(); //初始化與LED連接的硬件接口TIM1_PWM_Init(899,0); //不分頻。PWM頻率=72000/(899+1)=80KhzTIM2_Cap_Init(0XFFFF,72-1); //以1Mhz的頻率計數 while(1){delay_ms(10);TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);if(TIM_GetCapture1(TIM1)==300)TIM_SetCompare1(TIM1,0); if(TIM2CH1_CAPTURE_STA&0X80)//成功捕獲到了一次高電平{temp=TIM2CH1_CAPTURE_STA&0X3F;temp*=65536; //溢出時間總和temp+=TIM2CH1_CAPTURE_VAL; //得到總的高電平時間printf("HIGH:%d us\r\n",temp); //打印總的高點平時間TIM2CH1_CAPTURE_STA=0; //開啟下一次捕獲}} }timer.c
#include "timer.h" #include "led.h" #include "usart.h" #include "sys.h"//PWM輸出初始化 //arr:自動重裝值 //psc:時鐘預分頻數 void TIM1_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外設時鐘使能//設置該引腳為復用輸出功能,輸出TIM1 CH2的PWM脈沖波形GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值 80KTIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值 不分頻TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈沖值TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根據TIM_OCInitStruct中指定的參數初始化外設TIMxTIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主輸出使能 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1預裝載使能 TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的預裝載寄存器TIM_Cmd(TIM1, ENABLE); //使能TIM1}//定時器2通道1輸入捕獲配置TIM_ICInitTypeDef TIM2_ICInitStructure;void TIM2_Cap_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 清除之前設置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 輸入 GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉//初始化定時器2 TIM2 TIM_TimeBaseStructure.TIM_Period = arr; //設定計數器自動重裝值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //預分頻器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位//初始化TIM2輸入捕獲參數TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 選擇輸入端 IC1映射到TI1上TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻 TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波TIM_ICInit(TIM2, &TIM2_ICInitStructure);//中斷分組初始化NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占優先級2級NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //從優先級0級NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器 TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允許更新中斷 ,允許CC1IE捕獲中斷 TIM_Cmd(TIM2,ENABLE ); //使能定時器2}u8 TIM2CH1_CAPTURE_STA=0; //輸入捕獲狀態 u16 TIM2CH1_CAPTURE_VAL; //輸入捕獲值//定時器5中斷服務程序 void TIM2_IRQHandler(void) { if((TIM2CH1_CAPTURE_STA&0X80)==0)//還未成功捕獲 { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){ if(TIM2CH1_CAPTURE_STA&0X40)//已經捕獲到高電平了{if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高電平太長了{TIM2CH1_CAPTURE_STA|=0X80;//標記成功捕獲了一次TIM2CH1_CAPTURE_VAL=0XFFFF;}else TIM2CH1_CAPTURE_STA++;} }if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕獲1發生捕獲事件{ if(TIM2CH1_CAPTURE_STA&0X40) //捕獲到一個下降沿 { TIM2CH1_CAPTURE_STA|=0X80; //標記成功捕獲到一次上升沿TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 設置為上升沿捕獲}else //還未開始,第一次捕獲上升沿{TIM2CH1_CAPTURE_STA=0; //清空TIM2CH1_CAPTURE_VAL=0;TIM_SetCounter(TIM2,0);TIM2CH1_CAPTURE_STA|=0X40; //標記捕獲到了上升沿TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 設置為下降沿捕獲} } }TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中斷標志位}timer.h
#ifndef __TIMER_H #define __TIMER_H #include "sys.h"void TIM1_PWM_Init(u16 arr,u16 psc); void TIM2_Cap_Init(u16 arr,u16 psc);#endif總結
以上是生活随笔為你收集整理的【STM32】输入捕获实验代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【STM32】PWM 输出实验代码详解
- 下一篇: 【STM32】OLED 显示实验代码详解