概述
今天做了一下51单片机的测频法(给定一定的门限时间,来测频率个数),我的大体思路是用两个中断来控制,通过定时器0,来给定一个1s的门限时间,把待测信号输入到外部中断INT0(P3^2),然后通过外部中断进入的个数来确定信号的频率,即记的个数就是待测信号的脉冲。现在我把我的程序贴出来给大家参考一下
/*================================
程序名称 :测频
编者 :xxniuren
日期 :2012 11
程序目的 :用两个时钟来定时,第一个时钟是
外部中断INT0 第二个时钟是产生一个一秒的门信号
===============================*/
#include <reg52.h>
#include <lcd.h>
#define uchar unsigned char
#define uint unsigned int
uchar num,flag1,flag2;
long int count1,count2;
uint zhao,s_wan,wan,qian,bai,shi,ge;
uchar code table[] = "Pinlv";
//****************显示pinlv****************
void display()
{
write_com(0x80);
for(num = 0; num < 5; num++)
{
write_date(table[num]);
delay_1602(5);
}
//****************显示数字****************
}
void display_date(long int date)
{
zhao = date / 1000000;
s_wan = (date % 1000000) / 100000;
wan = (date % 100000) / 10000;
qian = (date % 10000) / 1000;
bai = (date % 1000) / 100;
shi = (date % 100) / 10;
ge = date % 10;
write_com(0xc0 + 3) ;
write_date(zhao + '0');
delay_1602(5);
write_date(s_wan + '0');
delay_1602(5);
write_date(wan + '0');
delay_1602(5);
write_date(qian + '0');
delay_1602(5);
write_date(bai + '0');
delay_1602(5);
write_date(shi + '0');
delay_1602(5);
write_date(ge + '0');
delay_1602(5);
write_date('H');
delay_1602(5);
write_date('z');
delay_1602(5);
}
/************
初始化外部中断
************/
void INT0_init(void)
{
EA = 1; // 打开全局中断
EX0 = 1; //打开外部中断0
IT0 = 1; //外部中断0触发 下降沿触发
}
/************
初始化定时器
************/
void timer0_init(void)
{
TMOD = 0x01;
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void main()
{
init_lcd();
display();
timer0_init();//先开门限时间中断
INT0_init(); //后开外部触发中断
while(1)
{
display_date(count2);
}
}
void T0_time() interrupt 1
{
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
num++;
if(num == 20)
{
num = 0;
flag1 = 1;
}
}
void INTRPT0()interrupt 0
{
count1++;
{
if(flag1 == 1)
{
count2 = count1;
flag1 = 0;
count1 = 0;
}
}
}
这个程序相对来说容易实现,但是测频相对来说不是太准,我测的时候100hz,显示的是92hz,20khz测出来是18360hz,所以不是很准,我后来想增加测量的周期数来提高程序的精度,但是效果不是很明显。所以还是有待改善
下面把我的1602的程序也贴出来,大家可以直接拿着试一下(注意下管脚)。如果有什么好的提高频率精度的方法 希望大家指点一下,然后相互进步。。。
/*==============================================
程序名称:lcd
编者:xxniuren
日期:2012 8
程序目的:生成一个lcd的头文件 方便调用。其中程序调用方法是
初始化--定义光标坐标--使用
===============================================*/
#include <reg52.h>
#include <lcd.h>
void delay_1602(uint xms)
{
uint i,j;
for (i = xms; i > 0; i--)
for(j = 110; j > 0; j--) ;
}
void write_com(uchar com)
{
lcdrs= 0; //先把写命令和数据设定为写命令按钮 0位命令 1为数据 0为写 1为读
lcd_data = com; //给P0一个数据
delay_1602(5); //延时5ms
lcden = 1; //给使能一个高电平
delay_1602(5); //延时5ms
lcden = 0; //给一个低脉冲 从而把数据传上去
}
void write_date(uchar date)
{
lcdrs = 1;//写入数据选择
lcd_data = date;
delay_1602(5);
lcden = 1;//打开使能端
delay_1602(5);
lcden = 0;//给一个脉冲从而输入数据
}
void init_lcd()
{
lcden = 0;
lcdrw = 0;
write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口
write_com(0x0c);//设置开显示 不显示光标
// write_com(0x06);//写一个数据后地址指针加一
write_com(0x01);//显示清零,数据指针清零
}
//lcd 1602 .h
#ifndef __lcd_H__
#define __lcd_H__
#define uchar unsigned char
#define uint unsigned int
#define lcd_data P0
sbit lcden = P1^2; //使能
sbit lcdrs = P1^0; //数据命令选择引脚
sbit lcdrw = P1^1; //读写选择引脚
void delay_1602(uint xms);
void write_com(uchar com);
void write_date(uchar date);
void init_lcd();
#endif
最后
以上就是阳光雪糕为你收集整理的stc89c2单片机测频的全部内容,希望文章能够帮你解决stc89c2单片机测频所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复