1. 求51单片机设计数字频率计,附带Proteus仿真和程序
刚刚下了一楼传的附件,测试后发现精度和测量范围都比较差。如果单从测频的角度来说,51的频率计是很简单的。恰好几年前我写过类似的程序,是用来测频率和占空比的。
理论上单用C52这单片机测频率最高为:12M/12/2=500KHZ。我写的这个程序可以同时测频率和脉宽,仿真下大概可以测到350KHZ;测脉宽好像10KHZ左右,再高的话脉宽的精度就会下降。测频精度在100KHZ以内,基本是2HZ;200K是5HZ;350KHZ以内是10HZ;最低测量频率1HZ。
仿真比较慢,数据要3秒后才会稳定,有兴趣的话自测吧。
50KHZ测量
2. 51单片机制作简易数字频率计程序
这里有一个四位数码管的频率计,供参考
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码
//ucharwei[4]={0XEf,0XDf,0XBf,0X7f};//位的控制端 (开发板)
ucharwei[4]={0X80,0X40,0X20,0X10};//位的控制端 (仿真)
uintz,x,c,v,date; //定义数据类型
uintdispcount=0;
uintlck=0;
uintdisp=0;
/******************************************************************
延时函数
******************************************************************/
voiddelay(uchart)
{
uchari,j;
for(i=0;i<t;i++)
{
for(j=13;j>0;j--);
{;
}
}
}
/**********************************************************************
数码管动态扫描
*********************************************************************/
voidxianshi()
{
/*****************数据转换*****************************/
z=date/1000; //求千位
x=date%1000/100; //求百位
c=date%100/10; //求十位
v=date%10; //求个位
P2=wei[0];
P0=an[z];
delay(50);
P2=wei[1];
P0=an[x];
delay(50);
P2=wei[2];
P0=an[c];
delay(50);
P2=wei[3];
P0=an[v];
delay(50);
}
/*************************************************************************
定时器初值1ms
**************************************************************************/
voidinitTimer(void)
{
TMOD=0x0;
TH0=0xe3;
TL0=0xc;
}
/*************************************************************************
定时器函数
**************************************************************************/
voidtimer0(void)interrupt1
{
TH0=0xe3;
TL0=0xc;
lck++;
if(lck==1000)
{
disp=dispcount;
lck=0;
dispcount=0;
}
}
/*************************************************************************
中断函数
**************************************************************************/
voidint0(void)interrupt0
{
dispcount++;//每一次中断,计数加一
}
/*************************************************************************
主函数
**************************************************************************/
voidmain(void)
{
IT0=1;//INT0下降沿中断
EX0=1;//允许INT1中断
initTimer();//装入初值
TR0=1;
ET0=1;
EA=1;
while(1)
{
date=disp;
xianshi();
}
}
3. 51单片机的数字频率计
本应用系统设计的目的是通过在“单片机原理及应用”课堂上学习的知识,以及查阅资料,培养一种自学的能力。并且引导一种创新的思维,把学到的知识应用到日常生活当中。在设计的过程中,不断的学习,思考和同学间的相互讨论,运用科学的分析问题的方法解决遇到的困难,掌握单片机系统一般的开发流程,学会对常见问题的处理方法,积累设计系统的经验,充分发挥教学与实践的结合。全能提高个人系统开发的综合能力,开拓了思维,为今后能在相应工作岗位上的工作打下了坚实的基础。
1.1数字频率计概述
数字频率计是计算机、通讯设备、音频视频等科研生产领域不可缺少的测量仪器。它是一种用十进制数字显示被测信号频率的数字测量仪器。它的基本功能是测量正弦信号,方波信号及其他各种单位时间内变化的物理量。在进行模拟、数字电路的设计、安装、调试过程中,由于其使用十进制数显示,测量迅速,精确度高,显示直观,经常要用到频率计。
本数字频率计将采用定时、计数的方法测量频率,采用一个1602A LCD显示器动态显示6位数。测量范围从1Hz—10kHz的正弦波、方波、三角波,时基宽度为1us,10us,100us,1ms。用单片机实现自动测量功能。
基本设计原理是直接用十进制数字显示被测信号频率的一种测量装置。它以测量周期的方法对正弦波、方波、三角波的频率进行自动的测量。
点击重新加载
1.2频率测量仪的设计思路与频率的计算
图1 频率测量原理图
频率测量仪的设计思路主要是:对信号分频,测量一个或几个被测量信号周期中已知标准频率信号的周期个数,进而测量出该信号频率的大小,其原理如右图1所示。
若被测量信号的周期为,分频数m1,分频后信号的周期为T,则:T=m1Tx 。由图可知: T=NTo
(注:To为标准信号的周期,所以T为分频后信号的周期,则可以算出被测量信号的频率f。)
由于单片机系统的标准频率比较稳定,而是系统标准信号频率的误差,通常情况下很小;而系统的量化误差小于1,所以由式T=NTo可知,频率测量的误差主要取决于N值的大小,N值越大,误差越小,测量的精度越高。
1.3 基本设计原理
基本设计原理是直接用十进制数字显示被测信号频率的一种测量装置。它以测量周期的方法对正弦波、方波、三角波的频率进行自动的测量。
所谓“频率”,就是周期性信号在单位时间(1s)内
4. 51单片机用定时器计数器测量频率
定时器1对外部脉冲计数时TMOD高4位设置应该是5
因此TMOD=0x51;
以下我的频率计程序:
#include <reg52.h>//因没用到STC12C5410专有特殊功能寄存器,此处用52或51的头文件均可
#define unit unsigned int
#define uchar unsigned char
//定义以I/O口的功能
sbit beiguang=P3^2;//液晶屏背光
sbit rs=P1^3;//液晶屏写选择,0命令 1数据
sbit rw=P1^4;//液晶屏读写选择
sbit lcden=P1^5;//液晶屏使能
sbit fm=P1^7;//蜂鸣器
#define db P2 //定义P2为数据输出口,写数据时用db代替P2,增加液晶屏程序的通用性
//更改硬件接线时,只更改此处,而不必去更改液晶屏读写子程序
uchar aa,bb,cc;//变量声明
unit dd,ee;
void Delay1ms(unsigned int i) //1ms延时程序
{
unsigned int j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void init()//初始化设置
{
TMOD=0x15;//定时器0作为计数器,定时器1作为定时器用
TH0=0;//计数器清0
TL0=0;
EA=1;//开总中断
ET1=1;//允许定时器1中断
TH1=0x4c;
TL1=0x5c;
TR0=1;//启动计数器
TR1=1;//启动定时器
aa=0;
}
void write_com(uchar com)//向液晶屏写命令
{
db=com;
rs=0;
rw = 0;
lcden=0;
Delay1ms(10*12);
lcden=1;
Delay1ms(10*12);
lcden=0;
}
void write_date(uchar date)//向液晶屏写数据
{
db=date;
rs=1;
rw = 0;
lcden=0;
Delay1ms(10*12);
lcden=1;
Delay1ms(10*12);
lcden=0;
}
void init2()//液晶屏初始化
{
beiguang=0;
rw=0;
write_com(0x38);
Delay1ms(10*12);
write_com(0x0f);
Delay1ms(10*12);
write_com(0x06);
Delay1ms(10*12);
write_com(0x01);
Delay1ms(10*12);
}
void display4(unsigned int number) //单行多位显示程序
{
uchar A1,A2,A3,A4,A5;
init2();//液晶屏初始化
A1=number/10000%10;//分离出万,千,百,十,个,对于int型数据,最大不超过65535
A2=number/1000%10;
A3=number/100%10;
A4=number/10%10;
A5=number%10;
write_com(0x80);//第1个数据的位置设定,第1行第1列
Delay1ms(10);
write_date(0x30+A1);//写数据
Delay1ms(10);
write_date(0x30+A2);
Delay1ms(10);
write_date(0x30+A3);
Delay1ms(10);
write_date(0x30+A4);
Delay1ms(10);
write_date(0x30+A5);
Delay1ms(10);
write_com(0x87);//第6个数据'H'的位置,中间空85和86 二格
write_date('H');
Delay1ms(10);
write_date('z');
Delay1ms(10);
}
void main()//主程序很简单
{
init();//初始化
while(1)//循环程序
{
dd=bb*256+cc;//0.5S的计数值
ee=2*dd;//换算为1秒钟的计数值
if(aa==1)
{
if(TH0>12)//预判断,50ms内TH0>12,1s内计数值将超过可计数的最大值65535
fm=0;//报警
}
display4(ee);//显示
fm=1;//报警停止
}
}
void timer1()interrupt 3//注意:定时器1的中断序号为3
{
aa++;
TH1=0x4c;//11.0592Mhz
TL1=0x5c;
if(aa==10)//中断10次,共0.5S
{
TR0=0;//暂停计数
aa=0;
bb=TH0;//读出计数器数据
cc=TL0;
TL0=0;//计数器清0
TH0=0;
TR0=1;//重新启动
}
}
5. 基于51单片机的数字频率计毕业论文
第1节引言2
1.1数字频率计概述2
1.2频率测量仪的设计思路与频率的计算2
1.3基本设计原理3
第2节数字频率计(低频)的硬件结构设计4
2.1系统硬件的构成4
2.2系统工作原理图4
2.3AT89C51单片机及其引脚说明5
2.4信号调理及放大整形模块7
2.5时基信号产生电路7
2.6显示模块8
第3节软件设计12
3.1定时计数12
3.2量程转换12
3.3BCD转换12
3.4LCD显示15
第4节结束语16
参考文献20
附录汇编源程序代码28
6. 单片机频率计
1.实验任务
利用51单片机的T0、T1的定时计数器功能,来完成对输入的信号进行频率计数,计数的频率结果通过8位动态数码管显示出来。要求能够对0-250KHZ的信号频率进行准确计数,计数误差不超过±1HZ。
2.电路原理图
见插图
3.程序设计内容
(1).定时/计数器T0和T1的工作方式设置,由图可知,T0是工作在计数状态下,对输入的频率信号进行计数,但对工作在计数状态下的T0,最大计数值为fOSC/24,由于fOSC=12MHz,因此:T0的最大计数频率为250KHz。对于频率的概念就是在一秒只数脉冲的个数,即为频率值。所以T1工作在定时状态下,每定时1秒中到,就停止T0的计数,而从T0的计数单元中读取计数的数值,然后进行数据处理。送到数码管显示出来。
(2).T1工作在定时状态下,最大定时时间为65ms,达不到1秒的定时,所以采用定时50ms,共定时20次,即可完成1秒的定时功能。
4.C语言源程序
/******************************************************************************
*定时器+计数器测频
*
*file:frequency.c
*name:zhzhchang
*time:2010.3.17
*V1.0
*blog:http://blog.csdn.net/zhzht19861011
*Nots:本程序定义6个数码管,经过实测,在200HZ~50KHZ时结果较准确,误差小于0.4%,
*50KHZ以上频率未进行测量.据资料表明,可以测量到120KHZ,本程序未证明.
*********************************************************************************/
#include<reg52.h>
bitint_flag;//定时器01S到标志位
unsignedcharvolatileint_count;//定时器0中断次数
unsignedcharvolatileT1count;//定时器1中断次数
unsignedcharcodedofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码值0123456789
unsignedlongsum;//1S内脉冲总个数
unsignedcharled[6];//LED显示缓存
///////////////软件延时/////////////
voiddelay(unsignedintcnt)
{
while(--cnt);
}
///定时器0初始化
voidinit_t0(void)
{
TMOD=(TMOD&0xF0)||0x01;//定时器0工作于方式1
TH0=(65536-50000)/256;//定时50ms
TL0=(65535-50000)%256;
}
//定时器1初始化
voidinit_t1(void)
{
TMOD=(TMOD&0x0F)|0x50;//timer1forcount
TH1=0x00;
TL1=0x00;
}
//显示
voiddisp(void)
{
unsignedchari;
for(i=0;i<6;i++)
{
P0=dofly[(led[i])];//取显示数据
P2=5-i;//取段码
delay(100);//扫描间隙延时,根据单片机调整,延时1ms即可
}
}
///////////////////////////////////////////////////////
voidmain(void)
{
EA=1;//开总中断
init_t0();//初始化定时器
init_t1();
TR0=1;//定时器开始工作
TR1=1;
ET0=1;//开T0中断
while(1)
{
if(int_flag==1)
{
int_flag=0;
sum=TL1+TH1*256+T1count*65536;//计算1秒内的脉冲个数
//以下将数据格式化,转成LED可显示的BCD码
led[0]=sum%10;//最低位
sum=sum/10;
led[1]=sum%10;//第二位
sum=sum/10;
led[2]=sum%10;
sum=sum/10;
led[3]=sum%10;
sum=sum/10;
led[4]=sum%10;
led[5]=sum/10;
int_count=0x00;
T1count=0;
TH1=0x00;
TL1=0x00;
TR1=1;
}
disp();
}
}
//定时器0中断服务程序
voidint_t0(void)interrupt1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
int_count++;
if(int_count==20)
{
TR1=0;
int_flag=1;
int_count=0x00;
}
}
//定时器1中断服务程序
voidint_t1(void)interrupt3
{
T1count++;
}
别说你的设计要求用汇编啊!!!
不过既然是课程设计,我这个只是给你参考,你自己一定要弄懂,变成自己的。我实测过,程序没问题,但用到你的硬件上可能需要改一下,因为你的硬件数码管不一定和我的硬件接法一样,但整体思路我都给你了。
7. 我用C51单片机做简易数字频率计,测量脉宽2K以内是差不多的,但是超过2K就各种不对了,这是测量脉
你用的是什么单片机?主频是多少?看你的寄存器应该是51。
别忘了,51单片机的主频12MHz,为了抗干扰,还要12分频。
也就是说,你只有1MHz的运算频率。然后你得到你的w,还要做那么复杂的灶衡运算,本身while(p3_5==0)的判凳轮断也要时间。
还有,你的n1,n2是什么类型的呀。你用的是n1=w*65536我就觉得,它至少是个32位的整型变量。我的老天,51的内核只有8位,它要做许许多多额外的运算才能给你拼合出32位变量。
还有你调用函数的各种开销,一旦你的所有时间开销大于500个周期,你就会错过脉宽。
总之,还得看你的目标频率范围是多大吧。任何仪器都有一个频率上限,超过频率上限的就测不了了。如果在2K以内,你就忍了。超过2K,建议你换平台。
8位系统建议你换AVR或者PIC,首先,这两个是RISC结构,拿AVR来说,单周期指令,不需要12分频,16~20Mhz的主频也比51的高。最关键的还有硬件捕捉等功隐粗做能,测量脉宽之类的操作可以靠硬件实现,软件只需要简单处理就可以了。
系统要求再高,可以考虑CORTEX M0系列的32位单片机。主频最高到72MHz,本身累加器是32位的,像你这种32位乘法一个周期就可以完成。也有各种硬件帮你测量脉宽。
8. 做用51单片机做一个频率计,测量范围为0.1Hz~10kHz
在不改变定时时间的前提下,也就是0.5秒定时,是不能实现0.1~2Hz频率的测量的。
你所谓2Hz~10KHz易实现也是基于这个道理。但这个也是理论情况。
当你0.5s内刚好检测到一个脉冲,你认为这个时候是2Hz而不是2.5hz或者3.9hz?
这中间存在一个测量精度的问题。实际上你所测到的信号是在2hz到4hz之间。
实际上我们在测量信号的时候,低频一般会采用测周期,高频用测频才能提高测量的准确性。
至于高低频的临界点,跟你的计数频率有关,感兴趣的话可以去看《电子测量原理》。
下面我来讲下测周实现的方法,可以使用边沿触发的D触发器输出作为单片机的外部定时控制,测量信号作为触发时钟,计数值作为该信号的周期。
9. 关于51单片机简易频率计的问题
该课程设计偏离了实际应用。
一般来说,单片机通过计数器实现频率测量。测量方波外围电路简单,测量正弦波需要外部调理电路,但是,既然能够做到测量正弦波了,方波更没问题了。人为分为两种模式,从使用上讲,不方便,从技术上讲,更是多此一举。
10. 基于51单片机的数字频率计(0—10MHZ)
再加两个数码管,用T1引脚检测频率,打开T1中断,每中断一次加1计数,
满1秒中后停止T1计数,读出T1计数器的TH1 TL1,
频率= 65536x中断次数+TH1 HL1。
前提是选择高速单片机,即只要T1引脚能够响应10M的频率就没有问题
因为要计数65536次才T1才会中断一次。