最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

STM32單片機-輸入捕獲、FFT測頻

2023-08-22 19:35 作者:liht1634  | 我要投稿

本內(nèi)容介紹基于STM32F103VET6的一個實際工程中添加采集A相電壓信號或B相電流信號頻率的功能,分別通過輸入捕獲與FFT實現(xiàn),均測試可用。持續(xù)更新,原創(chuàng)不易!

目錄:

一、硬件連接

1、電壓信號處理電路仿真

2、單片機連接

二、程序部分

1、通過STM32輸入捕獲

1)定時器配置 ? 2)定時溢出和輸入捕獲中斷處理

2、通過FFT實現(xiàn)

1)概述 ? 2)數(shù)據(jù)采集 ? 3)功能介紹

3、屏顯驅動介紹

附錄1:測頻法計算頻率?

---------------------------------------------------------------------------------------------?

一、硬件連接?

1、電壓信號處理電路仿真

-----------------------------------------------------------?

2、單片機連接?

主控MCU:STM32F103ZET6(STM32的介紹),LM293輸出連接在PB0上檢測電壓信號的頻率,如圖1.1.1與圖1.2.1所示。


編輯切換為居中


編輯切換為居中

如圖1.2.2所示,注意其中的TIM3_CH2N是PWM捕獲比較輸出,TIM3_CH3才是輸入捕獲。

---------------------------------------------------------------------------------------------?

二、程序部分 ?

這里通過STM32輸入捕獲或FFT轉換兩種方式實現(xiàn)頻率的測量,在實際工程中都已實現(xiàn)。STM32輸入捕獲信號幅度小于2V時,單片機檢測不到跳變沿,需硬件對信號適當處理(如圖1.1.1)。PB0/ADC8也可用ADC讀信號電壓值,ADC值為0時進行記錄,再次為0就相當于經(jīng)過了半個周期。計算兩次ADC為0的時間差,就可以計算出信號的頻率,這種方法不會受限于信號幅度的限制。?

--------------------------------?

1、通過STM32輸入捕獲?

下面的程序采集PB0口(圖1.2.1)的電壓信號,因頻率較低,且要求繼電器出口時間小于35mS,采用測周法計算頻率。給出主要部分定時器配置與定時器中斷程序。因上升沿示波器測試并不陡峭(圖1.1.1仿真圖也可看出),故取一周波兩次下降沿。 注意:后期的處理程序必須捕獲到兩個下降沿的前提下,才能作相應的處理。采集程序未完成,此時處理會出錯。

1)定時器配置


void adc_TIM_Init(void) { ? TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定時器 ? GPIO_InitTypeDef GPIO_InitStructure; //端口 ? TIM_ICInitTypeDef TIM_ICInitStructure; //輸入捕獲 ? ? //初始化GPIO口 ?GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空輸入模式 ? GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; ? GPIO_Init(GPIOB,&GPIO_InitStructure); ? GPIO_SetBits(GPIOB,GPIO_Pin_0); ? ? //使能時鐘 ? RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3 ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); ? ? //初始化TIM3定時 ? TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); ? TIM_TimeBaseStructure.TIM_Prescaler = 17; //1MHz計數(shù)脈沖 1uS ? TIM_TimeBaseStructure.TIM_Period = 65535; ? TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; ? TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數(shù) ? TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); ? TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); ? ? //初始化TIM3 Channel3輸入捕獲IC(Input Capture) ? TIM_ICInitStructure.TIM_Channel=TIM_Channel_3; ? TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling; //下降沿捕獲 ? TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI; //管腳與寄存器一一對應 ? TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; //有下降沿就捕獲,不分頻 ? TIM_ICInitStructure.TIM_ICFilter=0x00; //不打開輸入捕獲濾波器 ? TIM_ICInit(TIM3,&TIM_ICInitStructure); ? TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允許定時中斷 ? TIM_ITConfig(TIM3,TIM_IT_CC3,ENABLE); //允許CC3捕獲中斷 ? TIM_Cmd(TIM3,ENABLE); ………… }

--------------------------------?

2)定時溢出和輸入捕獲中斷處理


void TIM3_IRQHandler(void) //TIM3 { ? static u8 CapStatus=0; //捕獲狀態(tài),CapStatus=0未捕獲到第1個下降沿,CapStatus=1捕獲到第1個下降沿 ? static u8 TIM3_CH3_Capture=0; //總的計數(shù)次數(shù) ? u32 FrequencyTemp=0; ? ? if(TIM_GetITStatus(TIM3,TIM_IT_Update)) //TIM3定時溢出更新中斷 ? { ? ? ?TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中斷標志位 ? ? ?if(CapStatus) ? ? ? ? TIM3_CH3_Capture++; ? } ? ? if(TIM_GetITStatus(TIM3,TIM_IT_CC3)) //RB0輸入捕獲中斷 ? { ? ? ?TIM_ClearITPendingBit(TIM3,TIM_IT_CC3); //清除中斷標志位 ? ? ?if(!CapStatus) ? ? ?{ ? ? ? ? CapStatus=1; ? ? ? ? TIM_SetCounter(TIM3,0); //計數(shù)器清零 ? ? ?} ? ? ?else if(CapStatus) //已經(jīng)捕獲到第1個下降沿 ? ? ?{ ? ? ? ? CapStatus=0; ? ? ? ? FrequencyTemp=TIM_GetCapture3(TIM3)+TIM3_CH3_Capture*65536;//計算兩個下降沿總計數(shù) ? ? ? ? TIM3_CH3_Capture=0; //溢出次數(shù)清零 ? ? ? ? TIM_SetCounter(TIM3,0); //計數(shù)器清零 ? ? ? ? FrequencyValue=400000000/FrequencyTemp;//計算頻率,比如5000,單位0.01Hz ? ? ?} ? } }

-----------------------------------------------------------?

2、通過FFT實現(xiàn)?

1)概述 下面是采集PC1口(圖1.2.1)的小通道電流信號,計算頻率,其固件具ST官方DSP庫實現(xiàn)FFT,測試固件移步:FFT(具ST官方DSP庫實現(xiàn))。

-------------------------------- ?

2)數(shù)據(jù)采集 使用STM32F103自帶的12位ADC進行數(shù)據(jù)采集,定時器觸發(fā)ADC采集,DMA搬運,定時器時間自行設置,采樣頻率已知。此部分相關內(nèi)容移步:ADC轉換匯總(采樣原理、取平均、精度等)。

--------------------------------?

3)功能介紹 通過FFT可以準確測量電壓值、電流值、有功功率、無功功率、頻率、諧波分量(比如顯示2~32次諧波)、相角(電壓與電流夾角)。 互感器二次值精確到小數(shù)點后2位無壓力,電流范圍大,硬件增加大小通道、程序分別采集;涌流二次諧波含量最多,故可實現(xiàn)二次諧波制動,相關介紹移步:電力-涌流抑制與諧波。?

-----------------?

已實現(xiàn)FFT的控制板:

-----------------?

GSM短信功能介紹移步:SIM7600CE模塊(GSM/GPRS)調(diào)試。

-----------------?

GPRS數(shù)據(jù)功能介紹移步:STM32-GPRS模塊連接系統(tǒng)主站,可以采用映翰通工業(yè)數(shù)據(jù)終端做透明傳輸。?

-----------------?

以太網(wǎng)功能板,本方案基于W5500,詳細的介紹移步:網(wǎng)絡知識匯總(基于W5500以太網(wǎng))。

-----------------------------------------------------------?

3、屏顯驅動介紹?

移步:12864液晶顯示原理(C代碼)。

---------------------------------------------------------------------------------------------?

附錄1:測頻法計算頻率?

網(wǎng)上找的資料,不保證正確性,沒有實際測試過,僅供參考。 通過在一定時間內(nèi)檢測跳邊沿的個數(shù)可計算出頻率 頻率=上升沿或下降沿個數(shù)/統(tǒng)計時間。?

?-----------------------------------------------------------?

方法1:利用外部中斷統(tǒng)計跳邊沿個數(shù),配置一個定時器每隔一定時間對頻率進行計算。部分代碼如下。

void exti_init() ?//外部中斷初始化函數(shù) { ? ?GPIO_InitTypeDef GPIO_InitStructure; ? ?EXTI_InitTypeDef EXTI_InitStructure; ? ?NVIC_InitTypeDef NVIC_InitStructure; ? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); ? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); ? ? ? ? ?GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2; ? ?GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; ? ?GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; ? ?GPIO_Init(GPIOC,&GPIO_InitStructure); ? ?GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2); //選擇GPIO引腳用作外部中段線路 //此處一定要記住給端口管腳加上中斷外部線路 ? ?EXTI_InitStructure.EXTI_Line=EXTI_Line2; ? ?EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; ? ?EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; ?//下降沿進中斷 ? ?EXTI_InitStructure.EXTI_LineCmd = ENABLE; ? ?EXTI_Init(&EXTI_InitStructure); ? ?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); ? ? ?NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //打開EXTI2的全局中斷 ? ?NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //設置優(yōu)先級 ? ?NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; ? ? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ? //使能 ? ?NVIC_Init(&NVIC_InitStructure); }

外部中斷函數(shù):

void EXTI2_IRQHandler() ? ? { ? ?if(EXTI_GetITStatus(EXTI_Line2)==SET) ? ?{ ? ? ? ?EXTI_ClearITPendingBit(EXTI_Line0);//清中斷 ? ? ? ?if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==Bit_RESET) ? ?//確定沿 ? ? ? ?{ ? ? ? ? ? ?cnt++; ? ? ? ?} ? ?} }

定時器中斷函數(shù):


void TIM3_IRQHandler() ? { ? ?frequent=cnt; //定時器設置時間為1s時 ? ?cnt=0; ?//清零計數(shù)cnt ? ?TIM_ClearITPendingBit(TIM3,TIM_IT_Update); ? ?//清標志位 }

-----------------------------------------------------------?

方法2:采用定時器外部計數(shù)的方法,另外一個定時器負責每隔一段時間計算頻率,部分代碼如下。

void time_init() { ? ?GPIO_InitTypeDef GPIO_InitStructure; ? ?TIM_TimeBaseInitTypeDef TIM2_TimeBaseInitStructure; ? ? ?TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStructure; ? ?NVIC_InitTypeDef NVIC_InitStructure; ? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); ? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); ? ?GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; ? ?GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; ? ?GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; ? ?GPIO_Init(GPIOA,&GPIO_InitStructure); ? ?TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除TIM2中斷標志位 ? ?TIM2_TimeBaseInitStructure.TIM_Period = 0xFFFF;//設置自動重裝載值 ? ?TIM2_TimeBaseInitStructure.TIM_Prescaler = 0;//設置分頻 ? ?TIM2_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; ? ?TIM2_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數(shù) ? ?TIM_TimeBaseInit(TIM2,&TIM2_TimeBaseInitStructure); ? ? ?TIM_ETRClockMode1Config(TIM2, TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted, 0x00); ?//設置為采用外部時鐘計數(shù),可設定濾波參數(shù)消除信號干擾 ? ?TIM_Cmd(TIM2,ENABLE); ? ?TIM_ClearITPendingBit(TIM3,TIM_IT_Update); ? ?TIM3_TimeBaseInitStructure.TIM_Period = 999; ? ?TIM3_TimeBaseInitStructure.TIM_Prescaler = 3599; ? ?TIM3_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; ? ?TIM3_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; ? ?TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStructure); ? ?TIM_Cmd(TIM3,ENABLE); ? ?TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE ); ? ?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); ? ?NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; ? ?NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; ? ?NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; ? ? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ? ?NVIC_Init(&NVIC_InitStructure); }

定時器中斷函數(shù):

void TIM3_IRQHandler() ? { ? ?static u8 i; ? ?static u32 frequent_sum; ? ?TIM_ClearITPendingBit(TIM3,TIM_IT_Update); ? //清中斷 ? ?if(i<19) ? ?{ ? ? ? ?cnt += TIM_GetCounter(TIM2); ?//,獲取計數(shù)器的值,累加減少誤差 ? ? ? ?TIM_SetCounter(TIM2,0); ? ?//計數(shù)器清零 ? ? ? ?i++; ? ?} ? ?else ? ?{ ? ? ? ?cnt += TIM_GetCounter(TIM2); ? ? ? ?TIM_SetCounter(TIM2,0); ? ? ? ?cnt += cnt*0.000025; //根據(jù)實際情況修改系數(shù)線性補償 ? ? ? ?frequent = cnt; ? ? ? ?i = 0; ? ? ? ?cnt = 0; ? ?} }

---------------------------------------------------------------------------------------------

覺得不錯,動動您發(fā)財?shù)男∈值命c個贊哦!


STM32單片機-輸入捕獲、FFT測頻的評論 (共 條)

分享到微博請遵守國家法律
内乡县| 桐梓县| 屏南县| 陈巴尔虎旗| 冀州市| 剑河县| 祁门县| 根河市| 长子县| 泸州市| 阳江市| 邢台县| 池州市| 阿图什市| 长春市| 双城市| 舟山市| 介休市| 江阴市| 广灵县| 吉木萨尔县| 永川市| 亚东县| 灌阳县| 内江市| 农安县| 贵德县| 泰来县| 青海省| 长垣县| 沈丘县| 随州市| 柳河县| 西乌珠穆沁旗| 诸城市| 砚山县| 库伦旗| 遂宁市| 历史| 磐石市| 汉寿县|