找回密码
 立即注册

QQ登录

只需一步,快速开始

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

带分频整形的单片机频率计(1Hz—20MHz)源程序,仿真与设计论文等全套资料

  [复制链接]
跳转到指定楼层
楼主
单片机频率计 系统采用单片机+分频模块+整形模块+lcd1602液晶显示+按键设计而成。
频率的测量范围为1Hz—20MHz能测量各种周期信号能测出正弦波、三角波或方波等波形的频率。通过LCD1602液晶显示屏显示检测到的即时频率数值(最多8位数,单位为Hz)。


频率计电路原理图如下:


74HC14电路设计
              由于三极管放大电路输出的信号不是标准的方波信号,存在着上升沿不够陡峭,波形类似于正弦波等问题,为了使单片机对信号更好的采集,这里使用了施密特触发器74HC14对三极管放大电路输出的信号进行整形。电路图如图3-10所示。
图3-10施密特触发器电路原理图
              其中输入信号从芯片的1号脚输入,74HC14本身是一个芯片内部带有6个施密特触发器,我这里为了充分利用芯片使用了其中三个,实际上可以只使用一个。整形后的信号从芯片的6号脚输出。
3.5分频模块设计
3.5.1 74HC390芯片介绍
分频电路一般采用十进制计数器如74HC290、74HC390等来实现时间计数单元的计数功能。本次设计中选择74HC390。由其内部逻辑框图(如图3)可知,其为双2-5-10异步计数器,并每一计数器均有一个异步清零端(高电平有效)。由于我们要设计的是100分频电路,因此74HC390内部两个计数器都用上,分别都设置成10计数器。
图3-11 74HC390内部逻辑框图
3.5.2 74HC390分频电路设计
由于单片机运行速度有限,单片机运行一条基础指令需要1个机器周期即12个是时钟周期,换算成时间为1us。因此当频率过高的时候单片机就不能很精确的换算出频率。为了解决这个问题,这设计加入了一个100分频的计数器。当频率高于200KHZ的时候单片机计算分频后的信号,当频率低于200KHZ的时候计算分频前的信号。这样高低搭配可以扩大单片机的测量频率。最终换算出其真实对应的频率并在液晶上显示。其中电路图如图3-12所示。
图3-12 74HC390分频电路原理图

4.系统软件设计
4.1系统软件总体设计
4-1系统主流程图


频率计元件清单:


单片机仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


频率计仿真操作说明:
   鼠标右击这个元件,
选择最后一项就可以了

单片机频率计源程序如下:
  1. //******************************************************************************************
  2. //连接框图:       ___________________
  3. //                |              P1.0 |->RS
  4. //                |              P1.1 |->RW
  5. //                |              P1.2 |->E
  6. //                |              P0   |->DB
  7. //                |                     P3.4 |->1~9999hz的输入
  8. //                |              P3.5 |->1~9999KHZ输入 (分频后)
  9. //******************************************************************************************
  10. #include <reg52.h>
  11. unsigned long int fre;
  12. unsigned char time;
  13. unsigned int count;
  14. unsigned int count1;

  15. //端口及函数说明----------------------------------------------------------------------------

  16. sbit   LCD_RS=P1^0;          //片选信号
  17. sbit   LCD_RW=P1^1;          //读写信号
  18. sbit   LCD_E=P1^2;           //使能信号

  19. #define LCD_DB     P0        //数据信号
  20. unsigned char character[10]={0};//在屏幕上显示的字符串
  21. unsigned char character_1[]={"fre= Hz"};
  22. unsigned char FLAG = 0;

  23. void LCD_init(void);//初始化函数   
  24. void LCD_write_command(unsigned char command);//写指令函数         
  25. void LCD_write_data(unsigned char dat);//写数据函数           
  26. void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
  27. void delay_n40us(unsigned int n);//延时函数
  28.      
  29. void timer_init();            //中断初始化函数  


  30. //-------------------------------------------------------------------------------

  31. void delay_n40us(unsigned int n)                  //延时函数
  32. {
  33.         unsigned int i;
  34.         unsigned char j;            
  35.         for(i=n;i>0;i--)
  36.         for(j=0;j<2;j++);         
  37. }

  38. void delay_1s()
  39. {
  40.         unsigned int i,j;
  41.         for(i = 0;i<100;i++)
  42.                 for(j = 0;j<1000;j++);
  43. }                                      

  44. void LCD_init(void)         //液晶初始化函数
  45. {
  46.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  47.         LCD_write_command(0x38);//设置8位格式,2行,5x7
  48.         LCD_write_command(0x38);//设置8位格式,2行,5x7         切记要写三遍!!!!
  49.         LCD_write_command(0x0c);//整体显示,关光标,不闪烁
  50.         LCD_write_command(0x06);//设定输入方式,增量不移位
  51.         LCD_write_command(0x01);//清除屏幕显示         
  52.         delay_n40us(100);//清屏延时
  53. }

  54. void LCD_write_command(unsigned char dat)  //写命令函数
  55. {
  56.         LCD_DB=dat;
  57.         LCD_RS=0;//指令         
  58.         LCD_RW=0;//写入         
  59.         LCD_E=1; //使能         
  60.         LCD_E=0;
  61.         delay_n40us(1);//写命令延时   
  62. }         

  63. void LCD_write_data(unsigned char dat)          //写数据函数
  64. {
  65.         LCD_DB=dat;
  66.         LCD_RS=1;//数据         
  67.         LCD_RW=0;//写入         
  68.         LCD_E=1;//使能  
  69.         LCD_E=0;
  70.         delay_n40us(1);         //写数据延时
  71. }

  72. void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)//显示一个字符
  73. {
  74.         unsigned char address;
  75.         if(y==1)
  76.                  address=0x80+x;         //显示在第一排的时候的x的地址
  77.         else
  78.                  address=0xc0+x;         //显示在第二排的时候的x的地址
  79.         LCD_write_command(address);         //输入地址
  80.         LCD_write_data(dat);                 //输入数据
  81. }
  82. void LCD_disp_num(unsigned char x,unsigned char y,unsigned char dat)//显示一个数字
  83. {
  84.         unsigned char address;
  85.         if(y==1)
  86.                  address=0x80+x;         //显示在第一排的时候的x的地址
  87.         else
  88.                  address=0xc0+x;         //显示在第二排的时候的x的地址
  89.         LCD_write_command(address);         //输入地址
  90.         LCD_write_data(dat+48);                 //输入数据
  91. }

  92. void dis_num(void)
  93. {
  94.         unsigned char i=0,j=0,k=0;
  95.         LCD_write_command(0x01);//清除屏幕显示
  96.         
  97.         character[0] = fre/1000000;
  98.         character[1] = fre/100000%10;
  99.         character[2] = fre/10000%10;
  100.         character[3] = fre/1000%10;
  101.         character[4] = fre/100%10;
  102.         character[5] = fre/10%10;
  103.         character[6] = fre%10;
  104.     character[7] = 'H';
  105.         character[8] = 'z';
  106.         
  107.         for(i = 0;i<4;i++)                 //显示fre
  108.         {
  109.                  LCD_disp_char(i+0,1,character_1[i]);
  110.         }
  111.         for(i = 0;i<10;i++)         //判断第一个不为0的数
  112.         {
  113.                 if(character[i]!=0)
  114.                         break;
  115.         }
  116.         k = 10-i-2;
  117.         for(j = 0;j<k;j++)         //显示所有的数字
  118.         {
  119.                         LCD_disp_num(4+j,1,character[i++]);        
  120.         }
  121.         
  122.     for(i = 5;i<7;i++)         //显示Hz
  123.         {
  124.                  LCD_disp_char(j+4,1,character_1[i]);
  125.                 j++;
  126.         }
  127. }



  128. void main()
  129. {
  130.         unsigned char i;
  131.         LCD_init();
  132.         timer_init();             //定时/计数器初始化

  133.         for(i = 0;i<4;i++)
  134.         {
  135.                  LCD_disp_char(i+0,1,character_1[i]);
  136.         }
  137.         while(1)
  138.         {
  139.                 dis_num();         //显示
  140.                  delay_1s();
  141.                         
  142.         }                                                
  143. }

  144. void timer_init(void)         //定时/计数器初始化
  145. {
  146.         TMOD=0x66;                //计数器0工作工作方式2,自动重装初值
  147.         TH0=0;                    //计数器初值为0
  148.         TL0=0;
  149.         TR0=1;                    //计数器开始计数            
  150.         ET0=1;                    //打开计数器0中断   

  151.         TH1=0;                    //计数器初值为0
  152.         TL1=0;
  153.         TR1=1;                    //计数器开始计数            
  154.         ET1=1;                    //打开计数器0中断   

  155.         RCAP2H=(65536-62500)/256; //在程序初始化的时候给RCAP2L和RCAP2H赋值,
  156.         RCAP2L=(65536-62500)%256; //TH2和TL2将会在中断产生时自动使TH2=RCAP2H,TL2=RCAP2L。
  157.         TH2=RCAP2H;               //12M晶振下每次中断62.5ms
  158.         TL2=RCAP2L;
  159.         ET2=1;                    //打开定时器2中断         
  160.         TR2=1;                    //定时器2开始计时  
  161.         EA=1;                     //开总中断   
  162. }
  163. //----------------------------------------------------------------
  164. void timer2(void) interrupt 5 //定时器2中断(62.5ms)
  165. {
  166.         double temp;
  167.         time++;
  168.         TF2=0;                    //定时器2的中断标志位TF2不能够由硬件清零,所以要在中断服务程序中将其清零
  169.         if (time==16)             //定时1s时间到  
  170.         {
  171.            time=0;                //计时清0                 
  172.            fre=(long)count*256+TL1;     //count*256强制转换成long型,否则将不产生进位 先判断分频后的
  173.            FLAG = 0;
  174.          
  175.            if(fre<2000)//200K之后读取分频后的频率
  176.            {
  177.                            fre = (long)count1*256+TL0;
  178.                         FLAG = 1;         
  179.            }   
  180.            
  181.            count=0;               //清零计数器0计数         
  182.            count1=0;
  183.            EA=1;                  //开中断            
  184.         }
  185. }
  186. //----------------------------------------------------------------
  187. void timer0(void) interrupt 1 //计数器0中断         
  188. {
  189.         count++;
  190. }               
  191. //----------------------------------------------------------------
  192. void timer1(void) interrupt 3 //计数器1中断
  193. {
  194.         count1++;
  195. }
  196.         
  197. ……………………

  198. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
##单片机频率计.rar (10.69 MB, 下载次数: 949)


评分

参与人数 2黑币 +65 收起 理由
都市郎 + 15 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:419299 发表于 2018-11-2 14:02 | 只看该作者
资料配套齐全,很有参考价值。
回复

使用道具 举报

板凳
ID:65956 发表于 2018-11-27 11:50 | 只看该作者
很不错,收藏了
回复

使用道具 举报

地板
ID:324142 发表于 2018-12-10 11:02 | 只看该作者
下载打开根本是乱码,一点用都没有
回复

使用道具 举报

5#
ID:443340 发表于 2018-12-10 15:06 | 只看该作者
新手来看看
回复

使用道具 举报

6#
ID:272625 发表于 2018-12-11 01:27 | 只看该作者
资料非常全,很好,感谢楼主分享!
回复

使用道具 举报

7#
ID:195887 发表于 2018-12-13 21:39 | 只看该作者
赞一个
回复

使用道具 举报

8#
ID:68189 发表于 2019-3-29 16:52 | 只看该作者
已经下载了资料,很不错很有学习价值!谢谢.
回复

使用道具 举报

9#
ID:336842 发表于 2019-4-13 20:47 | 只看该作者
为什么我测不到1MHZ以上的频率啊,仿真一直崩溃
回复

使用道具 举报

10#
ID:442911 发表于 2019-4-14 22:21 | 只看该作者
感谢楼主分享
回复

使用道具 举报

11#
ID:501358 发表于 2019-4-18 10:19 | 只看该作者
谢谢分享
回复

使用道具 举报

12#
ID:501358 发表于 2019-4-18 10:28 | 只看该作者
感谢楼楼
回复

使用道具 举报

13#
ID:552029 发表于 2019-5-31 18:30 | 只看该作者
内容很详细,看的非常清楚,会一直关注这个网站的。
回复

使用道具 举报

14#
ID:399179 发表于 2019-5-31 21:26 来自手机 | 只看该作者
感谢楼主分享,有时间做个!
回复

使用道具 举报

15#
ID:656668 发表于 2019-12-9 23:10 来自手机 | 只看该作者
资料很全面,这两天正好在学习这个,感谢楼主分享
回复

使用道具 举报

16#
ID:661037 发表于 2019-12-31 16:47 | 只看该作者
很给力
回复

使用道具 举报

17#
ID:661037 发表于 2020-1-2 14:11 | 只看该作者
很不错哟
回复

使用道具 举报

18#
ID:702610 发表于 2020-3-4 22:50 来自手机 | 只看该作者
能帮我设计一下吗?
回复

使用道具 举报

19#
ID:196787 发表于 2020-3-10 22:16 | 只看该作者
资料非常全,很好,感谢楼主分享!
回复

使用道具 举报

20#
ID:724058 发表于 2020-4-28 19:22 | 只看该作者
仿真图文件夹里边的hex跟程序文件夹里边的不是同一个吧,仿真图文件夹里边的那个很准,程序文件夹里边的那个老是出错
回复

使用道具 举报

21#
ID:736675 发表于 2020-5-4 18:44 | 只看该作者
谢谢楼主
回复

使用道具 举报

22#
ID:159857 发表于 2020-5-14 21:38 | 只看该作者

很不错,收藏了
回复

使用道具 举报

23#
ID:712295 发表于 2020-5-17 13:41 | 只看该作者
楼主怎么计算这个频率计能测多少频率范围???
回复

使用道具 举报

24#
ID:759316 发表于 2020-5-23 18:03 | 只看该作者
这里的分频期间我认为可以设计成50分频,可以更好地利用资源
回复

使用道具 举报

25#
ID:739368 发表于 2020-6-13 15:16 | 只看该作者
很实用的资料,棒棒哒!!!
回复

使用道具 举报

26#
ID:302325 发表于 2020-6-17 09:03 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

27#
ID:774633 发表于 2020-6-18 08:37 | 只看该作者
正想学习这方面,谢谢分享
回复

使用道具 举报

28#
ID:628703 发表于 2020-7-2 22:14 | 只看该作者
超好的东西,收藏慢慢学!
回复

使用道具 举报

29#
ID:517951 发表于 2020-11-15 17:32 | 只看该作者
不错,值得学习。51hei有你更精彩!!
回复

使用道具 举报

30#
ID:362333 发表于 2021-1-26 14:31 来自手机 | 只看该作者
很不错,收藏了
回复

使用道具 举报

31#
ID:691287 发表于 2021-3-9 07:18 | 只看该作者
不错不错,正好想学习一下频率计。
回复

使用道具 举报

32#
ID:1067504 发表于 2023-7-4 11:56 来自手机 | 只看该作者
能不能测试晶振频率?
回复

使用道具 举报

33#
ID:149799 发表于 2023-7-27 08:46 | 只看该作者
能不能测试晶振频率?如果不超测量上限,应该能测试晶振频率。
回复

使用道具 举报

34#
ID:1067504 发表于 2023-11-27 19:26 来自手机 | 只看该作者
防制了一个,感觉有点误差,不知道什么原因,有谁做成功的分享一下经验
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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