找回密码
 立即注册

QQ登录

只需一步,快速开始

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

ARM7 LPC2138数字频率计的设计源码与报告

[复制链接]
跳转到指定楼层
楼主
ID:418561 发表于 2018-10-31 15:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
摘要
在当代电子设备中运用中,经常要测量一个波形的频率,然后对其进行分析研究。为了测量频率,就要用到频率计。在传统的电子测量仪器中,示波器在进行频率测量时测量精度较低,误差较大。频谱仪可以准确的测量频率并显示被测信号的频谱,但测量速度较慢,无法实时快速的跟踪捕捉到被测信号频率的变化。正是由于频率计能够快速准确的捕捉到被测信号频率的变化,因此,频率计拥有非常广泛的应用范围。 数字频率计的设计包括时基电路、整形电路、控制电路和计数显示电路四部分组成。 由时基电路产生一标准时间信号控制阀门,调节时基电路中的电阻可产生需要的标准时间信号。信号输入整形电路中,经过整形,输出一方波,通过阀门后,计时器对其计数。当计数完毕,时基电路输出一个上升沿,使锁存器打开,计数器计数结果输入译码器,从而让显示器显示,达到测量频率的目的。
目录
设计原理及方案选择
1.1、设计原理
1.2、方案选择
程序设计及原理图
2.1、原理图设计
2.2、程序设计
3、仿真结果
4、实物调试
  4.1、调试结果
4.2、调试中遇到的问题
5、设计小结
  • 设计原理及方案选择

1.1、设计原理

频率就是周期性信号在单位时间(1s)内变化的次数。若在一定时间间隔T内测得这个周期性信号的重复变化次数为N,则其频率可表示为f=N/T。其中f为被测信号的频率,N为计数器所累计的脉冲个数,T为N个脉冲所产生的时间。计数器所记录的结果就是被测信号的频率计数法又称测频法,是将被测信号通过一个定时闸门加到计数器进行计数的方法,如果闸门打开的时间为T,计数器得到的计数值为N1,则被测频率为f=N1/T。改变时间T,则可改变测量频率范围。设在T期间,计数器的精确计数值应为N,根据计数器的计数特性可知,N1的绝对误差是N1=N+1,N1的相对误差为ΔN1=(N1-N)/N=1/N。由N1的相对误差可知,N的数值愈大,相对误差愈小,成反比关系。因此,在f以确定的条件下,为减少N的相对误差,可通过增大T的方法来降低测量误差。当T为某确定值时(通常取1s),则有f1=N1,而f=N,故有f1的相对误差:Δf1=(f1-f)/f=1/f 从上式可知f1的相对误差f成反比关系,即信号频率越高,误差越小;而信号频率越低,则测量误差越大。因此测频法适合用于对高频信号的测量,频率越高,测量精度也越高。

1.2、方案选择

计时法又称为测周期法,测周期法使用被测信号来控制闸门的开闭,而将标准时基脉冲通过闸门加到计数器,闸门在外信号的一个周期内打开,这样计数器得到的计数值就是标准时基脉冲外信号的周期值,然后求周期值的倒数,就得到所测频率值。但由于用计时法所获得的信号周期数据,还需要求倒数运算才能得到信号频率,而求倒数运算用中小规模数字集成电路较难实现,因此,计时法不适合本实验要求。

计数法则适合于对较高频信号的测量。测频法的测量误差与信号频率成反比,信号频率越低,测量误差就越大,信号频率越高,其误差就越小。但用测频法所获得的测量数据,在闸门时间为一秒时,不需要进行任何换算,计数器所计数据就是信号频率。根据本设计要求的性能与技术指标,首先需要确定能满足这些指标的频率测量方法。因此,本实验所用的频率测量方法是测频法。


图1.1原理框图及其波形图


2.1原理图设计

图2.1 proteus电路图

2.2 程序设计

图2.2 程序流程图

3、仿真结果

  利用proteus和Keil软件,将程序编译正确后,并且生成HEX文件,然后用protest仿真。修改发射频率,观察结果。



图3.1仿真结果

4、实物调试

4.1调试结果

当信号发射器输入的频率为2kHz方波时,LCD显示屏显示也为2k,发射频率为3kHz时,显示屏显示3k,由此可得,实物实现了功能,并且达到了相应的精度。


4.1实物调试

4.2调试中遇到的问题

由于我们需要将编译好的程序烧录进入我们的板子,所以当时不是很清楚烧录程序的用法,所以开始出现LCD没有任何显示,我们一直以为是板子和显示屏的问题,所以浪费了很多时间。后来在了解清楚程序的使用方法后,我们成功的烧录进去了程序,然后连接好我们之前焊接好的局部程序电路板,实行调试,取得了最后的成功。


5、设计总结

本次设计让我体会到设计程序,连接原理图,调试的苦与甜,设计是我们必须得技能,而这次实习恰恰给了我们一个很好的实际操作的机会,从图书馆找资料设计程序、连接原理图,在这个过程中我学到了很多新的知识,并且对keil和proteus的应用更加的娴熟,感受到了这些软件的强大功能,当调试成功的时候感觉很神奇,很不可思议,同时更加深了我对这些知识的印象。

在设计过程中,因为我们设置定时器为计数模式。所以最高计数频率为时钟频率(44.2368MHz)的1/4(11.0592MHz),但是我们又100分频了的,所以最终只能测得110kHz。由于显示器的问题,前面固定字符已经占了很多位,所以只能到9999Hz。

在设计过程中,不能急躁,设计和调试要一步一步来,这次在设计过程中,由于刚开始对LPC2138的管脚功能不熟,设计过程中老是混淆,经过查资料认真学习才辨别清楚,特别是程序修改的时候,一定不能马虎,一个字母不对都编译失败,在最后的调试过程中,因为仿真结果已经准确无误,所以调试不出结果让人特别心急,还耽搁了了时间,建议能多一些好的开发板,若不是因为开发板和显示器有问题,也许我们的进度能更快一些。


LPC2138源程序:
  1. #include"LPC213x.h"
  2. #define uint unsigned int
  3. #define uchar  unsigned char
  4. int g_sample_cnt;
  5. #define RS              1<<5
  6. #define RW              1<<6
  7. #define EN               1<<7
  8. #define KEY_MC    (1<<31)
  9. #define KEY_RST    (1<<30)
  10. #define KEY_NIGHT    (1<<29)
  11. uchar num,i;
  12. uchar  table1[]={"frequency:    hz      "};
  13. uchar  table2[]={"                      "};
  14. uint HZ[]={                   0x08,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x00,           0x0F,0x09,0x0F,0x09,0x0F,0x09,0x11,0x00,              
  15. 0x0F,0x09,0x09,0x0F,0x09,0x09,0x0F,0x00};            
  16. void DelayNs(uint NS)
  17. {  uint i;
  18.    for(;NS>0;NS--)   
  19.    for(i=0;i<500;i++);
  20. }
  21. void writecom(uint com)
  22. {
  23.   IO0CLR=RS;
  24.   IO0PIN=(IO0PIN&0X00FF)+(com<<8);   
  25.   DelayNs(1);
  26.   IO0SET=EN;
  27.   IO0CLR=EN;
  28. }
  29. void writedata( uint data)
  30. {
  31.   IO0SET=RS;
  32.   IO0PIN=(IO0PIN&0X00FF)+(data<<8);     //P0=data;
  33.   DelayNs(1);
  34.   IO0SET=EN;
  35.   IO0CLR=EN;
  36. }
  37. void init()
  38. {
  39.    PINSEL0=0X00000000;
  40.    IO0DIR =0XFFFF;
  41. IO0CLR=RW;
  42.    IO0CLR=EN;
  43.    writecom(0x38);
  44.    writecom(0x0c);
  45.    writecom(0x06);
  46.    writecom(0x01);
  47. }
  48. int mile=0,premile=0;
  49. int night=0;
  50. int lowmode=0;
  51. int price=0;
  52. int lowmodefirsttime=0;
  53. int price_low=0;
  54. static int lowmodetime=0;
  55. void __irq IRQ_Timr0(void)
  56. {

  57.               table1[10]=g_sample_cnt/1000%10+'0';              table1[11]=g_sample_cnt/100%10+'0';
  58. table1[12]=g_sample_cnt/10%10+'0';
  59.               table1[13]=g_sample_cnt%10+'0';
  60.               writecom(0x80);
  61.               for(num=0;num<21;num++)
  62.               {
  63.                             writedata(table1[num]);
  64.                             DelayNs(1);
  65.               }
  66.               writecom(0x80+0x40);
  67.               for(num=0;num<21;num++)
  68.               {
  69.                             writedata(table2[num]);
  70.               }
  71.     g_sample_cnt=0;
  72.               T0IR = 0x01;   
  73.               VICVectAddr = 0x00;  
  74. }

  75. /**********************************************************
  76. void Timer0Init(void)
  77. {
  78.               //Fcclk = Fosc*4 = 11.0592MHz*4 = 44.2368MHz
  79.               //Fpclk = Fcclk/4 = 44.2368MHz/4 = 11.0592MHz
  80.               T0PR = 99;                                                  // 设置定时器0分频为100分频,得110592Hz
  81.               T0MCR = 0x03;                                                           // 匹配通道0匹配中断并复位T0TC
  82.               T0MR0 = 150350;                                              // 比较值(1S定时值)
  83.               T0TCR = 0x03;                                                           // 启动并复位T0TC
  84.               T0TCR = 0x01;
  85. VICIntSelect = 0x00;  
  86.               VICVectCntl0 = 0x20|4;
  87.               VICVectAddr0 = (unsigned long)IRQ_Timr0;
  88.               VICIntEnable = 1<<4;      
  89. }
  90. void main()
  91. {
  92.   init();
  93.   writecom(0x80);
  94.   DelayNs(100);
  95.   Timer0Init();
  96.   for(num=0;num<19;num++)
  97.   {
  98.                 writedata(table1[num]);
  99.               DelayNs(1);
  100.   }
  101.   //writecom(0x40);
  102. // for(num=0;num<24;num++)
  103. // {
  104. //   writedata(HZ[num]);
  105. // }
  106.   writecom(0x80+0x40);
  107.   for(num=0;num<19;num++)
  108.   {
  109.                 writedata(table2[num]);
  110.   }

  111.                 PINSEL1 &=0x00ffffff;
  112.               //IODIR  =0xe83fffff;
  113.               IO1DIR  |=0xff000000;
  114.   //writedata(0x00);
  115.   //writedata('4');
  116.   //writedata(0x01);
  117.   //writedata('2');
  118.   //writedata('6');
  119.   //writedata(0x02);
  120.               IO1DIR&=~KEY_MC;
  121.               IO1DIR&=~KEY_RST;
  122.               IO1DIR&=~KEY_NIGHT;
  123.               mile=325400;
  124.               lowmodetime=lowmodefirsttime=price=premile=mile=0;
  125.                 while(1)
  126.                 {
  127.                             #if 1
  128.                             if((IO1PIN&KEY_MC)==0)
  129.                             {
  130.                                           g_sample_cnt+=1;
  131.                                           //DelayNs(1);
  132.                                           while((IO1PIN&KEY_MC)==0);
  133.                             }
  134.                             #endif
  135.                 }

  136. }
复制代码

完整的Word格式文档51黑下载地址:
简易数字频率计的设计.docx (498.7 KB, 下载次数: 55)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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