欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7801|回復: 4
打印 上一主題 下一主題
收起左側

基于stm32的單片機的數字頻率計設計

  [復制鏈接]
跳轉到指定樓層
樓主
  1.簡介:數字頻率計主要由四個部分組成:時基電路,整形電路,控制電路和顯示電路組成。在一個測量周期過程中,由時基電路產生一標準時間信號控制閥門,調節時基電路中的電阻可產生需要的標準時間信號。信號輸入整形電路中,經過整形,輸出一方波,通過閥門后,計時器對其計數。當計數完畢,時基電路輸出一個上升沿,使鎖存器打開,計數器計數結果輸入譯碼器,從而讓顯示器顯示,達到測量頻率的目的。文件包括設計電路圖,設計源代碼與設計報
2.目標:本設計主要完成以下目標:
  1.測量信號輸入幅度1V~5V方波,頻率為1kHz~10kHz,測量精度1%,信號輸入幅度1V~5V三角波,頻率為1kHz~10kHz,測量精度1%,信號輸入幅度2V~5V正弦波,頻率為1kHz~10kHz,測量精度1%;
2.當輸入信號幅度大于15V時,具有報警功能,測量結果為數字顯示;
3.測量具有串口通信功能;
4.信號輸入幅度為1V~10V脈沖,頻率為20Hz~1kHz時,測量并計算占空比。
3.硬件設計:
3.硬件設計原理
硬件電路圖:

1.測頻部分:先對輸入信號進行波形轉換,通過一個過零比較器將三角波、正弦波轉化為方波,之后將將方波輸入單片機 口進行波形測試。
2.限幅報警部分:輸入信號經過D1變成半波信號,之后經過C3,C4,C5,C6,C7進行整流成為幅值直流信號,之后將信號輸入電位器進行分壓,保證15v電壓經過電位器后剩余3.3v電壓。最后輸出到端口上與3.3v電壓進行比較,將比較結果輸入單片機 口。
3.單片機供電部分:通過供電模塊輸出3.3v電壓供給stm32單片機。
4.軟件設計原理:
硬件部分會將所有波形統一成方波輸入。使用TIM3TIM4計時器。TIM3進行波形捕捉。TIM3捕捉波形的上升沿或者下降沿。開始計數,知道捕捉到相對應的上升沿或者下降沿。根據所計數的多少即可計算出波形的占空比。每次捕捉到上升沿且之前為低電平,頻率計數加一。TIM4計數器用來計數一秒,當TIM4計數滿一秒時,發生TIM4中斷,根據TIM3的頻率計數,即可計算出輸入波形的頻率。
5.源代碼:(帶有詳細注釋)Main函數:
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "oled.h"
#include "timer.h"
#include "led.h"
#include "key.h"

extern uint16_t  counter;                         //記錄捕獲狀態
extern uint8_t   flag;                                  //記錄計時是否滿一秒
extern uint32_t  rising_time;                  //高電平持續時間
extern uint32_t  falling_time;                 //低電平持續時間

int main(void)
{        
         delay_init();                                                                                 //延時函數初始化                    
         uart_init(115200);                                                                    //串口一初始化,設置波特率為115200
         LED_Init();                                                                                            //報警LED初始化
         KEY_Init();                                                                                            //比較器輸入初始化
         OLED_Init();                                                                                //OLED顯示屏初始化
         OLED_Clear();                                                                            //清空顯示屏
         OLED_ShowString(30,0, "Cymometer");                           //在屏幕上顯示Cymometer
         OLED_ShowString(20,4, "Fre:");
         OLED_ShowString(93,4, "Hz");
         OLED_ShowString(20,6, "Dut:");
         OLED_ShowString(87,6, "%");
         TIM3_Cap_Init(0xffff,72-1);                                         //TIM3初始化 時鐘設為1M Hz用于輸入捕獲
         TIM4_Int_Init(10000-1,72-1);                                               //TIM4初始化 時鐘設為1M Hz用于計時1s

         while(1)
         {                 
                   if(flag== 1)                //檢測計時是否滿1s                                          
                   {
                            flag= 0;
                            if((rising_time!= 0) && (falling_time != 0))     //有信號輸入
                            {
                                     printf("Fre:%dHz,     Dut:%1.2f\r\n", counter,(float)rising_time/(rising_time + falling_time));
                                     OLED_ShowNum(53,4, counter, 5, 16);
                                     OLED_ShowNum(71,6, (float)rising_time/(rising_time + falling_time)*100, 2, 16);
                            }
                            else
                            {
                                     printf("Fre:%d           Dut:0\r\n", counter);       //無信號輸入
                                     OLED_ShowNum(53,4, counter, 5, 16);
                                     OLED_ShowNum(71,6, 0, 2, 16);
                            }
                            counter= 0;
                            rising_time= 0;
                            falling_time= 0;
                   }
                   if(KEY== 1)                //檢測比較器輸入是否為高電平
                            LED= 0;             //報警燈亮
                   elseLED = 1;              //報警燈不亮
         }
}
計時器函數:
#include "sys.h"
#include "timer.h"
#include "usart.h"

void TIM3_Cap_Init(uint16_t arr, uint16_tpsc)                                  //TIM3用于輸入捕獲
{
         GPIO_InitTypeDefGPIO_InitStructure;
         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
         TIM_ICInitTypeDef  TIM3_ICInitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;

         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);     //使能TIM3時鐘
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);          //使能GPIOA時鐘

         GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;                      //選擇6號引腳
         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD;                      //輸入下拉
         GPIO_Init(GPIOA,&GPIO_InitStructure);                                             //初始化PA6
         GPIO_ResetBits(GPIOA,GPIO_Pin_0);                                                    //PA6下拉

         //初始化定時器3 TIM3  
         TIM_TimeBaseStructure.TIM_Period= arr;                               //設定計數器自動重裝值
         TIM_TimeBaseStructure.TIM_Prescaler=psc;                                    //預分頻器
         TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; //設置時鐘分割:TDTS = Tck_tim
         TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;  //TIM向上計數模式
         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

         //初始化TIM3輸入捕獲參數
         TIM3_ICInitStructure.TIM_Channel= TIM_Channel_1;                   //CC1S=01選擇輸入端 IC1映射到TI1
       TIM3_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;      //上升沿捕獲
       TIM3_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI; //映射到TI1
       TIM3_ICInitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;   //配置輸入分頻,不分頻
       TIM3_ICInitStructure.TIM_ICFilter = 0x00;                                  //IC1F=0000 配置輸入濾波器 不濾波
       TIM_ICInit(TIM3,&TIM3_ICInitStructure);

         //中斷分組初始化
         NVIC_InitStructure.NVIC_IRQChannel= TIM3_IRQn;            //TIM3中斷
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;  //先占優先級0
         NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;          //從優先級0
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;           //IRQ通道被使能
         NVIC_Init(&NVIC_InitStructure);

         TIM_ITConfig(TIM3,TIM_IT_CC1,ENABLE);

     TIM_Cmd(TIM3,ENABLE );     //使能定時器3
}

uint8_t  TIM3CH1_CAPTURE_STA;                                           //輸入捕獲狀態
uint16_t counter = 0;                                                           //記錄捕獲上升沿次數
uint8_t  sec_cnt = 0;                                                           //毫秒計時
uint8_t       flag = 0;                                                                          //計時1s完成標志
uint32_t rising_time;                                                            //高電平時間
uint32_t falling_time;                                                          //低電平時間

//定時器3中斷服務程序      
void TIM3_IRQHandler(void)
{
         if(TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)                            //發生捕獲事件
         {        
                   if(TIM3CH1_CAPTURE_STA& 0x80)                                                                 //捕獲下降沿(已經捕獲到上升沿)
                   {
                            rising_time= TIM_GetCapture1(TIM3);                             //讀取高電平時間(us)

                            TIM3CH1_CAPTURE_STA= 0;                                                         //清空
                            TIM_SetCounter(TIM3,0);
                            TIM3CH1_CAPTURE_STA|= 0x40;                                                //標記捕獲到了下降沿
                            TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising);   //設置為上升沿觸發
                   }
                   else                                                                                                                  //捕獲上升沿
                   {
                            falling_time= TIM_GetCapture1(TIM3);                                     //低電平時間

                            TIM3CH1_CAPTURE_STA= 0;                                                         //清零
                            TIM_SetCounter(TIM3,0);
                            TIM3CH1_CAPTURE_STA|=0X80;                                                            //標記捕獲到了上升沿
                            TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling);  //開始捕獲下降沿
                            counter++;                                                                                                     //頻率計數加一
                   }
         }

         TIM_ClearITPendingBit(TIM3,TIM_IT_CC1); //清除中斷標志位
}



void TIM4_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
         NVIC_InitTypeDefNVIC_InitStructure;

         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //時鐘使能

         TIM_TimeBaseStructure.TIM_Period= arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
         TIM_TimeBaseStructure.TIM_Prescaler=psc; //設置用來作為TIMx時鐘頻率除數的預分頻值
         TIM_TimeBaseStructure.TIM_ClockDivision= 0; //設置時鐘分割:TDTS = Tck_tim
         TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;  //TIM向上計數模式
         TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

         TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);

         NVIC_InitStructure.NVIC_IRQChannel= TIM4_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1;  //先占優先級1
         NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;  //從優先級0
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; //IRQ通道被使能
         NVIC_Init(&NVIC_InitStructure);  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器

         TIM_Cmd(TIM4,ENABLE);  

}

void TIM4_IRQHandler(void)                                                               //TIM3中斷,10000us中斷一次
{
         if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  //檢查指定的TIM中斷發生與否:TIM 中斷源
         {
                   sec_cnt++;                                                                                            
                   if(sec_cnt== 100)                                                                     //計時滿1
                   {
                            sec_cnt= 0;
                            flag= 1;
                   }
                   TIM_ClearITPendingBit(TIM4,TIM_IT_Update);           //清除TIMx的中斷待處理位:TIM 中斷源
         }
}
       LED初始化:
#include "led.h"
#include "sys.h"

void LED_Init(void)
{
         GPIO_InitTypeDef  GPIO_InitStructure;

         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);    //使能GPIOC端口時鐘

         GPIO_InitStructure.GPIO_Pin= GPIO_Pin_13;                                    //LED-->PC13 端口配置
         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;                //推挽輸出
         GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;                 //IO口速度為50MHz
         GPIO_Init(GPIOC,&GPIO_InitStructure);                                             //根據設定參數初始化GPIOB.5
         GPIO_SetBits(GPIOC,GPIO_Pin_13);
}
幅值報警初始化:
#include "key.h"
#include "sys.h"

void KEY_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA時鐘

         GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;
         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD; //設置成下拉輸入
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA5

}


全部資料51hei下載地址:
簡易頻率計.rar (663.26 KB, 下載次數: 188)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:91165 發表于 2020-4-26 19:39 | 只看該作者
好東東,頂樓主,謝謝分享
回復

使用道具 舉報

板凳
ID:473907 發表于 2020-4-27 16:24 | 只看該作者
感覺稍微復雜了些~  新手理解困難
回復

使用道具 舉報

地板
ID:942534 發表于 2021-6-22 15:49 | 只看該作者
感謝分享,先拿著學一下看看
回復

使用道具 舉報

5#
無效樓層,該帖已經被刪除
6#
無效樓層,該帖已經被刪除
7#
無效樓層,該帖已經被刪除
8#
ID:1108903 發表于 2024-1-11 10:19 | 只看該作者
電路圖就那么一點啊
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表