⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fm.c

📁 频率计的 电路图及 源程序
💻 C
字号:
#include "reg51.h"
#include "stdio.h"
#include " absacc.h "
#include <intrins.h>
#include <math.h>


/********************************************************************/
void delay_nms(unsigned int n);//delay function

sbit F_in=P3^6;  //测量频率管脚
sbit F_out=P3^7; //发生频率管脚

bit int_flag;
unsigned int frequency;

void Display(void);
void Mcu_init(void);
void Measure_F(void);
void Measure_T(void);
void Frequency_Measure(void);


/***********************************************************************/     

/********************/
sbit  RCLK = P2^5;
sbit  SCLK = P2^6;
sbit  SDAT = P2^7;

sbit  A_SEL = P2^2;
sbit  B_SEL = P2^3;
sbit  C_SEL = P2^4;

#define		SM0		A_SEL = 0;	B_SEL = 0;	C_SEL = 0
#define		SM1		A_SEL = 1;	B_SEL = 0;	C_SEL = 0
#define		SM2		A_SEL = 0;	B_SEL = 1;	C_SEL = 0
#define		SM3		A_SEL = 1;	B_SEL = 1;	C_SEL = 0
#define		SM4		A_SEL = 0;	B_SEL = 0;	C_SEL = 1
#define		SM5		A_SEL = 1;	B_SEL = 0;	C_SEL = 1
#define		SM6		A_SEL = 0;	B_SEL = 1;	C_SEL = 1
#define		SM7		A_SEL = 1;	B_SEL = 1;	C_SEL = 1

unsigned char leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };

void send(unsigned char data_out)
{
	unsigned char i;
	RCLK = 0;
	
	for(i=0;i<8;i++)
	{
		if( data_out & 0x80)
			SDAT = 1;
		else
			SDAT = 0;
		SCLK = 0;
		
		SCLK = 1;
		
		data_out =  data_out<<1;	  
	}
	RCLK = 1;
}

#define		delay		450



/***********************************************************************/
void dis_delay(void);
void display(unsigned int temp);
/***********************************************************************/

void display(unsigned int temp) 
{   
	unsigned int i;

	//send(0x00);

	SM6;
 	send(0x40);
 	for(i = 0; i < delay; i++);
	send(0x00);
	 
	SM7;
	if(frequency<2000)
 		send(0x39);
	else
		send(0x71);
 	for(i = 0; i < delay; i++);
	send(0x00);
	
	SM0;
 	send(leddata[temp/1000%10]);
 	for(i = 0; i < delay; i++);
	send(0x00);

	SM1;
 	send(leddata[temp/100%10]);
 	for(i = 0; i < delay; i++);
	send(0x00);

	SM2;
 	send(leddata[temp/10%10]);
 	for(i = 0; i < delay; i++);
	send(0x00);

	SM3;
 	send(leddata[temp%10]);
 	for(i = 0; i < delay; i++);
	send(0x00);


}
 
void main()
{ 
 Mcu_init();   //初始化
  
 while(1)    
 {
 unsigned int i;  
 Frequency_Measure();
 
 
 for(i=100;i>0;i--)
    display(frequency);
 }
}

void time0(void)  interrupt 1 
{
 int_flag=1; //计数溢出标志
}

void time1(void)  interrupt 3 
{
 TH1=0xfe; //重新附值
 TL1=0x33;
 F_out=!F_out; //取反 产生频率
}

void Frequency_Measure(void)   
{
 if(frequency<2000)   //小于 2k 测周
  Measure_T();
 else if(frequency>=2000) //大于2k 测频
  Measure_F();
}

//测频原理:
//开一个标准的50ms计数闸门,对被测信号计数
void Measure_F(void)  //测频子函数
{
 bit state_old=0,state_new=0; //定义状态
 unsigned int f_count=0;   //计数临时值
 int_flag=0;
 TH0=0x4c; //定时器初值 50ms
 TL0=0x00;
 TR0=1;  //启动计数器
 while(1)  //死循环 测频
 {
  state_new=F_in; //取得现在的 频率发生引脚状态
  if(state_old!=state_new) //与前一个时刻 旧值 比较,如果不同
   f_count++;  //则 计数加1
  state_old=state_new; //将新值 付给 旧值
  if(int_flag)  //如果到了定时时间
  { 
   TR0=0;  //关闭定时器0 
   frequency=f_count*10; //计算频率
      //定时 50ms计数 每个周期 计2次 所以 1s内计数= f_count*10
   return;  //返回 跳出循环
  }
 }
}

//原理:以被测信号的一个周期为闸门
//对单片机及其周期进行计数 读取定时器的值为计数值
void Measure_T(void) //测周子函数
{ 
 bit state_old=0,state_new=0; //定义状态
 unsigned char temp_flag=0;
 unsigned int t_count;   //计数临时值
 
 TH0=0;
 TL0=0;
    while(1) //死循环 测周
    {
      state_new=F_in; //取得现在的 频率发生引脚状态
        if(state_old&&!state_new)  // 下降沿开始启动闸门
        {
         temp_flag++;   
         TR0=1;  //启动定时器 计数
        }
        if(temp_flag==2)
        {
         TR0=0;   //计数停止
         t_count=TH0*256+TL0;  //取得当前的计数值
         frequency=1000000/t_count;  //计算频率
         return;  //返回
        }
        state_old=state_new;
 }
}


void Mcu_init(void) //初始化函数
{
 EA=1;  //开总中断
 ET0=1;  //定时器0 开
 TR0=1;    //启动定时器 0
 ET1=1;  //定时器 1 开
 TR1=1;  //启动定时器1 
 TMOD=0x11;  //工作状态
 TH0=0x4c; //定时器初值
 TL0=0x00;
 TH1=0xfe;
 TL1=0x33;

}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -