标题:
51单片机频率计(数码管显示)
[打印本页]
作者:
musi798
时间:
2018-11-19 22:12
标题:
51单片机频率计(数码管显示)
误差不大
单片机源程序如下:
#include "reg51.h"
#include "intrins.h"
#define CKSEL (*(unsigned char volatile xdata *)0xfe00)
#define CKDIV (*(unsigned char volatile xdata *)0xfe01)
#define IRC24MCR (*(unsigned char volatile xdata *)0xfe02)
#define XOSCCR (*(unsigned char volatile xdata *)0xfe03)
#define IRC32KCR (*(unsigned char volatile xdata *)0xfe04)
#define M 2000
sfr ADC_CONTR = 0xbc;
sfr ADC_RES = 0xbd;
sfr ADC_RESL = 0xbe;
sfr ADCCFG = 0xde;
sfr P_SW2 = 0xba;
sbit EADC = IE^5;
sfr AUXR = 0x8e;
sfr CMPCR1 = 0xe6;
sfr CMPCR2 = 0xe7;
sfr IE2 = 0xaf;
sfr AUXINTIF = 0xef;
sfr T4T3M = 0xd1;
sfr TL3 = 0xd5;
sfr TH3 = 0xd4;
sfr IPH = 0xb7;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sbit FreIn = P0^4;
sbit P26 = P2^6;
sbit P27 = P2^7;
sbit CLK = P2^3;
sbit DAT = P2^1;
void display164(unsigned char udata)
{
char i;
for(i=0;i<8;i++)
{
if(udata&0x80)
{
DAT=1;
CLK=0;
udata = udata<<1;
CLK=1;
}
else
{
DAT=0;
CLK=0;
udata = udata<<1;
CLK=1;
}
}
}
void DiviVol()
{
P26 = 1;
P27= 0;
}
void NotDiviVol()
{
P27 = 1;
P26 = 0;
}
void delay(int ms)
{
int a,b;
for(a=ms;a>0;a--)
for(b=120;b>0;b--);
}
unsigned int time = 0;
unsigned int count = 0;
unsigned long frequency = 0,temp=0,tempone = 0;
unsigned char code Table[]={0xee,0x28,0xcd,0x6d,0x2b,0x67,0xe7,0x2c,0xef,0x6f};
unsigned char code PotTable[]={0xfe,0x38,0xdd,0x7d,0x3b,0x77,0xf7,0x3c,0xff,0x7f};
unsigned int H=0,L=0;
unsigned char tempp[7]={0};
unsigned int Vol = 0,RawVol = 0;
bit flag = 0;
unsigned int qf = 0;
void SetOutXtal()
{
P_SW2 = 0x80;
XOSCCR = 0xc0; //启动外部晶振
while (!(XOSCCR & 1)); //等待时钟稳定
CKDIV = 0x00; //时钟不分频
CKSEL = 0x01; //选择外部晶振
P_SW2 = 0x00;
}
void CMP_Ini()
{
CMPCR1 = 0x86;
CMPCR2 = 0x42;
// CMPCR2 = 0x43;
P_SW2 = 0x00;
}
void T1_Ini()
{
TMOD = 0x00;
TH1 = 0x3c;
TL1 = 0xb0;
AUXR = 0x00;
ET1 = 1;
}
void T3_Ini()
{
T4T3M = 0x04;
TH3 = 0x00;
TL3 = 0x00;
IE2=0x20; //允许T3中断
}
void INT1_Ini()
{
IT1 = 1;
EX1 = 1;
IP = 0x04;
IPH = 0x04;
}
void SysClkTest()
{
display164(Table[0]); //七个数码管都显示0,则系统时钟选择正常
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
}
void ADC_Ini()
{
DiviVol(); //初始选择分压
P1M0 = 0x00; //设置P1.0为ADC口
P1M1 = 0x03; //P1.0和P1.1都设置为高阻输入模式
ADCCFG = 0x00; //设置ADC时钟为系统时钟/2/16/16
ADC_CONTR = 0x80; //使能ADC模块
}
void main()
{
int timev[M]={0};
int i,imax,imaxp;
imaxp=0;
SetOutXtal();
SysClkTest();
INT1_Ini();
CMP_Ini();
T1_Ini();
T3_Ini();
ADC_Ini();
EA = 1;
while(1)
{
if(flag==0)
{
for(i=0;i<M;i++)
{
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
delay(1);
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
H=ADC_RES;
L=ADC_RESL;
RawVol=H*16+L/16;
ADC_CONTR &= 0xa0;
// Vol = RawVol*11;
timev[i]=RawVol*11;
delay(5);
}
imax=timev[0];
for(i=1;i<M;i++)
{
if(timev[i]>imax)
{
imax=timev[i];
//imaxp=i;
}
}
Vol=2*imax;
// if(RawVol<33)
// {
// NotDiviVol();
// delay(5);
// ADC_CONTR = 0x81; //使能ADC模块
// delay(5);
// ADC_CONTR |= 0x40; //启动AD转换
// _nop_();
// _nop_();
// while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
// ADC_CONTR &= ~0x20; //清完成标志
// H=ADC_RES;
// L=ADC_RESL;
//
// RawVol=H*16+L/16;
//
// Vol = RawVol/11;
//
// }
display164(Table[Vol/10%10]);
display164(Table[Vol/100%10]);
display164(PotTable[Vol/1000%10]);
display164(Table[Vol/10000]);
display164(0x00);
display164(0x00);
display164(0x00);
display164(0x3e);
DiviVol();
delay(5);
//imax=0;
// ADC_CONTR = 0x80; //使能ADC模块
// ADC_CONTR |= 0x40; //启动AD转换
time = 0;
delay(6000);
}
if(flag==1)
{
if(time==0)
{
// while(FreIn==1);
// while(FreIn==0);
TR1=1;//打开T1、T3,开始测频
T4T3M |= 0x08;
}
}
if(time==20)
{
TR1 = 0;
T4T3M &= 0xf7;
temp = TH3*256+TL3+count*65536;
tempone = temp+1;
frequency = temp+(int)(tempone*0.0001);
tempp[0] = frequency%10;
tempp[1] = (frequency/10)%10;
tempp[2] = (frequency/100)%10;
tempp[3] = (frequency/1000)%10;
tempp[4] = (frequency/10000)%10;
tempp[5] = (frequency/100000)%10;
tempp[6] = (frequency/1000000)%10;
if((frequency/1000000)%10==0)
{
tempp[6] = 10;
if((frequency/100000)%10==0)
{
tempp[5] = 10;
if((frequency/10000)%10==0)
{
tempp[4] = 10;
if((frequency/1000)%10==0)
{
tempp[3] = 10;
if((frequency/100)%10==0)
{
tempp[2] = 10;
if((frequency/10)%10==0)
{
tempp[1] = 10;
if(frequency%10==0)
{
tempp[0] = 10;
}
}
}
}
}
}
}
display164(Table[tempp[0]]); //频率送显
display164(Table[tempp[1]]);
display164(Table[tempp[2]]);
display164(Table[tempp[3]]);
display164(Table[tempp[4]]);
display164(Table[tempp[5]]);
display164(Table[tempp[6]]);
display164(0x71);
time = 0;
count = 0;
TH3 = 0;
TL3 = 0;
TH1 = 0x3c;
TL1 = 0xb0;
}
}
}
void INT1_Ser() interrupt 2
{
flag=!flag;
}
void T1_Isr() interrupt 3
{
time++;
}
void T3_Isr() interrupt 19
{
count++;
AUXINTIF &= 0xfd; //清中断标志
}
/*
#include "reg51.h"
#include "intrins.h"
#define CKSEL (*(unsigned char volatile xdata *)0xfe00)
#define CKDIV (*(unsigned char volatile xdata *)0xfe01)
#define IRC24MCR (*(unsigned char volatile xdata *)0xfe02)
#define XOSCCR (*(unsigned char volatile xdata *)0xfe03)
#define IRC32KCR (*(unsigned char volatile xdata *)0xfe04)
sfr ADC_CONTR = 0xbc;
sfr ADC_RES = 0xbd;
sfr ADC_RESL = 0xbe;
sfr ADCCFG = 0xde;
sfr P_SW2 = 0xba;
sbit EADC = IE^5;
sfr AUXR = 0x8e;
sfr CMPCR1 = 0xe6;
sfr CMPCR2 = 0xe7;
sfr IE2 = 0xaf;
sfr AUXINTIF = 0xef;
sfr T4T3M = 0xd1;
sfr TL3 = 0xd5;
sfr TH3 = 0xd4;
sfr IPH = 0xb7;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sbit FreIn = P0^4;
sbit P26 = P2^6;
sbit P27 = P2^7;
sbit CLK = P2^3;
sbit DAT = P2^1;
void display164(unsigned char udata)
{
char i;
for(i=0;i<8;i++)
{
if(udata&0x80)
{
DAT=1;
CLK=0;
udata = udata<<1;
CLK=1;
}
else
{
DAT=0;
CLK=0;
udata = udata<<1;
CLK=1;
}
}
}
void DiviVol()
{
P26 = 1;
P27= 0;
}
void NotDiviVol()
{
P27 = 1;
P26 = 0;
}
void delay(int ms)
{
int a,b;
for(a=ms;a>0;a--)
for(b=120;b>0;b--);
}
unsigned int time = 0;
unsigned int count = 0;
unsigned long frequency = 0,temp=0,tempone = 0;
unsigned char code Table[]={0xee,0x28,0xcd,0x6d,0x2b,0x67,0xe7,0x2c,0xef,0x6f};
unsigned char code PotTable[]={0xfe,0x38,0xdd,0x7d,0x3b,0x77,0xf7,0x3c,0xff,0x7f};
//unsigned char code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
//unsigned char code PotTable[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
unsigned int H=0,L=0;
unsigned char tempp[7]={0};
unsigned int Vol = 0,RawVol = 0;
bit flag = 0;
unsigned int qf = 0;
void SetOutXtal()
{
P_SW2 = 0x80;
XOSCCR = 0xc0; //启动外部晶振
while (!(XOSCCR & 1)); //等待时钟稳定
CKDIV = 0x00; //时钟不分频
CKSEL = 0x01; //选择外部晶振
P_SW2 = 0x00;
}
void CMP_Ini()
{
CMPCR1 = 0x86;
CMPCR2 = 0x42;
// CMPCR2 = 0x43;
P_SW2 = 0x00;
}
void T1_Ini()
{
TMOD = 0x00;
TH1 = 0x3c;
TL1 = 0xb0;
AUXR = 0x00;
ET1 = 1;
}
void T3_Ini()
{
T4T3M = 0x04;
TH3 = 0x00;
TL3 = 0x00;
IE2=0x20; //允许T3中断
}
void INT1_Ini()
{
IT1 = 1;
EX1 = 1;
IP = 0x04;
IPH = 0x04;
}
void SysClkTest()
{
display164(Table[0]); //七个数码管都显示0,则系统时钟选择正常
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
display164(Table[0]);
}
void ADC_Ini()
{
DiviVol(); //初始选择分压
P1M0 = 0x00; //设置P1.0为ADC口
P1M1 = 0x03; //P1.0和P1.1都设置为高阻输入模式
ADCCFG = 0x00; //设置ADC时钟为系统时钟/2/16/16
ADC_CONTR = 0x80; //使能ADC模块
}
void main()
{
SetOutXtal();
SysClkTest();
INT1_Ini();
CMP_Ini();
T1_Ini();
T3_Ini();
ADC_Ini();
EA = 1;
while(1)
{
if(flag==0)
{
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
delay(1);
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
H=ADC_RES;
L=ADC_RESL;
RawVol=H*16+L/16;
ADC_CONTR &= 0xa0;
Vol = RawVol*11;
// if(RawVol<33)
// {
// NotDiviVol();
// delay(5);
// ADC_CONTR = 0x81; //使能ADC模块
// delay(5);
// ADC_CONTR |= 0x40; //启动AD转换
// _nop_();
// _nop_();
// while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
// ADC_CONTR &= ~0x20; //清完成标志
// H=ADC_RES;
// L=ADC_RESL;
//
// RawVol=H*16+L/16;
//
// Vol = RawVol/11;
//
// }
display164(Table[Vol/10%10]);
display164(Table[Vol/100%10]);
display164(PotTable[Vol/1000%10]);
display164(Table[Vol/10000]);
display164(0x00);
display164(0x00);
display164(0x00);
display164(0x3e);
DiviVol();
delay(5);
ADC_CONTR = 0x80; //使能ADC模块
ADC_CONTR |= 0x40; //启动AD转换
time = 0;
delay(3000);
}
if(flag==1)
{
if(time==0)
{
// while(FreIn==1);
// while(FreIn==0);
TR1=1;//打开T1、T3,开始测频
T4T3M |= 0x08;
}
}
if(time==20)
{
TR1 = 0;
T4T3M &= 0xf7;
temp = TH3*256+TL3+count*65536;
tempone = temp+1;
frequency = temp+(int)(tempone*0.0001);
tempp[0] = frequency%10;
tempp[1] = (frequency/10)%10;
tempp[2] = (frequency/100)%10;
tempp[3] = (frequency/1000)%10;
tempp[4] = (frequency/10000)%10;
tempp[5] = (frequency/100000)%10;
tempp[6] = (frequency/1000000)%10;
if((frequency/1000000)%10==0)
{
tempp[6] = 10;
if((frequency/100000)%10==0)
{
tempp[5] = 10;
if((frequency/10000)%10==0)
{
tempp[4] = 10;
if((frequency/1000)%10==0)
{
tempp[3] = 10;
if((frequency/100)%10==0)
{
tempp[2] = 10;
if((frequency/10)%10==0)
{
tempp[1] = 10;
if(frequency%10==0)
{
tempp[0] = 10;
}
}
}
}
}
}
}
display164(Table[tempp[0]]); //频率送显
display164(Table[tempp[1]]);
display164(Table[tempp[2]]);
display164(Table[tempp[3]]);
display164(Table[tempp[4]]);
display164(Table[tempp[5]]);
display164(Table[tempp[6]]);
display164(0x71);
time = 0;
count = 0;
TH3 = 0;
TL3 = 0;
TH1 = 0x3c;
TL1 = 0xb0;
}
}
}
void INT1_Ser() interrupt 2
{
flag=!flag;
}
void T1_Isr() interrupt 3
{
time++;
}
void T3_Isr() interrupt 19
{
count++;
AUXINTIF &= 0xfd; //清中断标志
}
*/
复制代码
所有资料51hei提供下载:
测频率.rar
(37.85 KB, 下载次数: 25)
2018-11-19 22:11 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
admin
时间:
2018-11-20 04:15
补全原理图或者详细说明一下电路连接即可获得100+黑币
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1