新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 定時器中斷—頻率計程序

        定時器中斷—頻率計程序

        作者: 時間:2012-11-10 來源:網絡 收藏

        /*注:的例子,簡單的,初學者留意各引腳電
        壓極性和電壓值,不可超出5V,我們只是做學習實驗,不要
        超出51hei單片機學習板的承受范圍,否則要求對電子非常熟悉,
        不然會燒壞芯片,版權:www.51hei.com,注意:P1.3與P1.7要相連接
        如果是測量外部頻率要共地.
        */
        #includereg52.h> //頭文件
        #includeintrins.h>
        #define uchar unsigned char//宏定義
        #define uint unsigned int
        sbit Fin=P1^3; //測量頻率管腳
        sbit Fout=P1^7; //發生頻率管腳
        uchar code table[]={0x3f,0x06,0x5b,//數碼管顯示的數值
        0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,};
        void display(uchar *lp,uchar lc); //顯示子函數
        void delay(); //
        void mee_F(); //測頻率子函數
        void mee_T(); //測周期子函數
        void Fry_mee(); //測頻測周選擇的子函數
        uchar l_tmpdata[8]; //程序顯示的緩沖區
        bit int_flag; //中斷事件相應的標志
        uint fry; //保存的頻率值
        void init() ;
        void main() //主函數
        {
        init(); // 調用初始化函數

        }
        void init() //初始化函數
        {
        uint tmp; //數據轉換緩沖區
        uint i=2000;//顯示延時,提高亮度
        EA=1; //打開總中斷
        TMOD=0x11;//工作方式3
        TH0=256-(50000/256); //裝入初值
        TL0=256-(50000%256);
        TH1=256-500/256;
        TL0=256-500%256;
        ET0=1; //定時器0開
        ET1=1; //定時器1開
        TR1=1; //啟動定時器1
        while(1)
        {
        Fry_mee();//開始測量
        l_tmpdata[0]=tmp/10000; //測量完后將整數分離出來
        tmp=tmp%10000; //進行顯示
        l_tmpdata[1]=tmp/1000;
        tmp=tmp%1000;
        l_tmpdata[2]=tmp/100;
        tmp=tmp%100;
        l_tmpdata[3]=tmp/10;
        l_tmpdata[4]=tmp%10;
        while(i--) //顯示延時,提高亮度
        {
        display(l_tmpdata,5); //用數字顯示頻率
        }
        i=2000; //從新裝入初值
        }
        }
        void time0() interrupt 1 //定時器0的中斷函數
        {
        int_flag=1; //中斷標志
        }
        void time1() interrupt 3 //定時器1的中斷函數,用來產生頻率
        {
        TH1=(65536-1000)/256; //從新賦值
        TL1=(65536-1000)%256;
        Fout=!Fout; //?反,產生頻率,即頻率發生器
        }
        void Fry_mee()
        {
        if(fry2000) //?于2k的,側周
        mee_T();
        else if(fry>=2000) //大于2k的,測頻
        mee_F();
        }
        //測頻原理:用一個標準的50ms計數中斷,對被測信號計數
        void mee_F() //測頻子函數
        {
        bit lhj_old=1,lhj_new=1; //定義起始狀態
        uint f_count=0;//計數變量
        int_flag=0;
        TH0=(65536-50000)/256;//定時器,初值50ms
        TL0=(65536-50000)%256;
        TR0=1; //啟動定時器0
        while(1) //死循環,測頻
        {
        lhj_new=Fin; //?現在頻率引腳的狀態
        if(lhj_old!=lhj_new) //與前一刻的值比較
        f_count++;
        lhj_old=lhj_new; //將新值賦給舊值
        if(int_flag) //如果到了定時時間
        {
        TR0=0; //關閉定時器0
        fry=f_count*10; //計算頻率,f_count=f_count*20/2
        //一個周期有2個跳變,20個周期為1s
        return; //返回
        }
        }
        }
        //測周原理:以被測信號的一個周期為中斷源,對單片機及其
        //周期進行計數讀?定時器的值為計數值
        void mee_T() //測周子函數
        {
        bit lhj_old=0,lhj_new=0; //定義初始狀態
        uchar temp_flag=0;
        uint t_count; //計數變量
        TH0=0; //賦初始值
        TL0=0;
        while(1) //死循環,測周
        {
        lhj_new=Fin; //取現在的頻率發聲引腳的狀態
        if(lhj_old!lhj_new) //當下降沿來臨時,啟動定時器
        {
        temp_flag++;
        TR0=1; //啟動定時器并開始計數
        }
        if(temp_flag==2)
        {
        TR0=0; //停止計數
        t_count=TH0*256+TL0;//取得當前的計數值
        fry=1000000/t_count;//計算頻率,這個1000000是
        //晶振12M經12分頻的計數脈沖
        return; //返回
        }
        lhj_old=lhj_new;
        }
        }
        void display(uchar *lp,uchar lc) //顯示子函數
        {
        uchar i;
        P2=0;
        P1=0xf8;
        for(i=0;ilc;i++)
        {
        P2=table[lp[i]];
        delay();
        if(i==7)
        break;
        P2=0;
        P1++;
        }
        }
        void delay() //
        {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        }



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 锦州市| 富宁县| 伊宁县| 文山县| 嘉兴市| 朝阳县| 潮安县| 祁连县| 保康县| 沙湾县| 天祝| 镇赉县| 滨州市| 息烽县| 桃园市| 尚志市| 博兴县| 方城县| 奉新县| 宜黄县| 呼伦贝尔市| 团风县| 鲁山县| 绥化市| 军事| 齐齐哈尔市| 朝阳区| 米脂县| 景德镇市| 武平县| 孟村| 固始县| 隆林| 高安市| 日土县| 和顺县| 安化县| 长顺县| 泰安市| 江达县| 涿州市|