stc89c2单片机测频

  今天做了一下51单片机的测频法(给定一定的门限时间,来测频率个数),我的大体思路是用两个中断来控制,通过定时器0,来给定一个1s的门限时间,把待测信号输入到外部中断INT0(P3^2),然后通过外部中断进入的个数来确定信号的频率,即记的个数就是待测信号的脉冲。现在我把我的程序贴出来给大家参考一下

/*================================
 程序名称 :测频
 编者     :xxniuren
 日期     :2012 11
 程序目的 :用两个时钟来定时,第一个时钟是
 外部中断INT0 第二个时钟是产生一个一秒的门信号
===============================*/
#include
#include
#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
#include
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单片机测频)