找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3104|回复: 1
打印 上一主题 下一主题
收起左侧

51单片机频率计(数码管显示)

[复制链接]
跳转到指定楼层
楼主
ID:373623 发表于 2018-11-19 22:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
误差不大

单片机源程序如下:

  1. #include "reg51.h"
  2. #include "intrins.h"

  3. #define CKSEL           (*(unsigned char volatile xdata *)0xfe00)
  4. #define CKDIV           (*(unsigned char volatile xdata *)0xfe01)
  5. #define IRC24MCR        (*(unsigned char volatile xdata *)0xfe02)
  6. #define XOSCCR          (*(unsigned char volatile xdata *)0xfe03)
  7. #define IRC32KCR        (*(unsigned char volatile xdata *)0xfe04)
  8. #define M 2000

  9. sfr     ADC_CONTR   =   0xbc;
  10. sfr     ADC_RES     =   0xbd;
  11. sfr     ADC_RESL    =   0xbe;
  12. sfr     ADCCFG      =   0xde;
  13. sfr     P_SW2       =   0xba;
  14. sbit    EADC        =   IE^5;
  15. sfr     AUXR        =   0x8e;
  16. sfr     CMPCR1      =   0xe6;
  17. sfr     CMPCR2      =   0xe7;
  18. sfr     IE2         =   0xaf;
  19. sfr     AUXINTIF    =   0xef;
  20. sfr     T4T3M       =   0xd1;
  21. sfr     TL3         =   0xd5;
  22. sfr     TH3         =   0xd4;
  23. sfr     IPH         =   0xb7;
  24. sfr     P1M0        =   0x92;
  25. sfr     P1M1        =   0x91;

  26. sbit FreIn  = P0^4;

  27. sbit P26 = P2^6;
  28. sbit P27 = P2^7;

  29. sbit CLK = P2^3;
  30. sbit DAT = P2^1;

  31. void display164(unsigned char udata)
  32. {
  33.   char i;
  34.   for(i=0;i<8;i++)
  35.   {
  36.     if(udata&0x80)
  37.     {
  38.       DAT=1;
  39.       CLK=0;
  40.       udata = udata<<1;
  41.       CLK=1;
  42.     }
  43.     else
  44.     {
  45.       DAT=0;
  46.       CLK=0;
  47.       udata = udata<<1;
  48.       CLK=1;
  49.     }
  50.   }
  51. }       

  52. void DiviVol()
  53. {
  54.         P26 = 1;
  55.         P27= 0;
  56. }
  57. void NotDiviVol()
  58. {
  59.         P27 = 1;
  60.         P26 = 0;
  61. }
  62. void delay(int ms)
  63. {
  64.         int a,b;
  65.         for(a=ms;a>0;a--)
  66.                 for(b=120;b>0;b--);
  67. }
  68. unsigned int time = 0;
  69. unsigned int count = 0;
  70. unsigned long frequency = 0,temp=0,tempone = 0;
  71. unsigned char code Table[]={0xee,0x28,0xcd,0x6d,0x2b,0x67,0xe7,0x2c,0xef,0x6f};
  72. unsigned char code PotTable[]={0xfe,0x38,0xdd,0x7d,0x3b,0x77,0xf7,0x3c,0xff,0x7f};

  73. unsigned int H=0,L=0;
  74. unsigned char tempp[7]={0};
  75. unsigned int Vol = 0,RawVol = 0;

  76. bit flag = 0;
  77. unsigned int qf = 0;
  78. void SetOutXtal()
  79. {
  80.         P_SW2 = 0x80;
  81.   XOSCCR = 0xc0;                              //启动外部晶振
  82.   while (!(XOSCCR & 1));                      //等待时钟稳定
  83.   CKDIV = 0x00;                               //时钟不分频
  84.   CKSEL = 0x01;                               //选择外部晶振
  85.   P_SW2 = 0x00;
  86. }
  87. void CMP_Ini()
  88. {
  89.         CMPCR1 = 0x86;
  90.         CMPCR2 = 0x42;
  91. //        CMPCR2 = 0x43;
  92.         P_SW2 = 0x00;
  93. }
  94. void T1_Ini()
  95. {
  96.         TMOD = 0x00;
  97.         TH1 = 0x3c;
  98.         TL1 = 0xb0;
  99.         AUXR = 0x00;
  100.         ET1 = 1;
  101. }
  102. void T3_Ini()
  103. {
  104.         T4T3M = 0x04;
  105.         TH3 = 0x00;
  106.         TL3 = 0x00;
  107.   IE2=0x20; //允许T3中断
  108. }
  109. void INT1_Ini()
  110. {
  111.         IT1 = 1;
  112.         EX1 = 1;
  113.         IP = 0x04;
  114.         IPH = 0x04;
  115. }
  116. void SysClkTest()
  117. {
  118.         display164(Table[0]);   //七个数码管都显示0,则系统时钟选择正常
  119.         display164(Table[0]);
  120.         display164(Table[0]);
  121.         display164(Table[0]);
  122.         display164(Table[0]);
  123.           display164(Table[0]);
  124.         display164(Table[0]);
  125.         display164(Table[0]);
  126. }
  127. void ADC_Ini()
  128. {
  129.         DiviVol();                                   //初始选择分压
  130.         P1M0 = 0x00;                                //设置P1.0为ADC口
  131.         P1M1 = 0x03;                                //P1.0和P1.1都设置为高阻输入模式
  132.         ADCCFG = 0x00;                              //设置ADC时钟为系统时钟/2/16/16
  133.         ADC_CONTR = 0x80;                           //使能ADC模块
  134. }
  135. void main()
  136. {
  137.         int timev[M]={0};
  138.         int i,imax,imaxp;
  139.         imaxp=0;
  140.    
  141.        
  142.         SetOutXtal();
  143.         SysClkTest();
  144.        
  145.         INT1_Ini();
  146.         CMP_Ini();
  147.         T1_Ini();
  148.         T3_Ini();
  149.         ADC_Ini();
  150.         EA = 1;

  151.         while(1)
  152.         {
  153.                 if(flag==0)
  154.                 {   
  155.                
  156.                        
  157.                         for(i=0;i<M;i++)
  158.                         {   
  159.                                 ADC_CONTR |= 0x40;                      //启动AD转换
  160.                                 _nop_();
  161.                                 _nop_();
  162.                                 delay(1);
  163.                                 while (!(ADC_CONTR & 0x20));            //查询ADC完成标志               
  164.                                 ADC_CONTR &= ~0x20;                     //清完成标志
  165.                                 H=ADC_RES;
  166.                                 L=ADC_RESL;
  167.                                 RawVol=H*16+L/16;
  168.                                 ADC_CONTR &= 0xa0;                                           
  169.                         //        Vol = RawVol*11;
  170.                                 timev[i]=RawVol*11;
  171.                                 delay(5);
  172.                         }
  173.                        
  174.                         imax=timev[0];
  175.                         for(i=1;i<M;i++)
  176.                     {

  177.                         if(timev[i]>imax)
  178.                         {
  179.                             imax=timev[i];
  180.                             //imaxp=i;
  181.                         }
  182.                 }
  183.                         Vol=2*imax;
  184.                

  185. //                        if(RawVol<33)
  186. //                        {       
  187. //                                NotDiviVol();       
  188. //                                delay(5);
  189. //                                ADC_CONTR = 0x81;                           //使能ADC模块
  190. //                                delay(5);
  191. //                                ADC_CONTR |= 0x40;                      //启动AD转换
  192. //                                _nop_();
  193. //                                _nop_();
  194. //                                while (!(ADC_CONTR & 0x20));            //查询ADC完成标志               
  195. //                                ADC_CONTR &= ~0x20;                     //清完成标志
  196. //                                H=ADC_RES;
  197. //                                L=ADC_RESL;
  198. //                            
  199. //                                RawVol=H*16+L/16;
  200. //
  201. //                                Vol = RawVol/11;
  202. //                               
  203. //                    }

  204.                                 display164(Table[Vol/10%10]);
  205.                                 display164(Table[Vol/100%10]);
  206.                                 display164(PotTable[Vol/1000%10]);
  207.                                 display164(Table[Vol/10000]);
  208.                                 display164(0x00);
  209.                             display164(0x00);
  210.                             display164(0x00);                       
  211.                                   display164(0x3e);
  212.                                   DiviVol();
  213.                                   delay(5);
  214.                                 //imax=0;
  215. //                  ADC_CONTR = 0x80;                           //使能ADC模块
  216. //                  ADC_CONTR |= 0x40;                          //启动AD转换
  217.                         time = 0;
  218.                   delay(6000);
  219.                  }
  220.                  if(flag==1)
  221.                  {
  222.                          if(time==0)
  223.                          {
  224. //                                while(FreIn==1);       
  225. //                    while(FreIn==0);       
  226.                           TR1=1;//打开T1、T3,开始测频
  227.               T4T3M |= 0x08;                       
  228.                          }                                 
  229.                  }          
  230.                  if(time==20)
  231.                  {                                       
  232.                          TR1 = 0;
  233.                         T4T3M &= 0xf7;               
  234.                         temp = TH3*256+TL3+count*65536;       
  235.                         tempone = temp+1;
  236.                         frequency = temp+(int)(tempone*0.0001);       
  237.                         tempp[0] = frequency%10;
  238.                         tempp[1] = (frequency/10)%10;
  239.                         tempp[2] = (frequency/100)%10;
  240.                         tempp[3] = (frequency/1000)%10;
  241.                         tempp[4] = (frequency/10000)%10;
  242.                         tempp[5] = (frequency/100000)%10;
  243.                         tempp[6] = (frequency/1000000)%10;
  244.                         if((frequency/1000000)%10==0)
  245.                         {
  246.                                 tempp[6] = 10;
  247.                                 if((frequency/100000)%10==0)
  248.                          {
  249.                                  tempp[5] = 10;
  250.                                         if((frequency/10000)%10==0)
  251.                                         {
  252.                                                 tempp[4] = 10;
  253.                                                 if((frequency/1000)%10==0)
  254.                                                 {
  255.                                                         tempp[3] = 10;
  256.                                                         if((frequency/100)%10==0)
  257.                                                         {
  258.                                                                 tempp[2] = 10;
  259.                                                                 if((frequency/10)%10==0)
  260.                                                                 {
  261.                                                                         tempp[1] = 10;
  262.                                                                         if(frequency%10==0)
  263.                                                                         {
  264.                                                                                 tempp[0] = 10;
  265.                                                                         }
  266.                                                                 }
  267.                                                         }
  268.                                                 }
  269.                                         }
  270.                          }
  271.                         }
  272.                         display164(Table[tempp[0]]);   //频率送显
  273.                         display164(Table[tempp[1]]);
  274.                         display164(Table[tempp[2]]);
  275.                         display164(Table[tempp[3]]);
  276.                         display164(Table[tempp[4]]);
  277.                         display164(Table[tempp[5]]);
  278.                         display164(Table[tempp[6]]);
  279.                         display164(0x71);               
  280.                         time = 0;
  281.                         count = 0;
  282.                         TH3 = 0;
  283.                         TL3 = 0;
  284.                         TH1 = 0x3c;
  285.                     TL1 = 0xb0;          

  286.            }       
  287.         }
  288. }
  289. void INT1_Ser() interrupt 2
  290. {
  291.         flag=!flag;
  292. }
  293. void T1_Isr() interrupt 3
  294. {       
  295.   time++;
  296. }
  297. void T3_Isr() interrupt 19
  298. {
  299.   count++;                        
  300.   AUXINTIF &= 0xfd; //清中断标志                       
  301. }

  302. /*
  303. #include "reg51.h"
  304. #include "intrins.h"

  305. #define CKSEL           (*(unsigned char volatile xdata *)0xfe00)
  306. #define CKDIV           (*(unsigned char volatile xdata *)0xfe01)
  307. #define IRC24MCR        (*(unsigned char volatile xdata *)0xfe02)
  308. #define XOSCCR          (*(unsigned char volatile xdata *)0xfe03)
  309. #define IRC32KCR        (*(unsigned char volatile xdata *)0xfe04)


  310. sfr     ADC_CONTR   =   0xbc;
  311. sfr     ADC_RES     =   0xbd;
  312. sfr     ADC_RESL    =   0xbe;
  313. sfr     ADCCFG      =   0xde;
  314. sfr     P_SW2       =   0xba;
  315. sbit    EADC        =   IE^5;
  316. sfr     AUXR        =   0x8e;
  317. sfr     CMPCR1      =   0xe6;
  318. sfr     CMPCR2      =   0xe7;
  319. sfr     IE2         =   0xaf;
  320. sfr     AUXINTIF    =   0xef;
  321. sfr     T4T3M       =   0xd1;
  322. sfr     TL3         =   0xd5;
  323. sfr     TH3         =   0xd4;
  324. sfr     IPH         =   0xb7;
  325. sfr     P1M0        =   0x92;
  326. sfr     P1M1        =   0x91;

  327. sbit FreIn  = P0^4;

  328. sbit P26 = P2^6;
  329. sbit P27 = P2^7;

  330. sbit CLK = P2^3;
  331. sbit DAT = P2^1;

  332. void display164(unsigned char udata)
  333. {
  334.   char i;
  335.   for(i=0;i<8;i++)
  336.   {
  337.     if(udata&0x80)
  338.     {
  339.       DAT=1;
  340.       CLK=0;
  341.       udata = udata<<1;
  342.       CLK=1;
  343.     }
  344.     else
  345.     {
  346.       DAT=0;
  347.       CLK=0;
  348.       udata = udata<<1;
  349.       CLK=1;
  350.     }
  351.   }
  352. }       

  353. void DiviVol()
  354. {
  355.         P26 = 1;
  356.         P27= 0;
  357. }
  358. void NotDiviVol()
  359. {
  360.         P27 = 1;
  361.         P26 = 0;
  362. }
  363. void delay(int ms)
  364. {
  365.         int a,b;
  366.         for(a=ms;a>0;a--)
  367.                 for(b=120;b>0;b--);
  368. }
  369. unsigned int time = 0;
  370. unsigned int count = 0;
  371. unsigned long frequency = 0,temp=0,tempone = 0;
  372. unsigned char code Table[]={0xee,0x28,0xcd,0x6d,0x2b,0x67,0xe7,0x2c,0xef,0x6f};
  373. unsigned char code PotTable[]={0xfe,0x38,0xdd,0x7d,0x3b,0x77,0xf7,0x3c,0xff,0x7f};
  374. //unsigned char code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
  375. //unsigned char code PotTable[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
  376. unsigned int H=0,L=0;
  377. unsigned char tempp[7]={0};
  378. unsigned int Vol = 0,RawVol = 0;

  379. bit flag = 0;
  380. unsigned int qf = 0;
  381. void SetOutXtal()
  382. {
  383.         P_SW2 = 0x80;
  384.   XOSCCR = 0xc0;                              //启动外部晶振
  385.   while (!(XOSCCR & 1));                      //等待时钟稳定
  386.   CKDIV = 0x00;                               //时钟不分频
  387.   CKSEL = 0x01;                               //选择外部晶振
  388.   P_SW2 = 0x00;
  389. }
  390. void CMP_Ini()
  391. {
  392.         CMPCR1 = 0x86;
  393.         CMPCR2 = 0x42;
  394. //        CMPCR2 = 0x43;
  395.         P_SW2 = 0x00;
  396. }
  397. void T1_Ini()
  398. {
  399.         TMOD = 0x00;
  400.         TH1 = 0x3c;
  401.         TL1 = 0xb0;
  402.         AUXR = 0x00;
  403.         ET1 = 1;
  404. }
  405. void T3_Ini()
  406. {
  407.         T4T3M = 0x04;
  408.         TH3 = 0x00;
  409.         TL3 = 0x00;
  410.   IE2=0x20; //允许T3中断
  411. }
  412. void INT1_Ini()
  413. {
  414.         IT1 = 1;
  415.         EX1 = 1;
  416.         IP = 0x04;
  417.         IPH = 0x04;
  418. }
  419. void SysClkTest()
  420. {
  421.         display164(Table[0]);   //七个数码管都显示0,则系统时钟选择正常
  422.         display164(Table[0]);
  423.         display164(Table[0]);
  424.         display164(Table[0]);
  425.         display164(Table[0]);
  426.           display164(Table[0]);
  427.         display164(Table[0]);
  428.         display164(Table[0]);
  429. }
  430. void ADC_Ini()
  431. {
  432.         DiviVol();                                   //初始选择分压
  433.         P1M0 = 0x00;                                //设置P1.0为ADC口
  434.         P1M1 = 0x03;                                //P1.0和P1.1都设置为高阻输入模式
  435.         ADCCFG = 0x00;                              //设置ADC时钟为系统时钟/2/16/16
  436.         ADC_CONTR = 0x80;                           //使能ADC模块
  437. }
  438. void main()
  439. {
  440.         SetOutXtal();
  441.         SysClkTest();
  442.        
  443.         INT1_Ini();
  444.         CMP_Ini();
  445.         T1_Ini();
  446.         T3_Ini();
  447.         ADC_Ini();
  448.         EA = 1;
  449.         while(1)
  450.         {
  451.                 if(flag==0)
  452.                 {      
  453.                         ADC_CONTR |= 0x40;                      //启动AD转换
  454.                         _nop_();
  455.                         _nop_();
  456.                         delay(1);
  457.                         while (!(ADC_CONTR & 0x20));            //查询ADC完成标志               
  458.                         ADC_CONTR &= ~0x20;                     //清完成标志
  459.                         H=ADC_RES;
  460.                         L=ADC_RESL;
  461.                         RawVol=H*16+L/16;
  462.                         ADC_CONTR &= 0xa0;                                           
  463.                         Vol = RawVol*11;
  464.                
  465. //                        if(RawVol<33)
  466. //                        {       
  467. //                                NotDiviVol();       
  468. //                                delay(5);
  469. //                                ADC_CONTR = 0x81;                           //使能ADC模块
  470. //                                delay(5);
  471. //                                ADC_CONTR |= 0x40;                      //启动AD转换
  472. //                                _nop_();
  473. //                                _nop_();
  474. //                                while (!(ADC_CONTR & 0x20));            //查询ADC完成标志               
  475. //                                ADC_CONTR &= ~0x20;                     //清完成标志
  476. //                                H=ADC_RES;
  477. //                                L=ADC_RESL;
  478. //                            
  479. //                                RawVol=H*16+L/16;
  480. //
  481. //                                Vol = RawVol/11;
  482. //                               
  483. //                    }

  484.                                 display164(Table[Vol/10%10]);
  485.                                 display164(Table[Vol/100%10]);
  486.                                 display164(PotTable[Vol/1000%10]);
  487.                                 display164(Table[Vol/10000]);
  488.                                 display164(0x00);
  489.                     display164(0x00);
  490.                     display164(0x00);                       
  491.                           display164(0x3e);
  492.                           DiviVol();
  493.                   delay(5);
  494.                   ADC_CONTR = 0x80;                           //使能ADC模块
  495.                   ADC_CONTR |= 0x40;                          //启动AD转换
  496.                         time = 0;
  497.                   delay(3000);
  498.                  }
  499.                  if(flag==1)
  500.                  {
  501.                          if(time==0)
  502.                          {
  503. //                                while(FreIn==1);       
  504. //                    while(FreIn==0);       
  505.                           TR1=1;//打开T1、T3,开始测频
  506.               T4T3M |= 0x08;                       
  507.                          }                                 
  508.                  }          
  509.                  if(time==20)
  510.                  {                                       
  511.                          TR1 = 0;
  512.                         T4T3M &= 0xf7;               
  513.                         temp = TH3*256+TL3+count*65536;       
  514.                         tempone = temp+1;
  515.                         frequency = temp+(int)(tempone*0.0001);       
  516.                         tempp[0] = frequency%10;
  517.                         tempp[1] = (frequency/10)%10;
  518.                         tempp[2] = (frequency/100)%10;
  519.                         tempp[3] = (frequency/1000)%10;
  520.                         tempp[4] = (frequency/10000)%10;
  521.                         tempp[5] = (frequency/100000)%10;
  522.                         tempp[6] = (frequency/1000000)%10;
  523.                         if((frequency/1000000)%10==0)
  524.                         {
  525.                                 tempp[6] = 10;
  526.                                 if((frequency/100000)%10==0)
  527.                          {
  528.                                  tempp[5] = 10;
  529.                                         if((frequency/10000)%10==0)
  530.                                         {
  531.                                                 tempp[4] = 10;
  532.                                                 if((frequency/1000)%10==0)
  533.                                                 {
  534.                                                         tempp[3] = 10;
  535.                                                         if((frequency/100)%10==0)
  536.                                                         {
  537.                                                                 tempp[2] = 10;
  538.                                                                 if((frequency/10)%10==0)
  539.                                                                 {
  540.                                                                         tempp[1] = 10;
  541.                                                                         if(frequency%10==0)
  542.                                                                         {
  543.                                                                                 tempp[0] = 10;
  544.                                                                         }
  545.                                                                 }
  546.                                                         }
  547.                                                 }
  548.                                         }
  549.                          }
  550.                         }
  551.                         display164(Table[tempp[0]]);   //频率送显
  552.                         display164(Table[tempp[1]]);
  553.                         display164(Table[tempp[2]]);
  554.                         display164(Table[tempp[3]]);
  555.                         display164(Table[tempp[4]]);
  556.                         display164(Table[tempp[5]]);
  557.                         display164(Table[tempp[6]]);
  558.                         display164(0x71);               
  559.                         time = 0;
  560.                         count = 0;
  561.                         TH3 = 0;
  562.                         TL3 = 0;
  563.                         TH1 = 0x3c;
  564.                     TL1 = 0xb0;          

  565.            }       
  566.         }
  567. }
  568. void INT1_Ser() interrupt 2
  569. {
  570.         flag=!flag;
  571. }
  572. void T1_Isr() interrupt 3
  573. {       
  574.   time++;
  575. }
  576. void T3_Isr() interrupt 19
  577. {
  578.   count++;                        
  579.   AUXINTIF &= 0xfd; //清中断标志                       
  580. }       
  581. */
复制代码

所有资料51hei提供下载:
测频率.rar (37.85 KB, 下载次数: 25)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-11-20 04:15 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表