新闻  |   论坛  |   博客  |   在线研讨会
频率计
0750long | 2009-04-11 09:23:46    阅读:1556   发布文章

频率计

 

zip简单频率计

用LCD1602显示

/*--------------------------------------------------------------*/
//简单频率计
//单片机: STC89C52RC
//时钟模式: 6T/双倍数
//晶振:  24MHz
//最高频率: 1.9MHz
//最大误差: 1Hz
//由于误差成线性,所以采用软件处理提高精度
//采用74HC393分频后,可以测量最高频率40MHz左右,最大误差为32Hz
//数据选择用74HC151

 

 

/*--------------------------------------------------------------*/
#include <at89x52.h>
#include "LCD1602_8A.H"
sbit Key = P1^3; //按键
sfr  sel = 0x80;

/*--------------------------------------------------------------*/
unsigned char dat[8];  //显示数据
unsigned char i, counter; //循环变量和计数变量
unsigned int  num;   //定时变量
unsigned long x, y;   //计算频率变量
unsigned char k_val;  //按键变量


/*--------------------------------------------------------------*/
//变量初始化
void counter_data_init(void)
{
 counter = 0;
 num = 0;
 for(i = 0; i < 8; i++) dat[i] = 0;
 i = 0;
}


/*--------------------------------------------------------------*/
//延时1.25s 函数定义
void delay1_25s(void)
{
 unsigned char i, j, k;
 for(i = 189; i > 0; i--)
 for(j = 68;  j > 0; j--)
 for(k = 193; k > 0; k--);
}


/*--------------------------------------------------------------*/
//延时5ms 函数定义
void delay5ms(void)
{
    unsigned char i, j;
    for(i = 215; i > 0; i--)
    for(j = 45; j > 0; j--);
}


/*--------------------------------------------------------------*/
//按键处理
void key_pro(void)
{
 if(Key == 0)
 {
  delay5ms();
  if(Key == 0)
  {
   k_val++;
   if(k_val > 5) k_val = 0;
   LCD_printc(15, 1, k_val+48);
  }
  while(Key == 0);
 }
 sel = k_val;
}


/*--------------------------------------------------------------*/
//计数定时器初始化
void ct_mode_init(void)
{
 TMOD = 0x25;    // T0计数,T1定时

 TH0 = 0x00;  TL0 = 0x00;
 TH1 = 0x06;  TL1 = 0x06;
 ET0 = 1;  ET1 = 1;
 EA  = 1;
 TR0 = 1;  TR1 = 1;
}


/*--------------------------------------------------------------*/
//主函数
void main(void)
{
 LCD_init();
 LCD_prints(2, 0, "System is");
 LCD_prints(0, 1, "Initializing...");
 delay1_25s();
 LCD_clr();
 LCD_prints(0,  0, "T:");
 LCD_prints(12, 0, "ns");
 LCD_prints(0,  1, "F:");
 LCD_prints(12, 1, "Hz");

 while(1)
 {
  counter_data_init();
  ct_mode_init();
  delay1_25s();    //延时1.25s,等待计数结束
  x = ((unsigned long)(counter) << 16) + TH0 * 256 + TL0; //计算频率f
  x <<= k_val;
  y = x;      //保存频率f
  
  while(x / 10)    //频率f拆位
  {
   dat[i] = x % 10;
   x /= 10;
   i++;
  }
  dat[i] = x;
  LCD_printd(4, 1, dat, 8); //显示频率f
  
  counter_data_init();  //数据初始化
  if(y == 0);
  else y = 1000000000 / y; //计算周期T
  while(y / 10)    //频率T拆位
  {
   dat[i] = y % 10;
   y /= 10;
   i++;
  }
  dat[i] = y;
  LCD_printd(4, 0, dat, 8); //显示周期T
  key_pro();
 }
}


/*--------------------------------------------------------------*/
//计数器T0中断服务程序
void T0_counter(void) interrupt 1 using 1
{
 counter++;
}


/*--------------------------------------------------------------*/
//定时器T1中断服务程序
void T1_timer(void) interrupt 3 using 3
{
 num++;
 if(num == 15598) {TH1 = 0x05;}  //软件处理
 if(num == 16000) {TR0 = 0; TR1 = 0;}
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客