51测频率程序
玛丽莲梦兔
596次浏览
2020年08月02日 00:12
最佳经验
本文由作者推荐
圆口纲-飔怎么读
51测频率程序,数码管显示————jinsongliang
定时1s数脉冲个数,
频率值为1S内脉冲个数,无小数部分,有修正但小数部分不准。
1k~999.99k之间有万分之一以下精度
999~100HZ,整数位无误差,由于小数位无法测量,
误差小于百分之一,大于千分之一;脉冲间隔大于1MS
频率在1K以下时测量一个脉冲的时间,有万分之一以下精度
1.0054HZ测得1.0055HZ
*/
#include<reg51.h>
#include"lib51v3.c"
#include"segv3.c"
#include"mix.c"
#define SET_16TIMER0()tttTMOD|=T0_M0
#define SET_16COUNTER1()ttTMOD|=(T1_M0|T1_CT)
#define EN_TIMER0()tttTCON|=TR0_L
#define DIS_TIMER0()tttTCON&=~TR0_Lt
#define EN_COUNTER1()tttTCON|=TR1_L
#define DIS_COUNTER1()tttTCON&=~TR1_Lt
#define INTURP_ALL_YES()ttIE|=EA_L
//#define INTURP_ALL_NO()ttIE&=~EA_L
#define INTURP_TIMER0_YES()ttIE|=ET0_L
//#define INTURP_TIMER0_NO()ttIE&=~ET0_L
#define INTURP_COUNTER1_YES()ttIE|=ET1_L
//#define INTURP_COUNTER1_NO()ttIE&=~ET1_L
volatile unsigned char v=0;
volatile unsigned char t=0;
volatile unsigned char err=0;
void main (void)
{
float fcy=0;
float f_temp;
SET_16COUNTER1();
SET_16TIMER0();
INTURP_ALL_YES();
INTURP_TIMER0_YES();
INTURP_COUNTER1_YES();
while(1)
{
v=0;
t=0;
TL0=0xAF;ttttttt//15,535=65,535-50,000=0x3caf
TH0=0x3C;
TL1=0x00;ttttttt
TH1=0x00;
EN_TIMER0();
EN_COUNTER1();
while(TCON&TR1_L);
fcy=TH1*256+TL1+v*65536;
fcy/=1.000099;
if(fcy<100.0&&fcy>0)
{
err=1;
v=0;
t=0;
TL0=0xAF;ttttttt//15,535=65,535-50,000=0x3caf
TH0=0x3C;
TL1=0xFF;ttttttt
TH1=0xFF;
EN_COUNTER1();
while(!(TCON&TR0_L));
err=2;
while(TCON&TR1_L);
f_temp=t*50000+TH0*256+TL0-0x3CAF;
fcy=1000000.0/f_temp;
}
Seg_Sp_Display (fcy);
}
}
void Counter1_Irupt (void)tinterrupt 3
{
++v;
if(err==1)
{
EN_TIMER0();
TL1=0xFF;ttttttt
TH1=0xFF;
}
else if(err==2)
{
DIS_TIMER0();
DIS_COUNTER1();
}
}
void Timer0_Irupt (void) interrupt 1
{
TL0=0xAF+0x02;ttttttt//15,535=65,535-50,000=0x3caft2us中断跳转补偿
TH0=0x3C;tt ttttttt
++t;
if(t==20)tttttttt//50ms*20=1s
{
DIS_COUNTER1();
DIS_TIMER0();
}
}
lib51v3.c:
//TMODtt
//GATEt(启动方式) t
//C/~Tt(定时=0/计数=1)t
//M1t(四种模式)16位01t
//M0t(四种模式)tt
//GATEt(定时计数器0)t
//C/~Tt
//M1
//M0
#define T1_GATEtt(1<<7)
#define T1_CTtt(1<<6)
#define T1_M1tt(1<<5)
#define T1_M0tt(1<<4)
#define T0_GATEtt(1<<3)
#define T0_CTtt(1<<2)
#define T0_M1tt(1<<1)
#define T0_M0tt(1<<0)
//TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
#define TF1_Ltt(1<<7)tt//定时计数器1益处标志
#definetTR1_Ltt(1<<6)tt//定时计数器1启动
#definetTF0_Ltt(1<<5)tt//定时计数器0益处标志
#definetTR0_Ltt(1<<4)tt//定时计数器0启动
#def
inetIE1_Ltt(1<<3)tt//外部中断1触发方式 0为负电平触发,1为下降沿触发
#definet
IT1_Ltt(1<<2)tt//外部中断1的中断发生标志
#definetIE0_Ltt(1<<1)tt//外部中断0触发方式 0为负电平触发,1为下降沿触发
#definetIT0_Ltt(1<<0)tt//外部中断0的中断发生标志
//IE EA - - ES ET1 EX1 ET0 EX0
#definetEA_Ltt(1<<7)
#definetES_Ltt(1<<4)tt//串行通信中断 t
#definetET1_Ltt(1<<3)
#definetEX1_Ltt(1<<2)
#definetET0_Ltt(1<<1)
#definetEX0_Ltt(1<<0)
//IP - - - PS PT1 PX1 PT0 PX0
#definetPS_Ltt(1<<4)
#definetPT1_Ltt(1<<3)
#definetPX1_Ltt(1<<2)
#definetPT0_Ltt(1<<1)
#definetPX0_Ltt(1<<0)
#define IE0_VECTORt0 /* 0x03 External Interrupt 0 */
#define TF0_VECTORt1 /* 0x0B Timer 0 */
#define IE1_VECTORt2 /* 0x13 External Interrupt 1 */
#define TF1_VECTORt3 /* 0x1B Timer 1 */
#define SIO_VECTORt4 /* 0x23 Serial port */
void Delay_Nus (unsigned char n)tttt
{
while(n--);
//for (;n>0;n--);
}
/*
void Delay_Nms (unsigned int n)ttttt
{
while(n--)
{
unsigned char i=123;
while(i--);
}
}
void Delay_Nms (unsigned int n)ttttt
{
while(n--)
{
unsigned int i;
for(i=0;i<8329;i++);
}
}
*/
//deci_code[0]:ttttt符号
//deci_code[1]~deci_code[7]:t5位有效数字
//deci_code[8]:ttttt阶次数符号
//deci_code[9]~deci_code[10]:t阶次数
//314等于3.140000乘以10的2次方
//静态全局变量,作用域仅限于变量被定义的文件中,其他文件即使用extern 声明也没法
//使用他。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些
//代码行也不能使用它。想要使用就得在前面再加extern。
//static unsigned char deci_code[9];
unsigned char *Decimal_Deal (float f_data)
{t
//静态局部变量,在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他
//函数也用不了。由于被static 修饰的变量总是存在内存的静态区,所以即使这个函数运行结
//束,这个静态变量的值还是不会被销毁,函数下次使用时仍然能用到这个值。 只初始化一次,默认值为0.
static unsigned char deci_code[11]; tt
unsigned char e=127;
unsigned char i;
if(f_data<0)tttttttttt//取f_data绝对值,及符号
{
deci_code[0]='-';tttttttt//1代表有负号,下面也如此
f_data=-f_data;
}
else if(f_data>0)
deci_code[0]='+';t
else
{
for(i=0;i<11;i++)
deci_code[i]=0;
return (deci_code);t
}
while(f_data>=10)
{
f_data/=10;
++e;
}tt
while(f_data<1)
{
f_data*=10;
--e;
}t
f_data+=0.000001;tttttttt//减小误差t
for(i=0;i<7;i++)tttttttt//提取纯小数7位有效数字
{
deci_code[i+1]=(unsigned char)f_data;
f_data-=deci_code[i+1];
f_data*=10;
}
if(e>127)
{
deci_code[8]='+';t
deci_code[9]=(e-127)/10;
deci_code[10]=(e-127)%10;t
}
else if(e<127)
{
deci_code[8]='-';
deci_code[9]=(127-e)/10;
deci_code[10]=(127-e)%10;t
}
else
{
deci_code[8]='+';
deci_code[9]=deci_code[10]=0;tt
}
return (deci_code);
}
segv3.c:
#define COMMON_ANODICtt0tt//共阳
#define COMMON_CATHODAL t1tt//共阴
#define SEG_CATEGORYtt0
#define SEG8_Att~(1<<0)ttt//A亮为0,属共阳
#define SEG8_Btt~(1<<1)
#define SEG8_Ctt~(1<<2)
#define SEG8_Dtt~(1<<3)
#define SEG8_Ett~(1<<4)
#define SEG8_Ftt~(1<<5)
#define SEG8_Gtt~(1<<6)
#define SEG8_DPtt~(1<<7)t
#definetSEG8_CHAR_0tt~(SEG8_G&SEG8_DP)t
#definetSEG8_CHAR_1tt~(SEG8_A&SEG8_D&SEG8_E&SEG8_F&SEG8_G&SEG8_DP)
#definetSEG8_CHAR_2tt~(SEG8_C&SEG8_F&SEG8_DP)
#definetSEG8_CHAR_3tt~(SEG8_E&SEG8_F&SEG8_DP)
#definetSEG8_CHAR_4tt~(SEG8_A&SEG8_D&SEG8_E&SEG8_DP)
#definetSEG8_CHAR_5tt~(SEG8_B&SEG8_E&SEG8_DP)
#definetSEG8_CHAR_6tt~(SEG8_B&SEG8_DP)
#definetSEG8_CHAR_7tt~(SEG8_D&SEG8_E&SEG8_F&SEG8_G&SEG8_DP)
#definetSEG8_CHAR_8tt~SEG8_DP
#definetSEG8_CHAR_9tt~(SEG8_E&SEG8_DP)
#definetSEG8_CHAR_tt0xff
#definetSEG8_CHAR_Ett~(SEG8_B&SEG8_C&SEG8_DP)
#definetSEG8_CHAR_Rtt~(SEG8_A&SEG8_B&SEG8_C&SEG8_D&SEG8_F&SEG8_DP)
#definetSEG8_CHAR_SUBtt~(SEG8_A&SEG8_B&SEG8_C&SEG8_D&SEG8_E&SEG8_F&SEG8_DP)
//#definetSEG8_CHAR_A
//#definetSEG8_CHAR_B
#definetSEG8_CHAR_Ctt~(SEG8_B&SEG8_C&SEG8_G&SEG8_DP)
//#definetSEG8_CHAR_D
//#definetSEG8_CHAR_F
//#definetSEG8_CHAR_H
#if SEG_CATEGORY==COMMON_ANODIC
static const unsigned char SEG8_CODE[]={
SEG8_CHAR_0,
SEG8_CHAR_1,
SEG8_CHAR_2,
SEG8_CHAR_3,
SEG8_CHAR_4,
SEG8_CHAR_5,
SEG8_CHAR_6,
SEG8_CHAR_7,
SEG8_CHAR_8,
SEG8_CHAR_9,
SEG8_CHAR_,ttt//SEG8_CODE[10]
SEG8_CHAR_E,ttt//SEG8_CODE[11]
SEG8_CHAR_R,ttt//SEG8_CODE[12]
SEG8_CHAR_SUB,ttt//SEG8_CODE[13]
SEG8_CHAR_Cttt//SEG8_CODE[14]
};
#else
static const unsigned char SEG8_CODE[]={
~SEG8_CHAR_0,
~SEG8_CHAR_1,
~SEG8_CHAR_2,
~SEG8_CHAR_3,
~SEG8_CHAR_4,
~SEG8_CHAR_5,
~SEG8_CHAR_6,
~SEG8_CHAR_7,
~SEG8_CHAR_8,
~SEG8_CHAR_9,
~SEG8_CHAR_,tt//SEG8_CODE[10]
~SEG8_CHAR_E,tt//SEG8_CODE[11]
~SEG8_CHAR_R,tt//SEG8_CODE[12]
~SEG8_CHAR_SUB,tt//SEG8_CODE[13]
~SEG8_CHAR_Ctt//SEG8_CODE[14]
};
#endif
#define SEG8_SLECT_PORTttP1
#define BIT0tttt3t
#define BIT1tttt2
#define BIT2tttt1
#define BIT3tttt0
#define SEG8_BIT0_ON()ttSEG8_SLECT_PORT|=(1<<BIT0)
#define SEG8_BIT0_OFF()ttSEG8_SLECT_PORT&=~(1<<BIT0)
#define SEG8_BIT1_ON()ttSEG8_SLECT_PORT|=(1<<BIT1)
#define SEG8_BIT1_OFF()ttSEG8_SLECT_PORT&=~(1<<BIT1)
#define SEG8_BIT2_ON()ttSEG8_SLECT_PORT|=(1<<BIT2)
#define SEG8_BIT2_OFF()ttSEG8_SLECT_PORT&=~(1<<BIT2)
#define SEG8_BIT3_
ON()ttSEG8_SLECT_PORT|=(1<<BIT3)
#define SEG8_BIT3_OFF()ttSEG8_SLECT_PORT&=~(1<<BIT3)
#define SEG8_CODE_PORTttP2
void Seg_Display (char *p)
{
unsigned char temp[4];
temp[0]=SEG8_CODE[*p++];
temp[1]=SEG8_CODE[*p++];
temp[2]=SEG8_CODE[*p++];
temp[3]=SEG8_CODE[*p++];
if(*p<4)
#if SEG
_CATEGORY==COMMON_ANODIC
temp[*p]&=SEG8_DP;t
#else
temp[*p]|=~SEG8_DP;
#endif
{
unsigned char i;
for(i=0;i<150;i++)
{
SEG8_CODE_PORT = temp[0];
SEG8_BIT0_ON();
Delay_Nus(6);ttttt//lib51v3.c
SEG8_BIT0_OFF();
SEG8_CODE_PORT = temp[1];
SEG8_BIT1_ON();
Delay_Nus(6);
SEG8_BIT1_OFF();
SEG8_CODE_PORT = temp[2];
SEG8_BIT2_ON();
Delay_Nus(6);
SEG8_BIT2_OFF();
SEG8_CODE_PORT = temp[3];
SEG8_BIT3_ON();
Delay_Nus(6);
SEG8_BIT3_OFF();
}
}
}
mix.c:
void Seg_Sp_Display (float f_data)
{
unsigned char a[5]={0,0,0,0,0};
unsigned char *c;
unsigned char i;
c=Decimal_Deal(f_data);
if(*c=='+')
a[0]=10;
else if(*c=='-')
a[0]=13;
a[1]=*(c+1);
a[2]=*(c+2);
a[3]=*(c+3);
a[4]=1;
for(i=0;i<50;i++)
Seg_Display(a);
a[0]=*(c+4);
a[1]=*(c+5);
a[2]=*(c+6);
a[3]=*(c+7);
a[4]=5;
for(i=0;i<50;i++)
Seg_Display(a);
if(*(c+8)=='+')
a[0]=10;
else if(*(c+8)=='-')
a[0]=13;
a[1]=10;
a[2]=*(c+9);
a[3]=*(c+10);
for(i=0;i<50;i++)
Seg_Display(a);
}