久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機頻率計數器(程序)

[復制鏈接]
跳轉到指定樓層
樓主
ID:71259 發表于 2014-12-30 15:46 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 daming 于 2014-12-30 15:47 編輯

該程序能實現測量10至3MHZ的TTL信號頻率,液晶顯示4為有效數字,同時能夠測量脈沖占空比,精度在0.5%左右...
需要硬件支持:C8051F360單片機,鍵盤,液晶顯示器
main()
{
    int xdata flag1=0;
       float  sum1=0,sum2=0;
       float xdata sum3[10];
       int i;
       Init_device();
       LCD_REST();
       LCD_INIT();
       f=0;
       f1=0;
  while(1)
{
    if(flag)
   {
        if(f>=10&&f<=99)   額,不得不說,取11個數求平均值確實不好,讀數不能穩定的說....
{
             sum2=(jishu[0]+jishu[1]+jishu[2]+jishu[3]+jishu[4]+jishu[5]+jishu[6]+jishu[7]+jishu[8]+jishu[9]+jishu[10])/11;
             get_flow(sum2);
             LCD_HZ(0x80,TAB_WORD);
             LCD_HZ(0x90,F_DISPLOW);
          flag=0;
            }
          else if(f>=100&&f<= 999)
       {
               get_flowhigh();
               LCD_HZ(0x80,TAB_WORD);
               LCD_HZ(0x90,F_DISPLOWHIGH);
               flag=0;
       }
          else if (f>=1000&&f<=9999)
          {
             get_high();
                LCD_HZ(0x80,TAB_WORD);
                LCD_HZ(0x90,F_DISPHIGH);
                flag=0;
          }
          else if(f>=10000&&f<=99999)
          {
             get_highone();
                LCD_HZ(0x80,TAB_WORD);
                LCD_HZ(0x90,F_DISPHIGHONE);
                flag=0;
          }
          else if(f>=100000&&f<=999999)
       {
           get_highone();
           LCD_HZ(0x80,TAB_WORD);
           LCD_HZ(0x90,F_DISPHIGHONE);         內部數據存儲器只有128位,為節約空間與上個數組存在同一空間
                                                                                   (內部數據存儲器空間用完的說...)
           flag=0;
              }
              else
              {
              get_highthree();
              LCD_HZ(0x80,TAB_WORD);
              LCD_HZ(0x90,F_DISPHIGHTHREE);
              flag=0;
              }
     }
       if((key_num&0xf0)==0)
        {   
               TR0=0;
                ET1=1;
                TMOD=0x10;
                TCON=0x40;
                for(i=0;i<10;i++)
                {
                 while(CHUFA==0);
                 TH1=0;
            TL1=0;
                  f1=0;
                     TR0=0;
                 while(CHUFA==1);
               while(CHUFA==0);
                 TR1=1;
                while(CHUFA==1);
              TR1=0;
                m=f1*65536+256*TH1+TL1;
                while(CHUFA==0);
                  TH1=0;
                TL1=0;
                f1=0;
                TR1=0;
                while(CHUFA==1);
                TR1=1;
                while(CHUFA==0);
                TR1=0;
                f=f1*65536+256*TH1+TL1;
          key_num=0xf0;
          sum1=m;
          sum2=m+f;
          sum1=sum1/sum2;
          sum3[ i]=sum1;
          }
          sum2=0;
          for(i=0;i<10;i++)
          {
            sum2=sum2+sum3[ i];
          }
          sum2=sum2/10;
             if(sum2>=0.1&&sum2<=0.40)
              {
                sum2=sum2-0.07;
                }
               else if(sum2>0.40&&sum2<=0.44)
                {
                sum2=sum2-0.04;
                }                                                                    占空比程序設計,本想用個中斷來著,試驗不成功簡單的算了
                                                                                      由于每次運行指令要耗費時間,精度不高,故加個實測校準程序
                                                                                      O(∩_∩)O哈哈~測評時能達到0.5%的精度,踩狗屎運了...
                else if(sum2>0.44&&sum2<=0.55)
                {
                 sum2=sum2-0.02;
                }                                                            
                else if(sum2>0.55&&sum2<=0.63)
                {
                sum2=sum2+0.03;
                }
                else sum2=sum2+0.07;
          get_f(sum2);
          LCD_HZ(0x88,TAB_WORD1);
          LCD_HZ(0x98,F_DISP);
          flag1=1;
        }
        if(flag1==1)                                        讓程序能范圍繼續測量頻率
        {
            TMOD=0x51;                          
           CKCON=0;         
           TCON=0x50;
              flag1=0;
       }
}
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:71259 發表于 2014-12-30 15:47 | 只看該作者
頻率計數器就(3.ASCII液晶輸出函數):
void get_f(float s1)

{

   int term;

   term=(int)(s1*10000);

F_DISP[0]=term/1000%10+0x30;

F_DISP[1]=term/100%10+0x30;

F_DISP[2]=0x2E;

F_DISP[3]=term/10%10+0x30;

F_DISP[4]=term%10+0x30;             占空比(原值一般為0.****)

}

//*******************************************

void  get_flow(float s1)

{  int term;

   term=(int)(s1*100);



F_DISPLOW[0]=term/1000%10+0x30;

F_DISPLOW[1]=term/100%10+0x30;

F_DISPLOW[2]=0x2E;

F_DISPLOW[3]=term/10%10+0x30;

F_DISPLOW[4]=term%10+0x30;              頻率讀數輸出顯示(10——99HZ)

}

//********************************************

void  get_flowhigh(void)

{

  

  

   F_DISPLOWHIGH[0]=f/100%10+0x30;

   F_DISPLOWHIGH[1]=f/10%10+0x30;

   F_DISPLOWHIGH[2]=f%10+0x30;

   F_DISPLOWHIGH[3]=0x2E;

   F_DISPLOWHIGH[4]=0x30;                     頻率讀書輸出顯示(100——999HZ)以下類推...

}

//********************************************

void  get_high(void)

{

  

   F_DISPHIGH[0]=f/1000%10+0x30;

   F_DISPHIGH[1]=f/100%10+0x30;

   F_DISPHIGH[2]=f/10%10+0x30;

   F_DISPHIGH[3]=f%10+0x30;

   }

  //*******************************************

  void get_highone(void)

  {

    if(f>=10000&&f<=99999)

       {

   F_DISPHIGHONE[0]=f/10000%10+0x30;

   F_DISPHIGHONE[1]=f/1000%10+0x30;

   F_DISPHIGHONE[2]=0x2E;

   F_DISPHIGHONE[3]=f/100%10+0x30;

   F_DISPHIGHONE[4]=f/10%10+0x30;

   }

   else

    {   F_DISPHIGHONE[0]=f/100000%10+0x30;

       F_DISPHIGHONE[1]=f/10000%10+0x30;

       F_DISPHIGHONE[2]=f/1000%10+0x30;

       F_DISPHIGHONE[3]=0x2E;

       F_DISPHIGHONE[4]=f/100%10+0x30;

       }

   }

   //******************************************





       void get_highthree(void)

   {

       F_DISPHIGHTHREE[0]=f/1000000%10+0x30;

       F_DISPHIGHTHREE[1]=0x2E;

       F_DISPHIGHTHREE[2]=f/100000%10+0x30;

       F_DISPHIGHTHREE[3]=f/10000%10+0x30;

       F_DISPHIGHTHREE[4]=f/1000%10+0x30;

       }
回復

使用道具 舉報

板凳
ID:71259 發表于 2014-12-30 15:48 | 只看該作者
頻率計數器(2.初始化及中斷):
void PCA_INIT(void)

{

       PCA0CN=0X40;                         //允許PCA計數器、定時器

       PCA0MD=0;                               //禁止看門狗定時器

}

//***********************************************

void INT_INIT(void)

{

       EX0=1;                                      //INIT0,鍵盤

       PX0=0;                                      //INT0為低優先級

       ET0=1;                                      //T0

       ET1=1;                                    //T1

       ET2=0;                                      //T2

       EIE1=0X0;                                 //0X08,允許ADC中斷

       ES0=0;                                       //uart

       EA=1;

}

//**************************************************



void Init_device(void)

{

       OSC_INIT();

       IO_INIT();

       XRAM_INIT();

       SMB_INIT();

       UART_INIT();

       DAC_INIT();

       ADC_INIT();

       INT0_INIT();

       TIMER_INIT();

       PCA_INIT();

       INT_INIT();

}

//**************************************************

void LCD_REST(void)

{

       int i;

       LCD_RST=0;

       for(i=0;i<255;i++);

       LCD_RST=1;

}

//********************************************************

void LCD_WC(unsigned char command)                          //LCD寫命令

{

       while(RCOMADDR&0X80);

       WCOMADDR=command;

}

//********************************************************

void LCD_INIT(void)                                                 //LCD初始化

{

       LCD_WC(0X30);                                                    //設為基本命令集

       LCD_WC(0X01);

       LCD_WC(0X02);                                                    //將DDRAM填滿20H,并設定DDRAM地址計數器為0

       LCD_WC(0X0C);                                                   //開整體顯示

}

//***********************************************************



void LCD_WD(unsigned char d)                               //LCD寫數據

{

       while(RCOMADDR&0X80);

       WDATADDR=d;

}

//**********************************************************

void LCD_HZ(unsigned char x,unsigned char temp[])                      //顯示一行字符

{

   int i=0;

   LCD_WC(x);                                                                                    //x代表位置,=0x80對應左上角

   while(temp[i]!=0)

        {

              LCD_WD(temp[i]);

              i++;

       }

}

//********************************************************

void LCD_BYTE(unsigned char x,unsigned char temp)                           //顯示一行字符

{

   LCD_WC(x);                                                                                    //x代表位置,=0x80對應左上角

   LCD_WD(temp);

}

//*********************************************************

void LCD_CLR(void)                                                     //LCD清屏

{

        LCD_WC(0X01);

}

//********************************************************

void KEY_INIT0(void) interrupt 0

{

  key_num=KEYCS&0x0f;

}

//*****T0中斷服務***************************************

void  TT0_INT0(void) interrupt 1

{

    int j=0;

       TL0=0x66;                                        //0Xb0;

       TH0=0x3d;                                        //0X3c;每單位0.5微秒*50000*40

擦,難道上次精度不夠是因為參數還沒改正確?

      fp--;

        if(fp) return;

        TR1=0;

              fp=T_C;                      //1s

        f=65536*f1+256*TH1+TL1;

              if(n==0)

              {

              jishu[n%11]=f;

              }

              else

              {

              if(abs(jishu[n%11-1]-f)>=10)

              {

                for(j=0;j<=10;j++)

                {

                  jishu[j]=f;

                }

           }

                else

                     {

                          jishu[n%11]=f;

                         }

              }



              n++;

        flag=1;

  TH1=0;

        TL1=0;

        f1=0;

              TR1=1;

     }

//******************************************

void TT1_INT1(void ) interrupt 3

{

f1++;      定時器中斷3,當計數器有溢出時會引發中斷

}
回復

使用道具 舉報

地板
ID:71259 發表于 2014-12-30 15:49 | 只看該作者
頻率計數器(1.液晶初始及鍵盤等):
#define WDATADDR XBYTE[0XC009]                            //LCD寫數據地址

#define RDATADDR XBYTE[0XC00B]                            //LCD讀數據地址

#define WCOMADDR XBYTE[0XC008]                          //LCD寫命令地址

#define RCOMADDR XBYTE[0XC00A]                           //LCD讀命令地址

#define KEYCS      XBYTE[0XC00C]                      //鍵盤片選地址

#define T_C    40

sbit LCD_RST=P3^0;

sbit CHUFA=P0^6;

unsigned char code TAB_WORD[]={"Frequency="};

unsigned char code TAB_WORD1[]={"DUTY="};

unsigned char    F_DISP[]={"00000%"};

unsigned char   F_DISPLOW[]={"00000HZ    "};

unsigned char   F_DISPLOWHIGH[]={"00000HZ   "}  ;

unsigned char  F_DISPHIGH[]={"0000HZ     "} ;

unsigned char  F_DISPHIGHONE[]={"00000*1kHZ"};

unsigned char  F_DISPHIGHTHREE[]={"00000*1MHZ"};  

unsigned char   jishu[11]={ 0,0,0,0,0,0,0,0,0,0,0};        低頻采用堆棧求平均值方法,但貌似最終對數不能穩定,難道是因為取11個數不好?

unsigned long n=0;

unsigned long m=0;

unsigned char fp;

unsigned long f;

unsigned char f1;

bit flag=0;

unsigned char key_num=0xff;                                  //存鍵號

void OSC_INIT (void)

{

       SFRPAGE=0X0F;

       OSCICL=OSCICL+4;

       OSCICN=0XC3;

       CLKSEL=0X30;

       SFRPAGE=0;

}

//********************************************

void IO_INIT(void)

{

       SFRPAGE=0X0F;

       P0MDIN=0Xe7;

       P0MDOUT=0X83;

       P0SKIP=0XF9;

       P1MDIN=0XFF;

       P1MDOUT=0XFF;

       P1SKIP=0XFF;

       P2MDIN=0XFE;

       P2MDOUT=0XFF;

       P2SKIP=0XFF;

       P3MDIN=0XFF;

       P3MDOUT=0XFF;

       P3SKIP=0XF9;                   //0xfd,增加P3.2作T1輸入

       P4MDOUT=0XFF;

       XBR0=0X09;

       XBR1=0Xe0;                       //0xc0,增加T1

       SFRPAGE=0X0;

}

//********************************************

void XRAM_INIT(void)

{

       SFRPAGE=0X0F;

       EMI0CF=0X07;

       SFRPAGE=0;

}

//********************************************

void SMB_INIT(void)

{

       SMB0CF=0XC1;

}

//********************************************

void UART_INIT(void)

{

             SCON0=0X0;

//********************************************

void DAC_INIT(void)

{

       IDA0CN=0XF2;

}

//********************************************

void ADC_INIT(void)

{

       REF0CN=0;                         //VDD為基準

       AMX0P=0X08;                           //正端接P20

       AMX0N=0X1F;                          //負端接GND

       ADC0CF=0X2C;                  //左對齊,轉換時鐘2MHZ

       ADC0CN=0X80;                  //寫ADOBUSY啟動AD

}

//********************************************

void INT0_INIT(void)

{

       IT01CF=0X05;                           //P0.5為INT0

       IT0=1;                                       //下降沿觸發

}

//********************************************

void TIMER_INIT(void)

{

       TMOD=0x51;                             //T0、T1方式1,T1計數方式

       CKCON=0;                                //系統時鐘12分頻

       TL0=0x66;                                

       TH0=0x3e;                        

       TL1=0X0;

       TH1=0X0;                                  //計數器清0

       fp=T_C;

       TMR2CN=0X04;                        //16位自動重裝

       TMR2RLL=0XF0;                       //10MS

       TMR2RLH=0XD8;

       TMR3CN=0X0C;                        //雙8位自動重裝入,系統時鐘1/12

       TMR3RLL=0XE0;                       //定時100us

       TMR3RLH=0XFF;

       TR0=1;

       TR1=1;

}
回復

使用道具 舉報

5#
ID:71326 發表于 2014-12-30 15:59 | 只看該作者
好 非常好
回復

使用道具 舉報

6#
ID:890642 發表于 2023-12-13 22:17 來自手機 | 只看該作者
daming 發表于 2014-12-30 15:49
頻率計數器(1.液晶初始及鍵盤等):
#define WDATADDR XBYTE[0XC009]                            //LCD寫 ...

夠詳細,值得學習
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 观看av| 免费在线观看av | xx视频在线观看 | 激情五月婷婷综合 | 国产99久久精品一区二区300 | 九九免费视频 | 日日摸天天添天天添破 | 国产我和子的乱视频网站 | 日韩在线小视频 | 成人午夜电影在线观看 | 国产激情视频在线免费观看 | 午夜小电影 | 日韩毛片免费看 | 激情一区二区三区 | 国产高清一区二区 | 欧美性生活免费 | 久久久青草婷婷精品综合日韩 | www..com18午夜观看| 精品国产伦一区二区三区观看方式 | 中文字幕一级毛片视频 | 中文字幕韩在线第一页 | 欧美一二三区 | 瑟瑟免费视频 | 91精品久久久久久久 | 亚洲香蕉在线视频 | 欧美一区二区三区国产 | 久草福利| 国产成人久久精品一区二区三区 | 91在线看| 久久99一区二区 | 亚洲精品久久久久久久久久久 | 久久亚洲一区 | 日韩欧美手机在线 | 九九热精品免费 | 精品久久久久久久久久久久 | 成人小视频在线观看 | 中文字幕av一区二区三区 | 中文字幕视频在线 | 亚洲一二三区精品 | 久久亚洲国产精品日日av夜夜 | 亚洲www|