| 说明,开始时候,写的程序没有显示,
不知道网友们都调试了没有,呵呵,
这回加上了显示,发上来,但是有些
小的bug,希望有高手帮助解决!
或者,等我再有空的时候,在研究研究
/* Measure Frequency program on 51 Mcu Study Board II zl0801 2006-11-19 17:30 zhaoliang0801@gmail.com 功能描述: 开发板测频率实验, 按照 说明将测评的跳线帽插到外面的2个管脚上 下载程序,程序执行时,利用内部的定时器产生 一个6k左右的方波,用示波器可以观测到,同时 这个信号用跳线连接到开发板的测频管脚,这个 程序加上了数码管显示,但是由于测频的时间比较 长,使得显示的时候有些闪烁,呵呵,改了半天, 也没有解决,如果那位朋友解决了,告诉我 ^_^ */
#i nclude "reg51.h" #i nclude "stdio.h" #i nclude " absacc.h " #i nclude <intrins.h> #i nclude <math.h>
/********************************************************************/ void delay_nms(unsigned int n);//delay function
sbit F_in=P1^3; //测量频率管脚 sbit F_out=P1^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);
/***********************************************************************/
/********************/ unsigned char table[]= {0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f, 0x40,0x00}; //共阴数码管 0-9 '-' '熄灭‘表 /********************/ sbit seclet_A = P1^0; //管脚定义 74-138 3-8 控制信号线 sbit seclet_B = P1^1; sbit seclet_C = P1^2; /********************/ //宏定义 #define SM_1 seclet_C=0;seclet_B=0;seclet_A=0 #define SM_2 seclet_C=0;seclet_B=0;seclet_A=1 #define SM_3 seclet_C=0;seclet_B=1;seclet_A=0 #define SM_4 seclet_C=0;seclet_B=1;seclet_A=1 #define SM_5 seclet_C=1;seclet_B=0;seclet_A=0 #define SM_6 seclet_C=1;seclet_B=0;seclet_A=1 #define SM_7 seclet_C=1;seclet_B=1;seclet_A=0 #define SM_8 seclet_C=1;seclet_B=1;seclet_A=1 #define SM_FF P2=table[11]
/***********************************************************************/ void dis_delay(void); void display(unsigned int temp); /***********************************************************************/
//显示延时 函数 void dis_delay(void) { unsigned char i; for(i=0;i<20;i++); } //显示子函数 注意参数传递 void display(unsigned int temp) { SM_FF; SM_8; P2=table[temp%10]; dis_delay(); SM_FF; SM_7; P2=table[temp/10%10]; dis_delay(); SM_FF; SM_6; P2=table[temp/100%10]; dis_delay(); SM_FF; SM_5; P2=table[temp/1000%10]; dis_delay(); SM_FF; SM_4; P2=table[11]; dis_delay(); SM_FF; SM_3; P2=table[10]; dis_delay(); SM_FF; SM_2; P2=0x71; dis_delay(); SM_FF; SM_1; P2=table[11]; dis_delay(); SM_FF; } void main() { Mcu_init(); //初始化 while(1) { unsigned int i; Frequency_Measure(); for(i=200;i>0;i--) display(frequency); } }
void time0(void) interrupt 1 { int_flag=1; //计数溢出标志 }
void time1(void) interrupt 3 { TH1=-1000/256; //重新附值 TL1=-1000%256; 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=-50000/256; //定时器初值 50ms TL0=-50000%256; 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=0x01; //工作状态 TH0=-(50000/256); //定时器初值 TL0=-(50000%256); TH1=-500/256; TL1=-500%256;
}
|