標題: 單片機數(shù)字頻率計單周期實現(xiàn) 2015電賽F題答案 [打印本頁]

作者: zhangsisi    時間: 2018-7-30 09:58
標題: 單片機數(shù)字頻率計單周期實現(xiàn) 2015電賽F題答案
電路原理圖如下:


單片機源程序如下:
  1. #include<reg51.h>      
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. //單周期定閘門時間測量盡量降低誤差
  5. //后續(xù)待實現(xiàn):實現(xiàn)多周期定閘門時間測量以降低誤差

  6. static bit end= 0;        //周期開始結束標志,為減少中斷服務工作量定義為全局變量
  7. uchar m=0;         //保存定時器清零次數(shù)
  8. uchar u=0;
  9. uint xL,xH=0;                //剩余計數(shù)次數(shù)
  10. unsigned long t0,c;                //分別保存被測信號的周期和頻率
  11. uchar a[]={'F',':','w','a','i','t','.','.','.','.','.','H','z'};          //頻率數(shù)據結果保存

  12. sbit lcdrw=P1^6;
  13. sbit lcdrs=P1^7;
  14. sbit lcden=P2^4;

  15. void delay(uint s)//延時1MS
  16. {
  17.   uint r,g;
  18.    for(r=s;r>0;r--)
  19.      for(g=10;g>0;g--); //原值為110,我改為了10,做實際產品時可能要改回去
  20. }

  21. /////////////////LCD1602的設置//////////////////
  22. void write_com(uchar com) // 寫指令
  23. {  
  24.    lcdrs=0;                //低電平0時選擇指令寄存器
  25.    P0=com;
  26.    delay(5);
  27.    lcden=1;                //高電平(1)時讀取信息
  28.    delay(5);
  29.    lcden=0;                //負跳變時執(zhí)行指令
  30. }
  31. void write_data(uchar date) // 寫數(shù)據
  32. {  
  33.    lcdrs=1;                 //高電平1時選擇數(shù)據寄存器
  34.    P0=date;
  35.    delay(5);   //高電平(1)時讀取信息
  36.    lcden=1;
  37.    delay(5);
  38.    lcden=0;           //負跳變時執(zhí)行指令
  39. }
  40. void initlcd()//初始化LCD1602
  41. {
  42.   lcdrw=0;        //低電平(0)時進行寫操作
  43.   lcden=0;          //負跳變時執(zhí)行指令
  44.   write_com(0x38);//顯示模式設置
  45.   write_com(0x0c); //顯示開,開游標,不閃爍  
  46.   write_com(0x06); // 字符時整體不移動  
  47. }
  48. ////////////LCD1602設置///////////////////////

  49. ///////////定時計數(shù)器外部中斷設置//////////////
  50. void CTINT0_init()                 //定時計數(shù)器0和外部中斷0初始化
  51. {       
  52.         TMOD = 0x1;             //T0工作在模式1,定時方式FHP
  53.         TH0=0;                         //定時計數(shù)器初值清零
  54.         TL0=0;
  55.         EA=1;                                  //開總中斷
  56.         ET0=1;                         //開Timer0中斷
  57.         EX0=1;                                  //開外部中斷0
  58.         IT0=1;                                  //設置外部中斷方式為下降沿觸發(fā)
  59. }
  60. ///////////定時計數(shù)器外部中斷設置//////////////

  61. ////////////////中斷服務函數(shù)//////////////////
  62. void ITC0() interrupt 0   //外部中斷0服務程序
  63. {       
  64.         if(end)         //FHP被測信號一個周期結束做三件事情:1、記錄周期相關數(shù)據;2、定時計數(shù)器清零并停止;3、告知下次中斷為周期開始
  65.         {
  66.                 u=m;                                  //讀定時計數(shù)器0溢出次數(shù)
  67.                 TR0=0;        //停止計時器
  68.                 xH=TH0;                  //讀定時計數(shù)器0當前值
  69.                 xL=TL0;
  70.                 end = 0;                //設置下次中斷為周期開始
  71.         }
  72.         else        //FHP被測信號一個周期開始做一件事情:啟動計時器
  73.         {
  74.                 TH0=TL0=0;                         //定時計數(shù)器初值清零
  75.                 TR0=1;        //啟動計時器
  76.                 m=0;                                  //溢出次數(shù)清零
  77.                 end = 1;        //                //設置下次中斷為周期結束
  78.         }
  79. }
  80. void TIME0() interrupt 1  //定時計數(shù)器0溢出中斷服務程序
  81. {
  82.         m++;                                  //溢出次數(shù)加1
  83. }
  84. ////////////////中斷服務函數(shù)//////////////////

  85. void main()
  86. {
  87.         uchar i;
  88.         CTINT0_init();                  //定時計數(shù)器外部中斷初始化       
  89.         initlcd();                          //液晶顯示初始化       
  90.         while(1)
  91.         {                               
  92.                         t0=u*65536 + xH*256 + xL;                                   //計算周期
  93.                         c=1000000000/t0;                           //計算頻率,保存的是頻率擴大了1000倍的值
  94.                         //計算結果逐位保存,首先是小數(shù)點后三位
  95.                         a[10]=c%10+'0';
  96.                         a[9]=(c/10)%10+'0';
  97.                         a[8]=(c/100)%10+'0';
  98.                         c /= 1000;//下面是整數(shù)部分
  99.                         a[6]=c%10+'0';
  100.                         a[5]=(c/10)%10+'0';
  101.                         a[4]=(c/100)%10+'0';
  102.                         a[3]=(c/1000)%10+'0';
  103.                         a[2]=(c/10000)%10+'0';
  104.                         write_com(0x80);
  105.                         for(i=0;i<=12;i++)
  106.                         {  
  107.                                 write_data(a[i]);
  108.                                 delay(2);                //現(xiàn)在延時只有0.2ms,實際做產品時可能要加長
  109.                         }         
  110.          }
  111. }
復制代碼

所有資料51hei提供下載:
數(shù)字頻率計單周期實現(xiàn).rar (563.21 KB, 下載次數(shù): 87)



作者: 部落歲月    時間: 2022-2-11 17:46
這個看原理圖就知道不行了啊

作者: zhxiufan    時間: 2022-5-10 10:38
嗯,測低頻還是可以的,中高頻就有些吃力了。
作者: hy47566398    時間: 2022-5-10 16:36
簡單的事搞復雜了!
作者: 3211056565    時間: 2024-4-18 14:14
這樣連RS  RW  E不會亮的 直接連




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1