设计一个以单片机为核心的频率测量装置。使用AT89C51单片机的定时器/计数器的定时和计数功能,外部扩展6位LED数码管,要求累计每秒进入单片机的外部脉冲个数,用LED数码管显示出来。测量频率有测频法和测周法两种。
求个C程序
æ°ç 管å°å¤èäºï¼ä½ ç¨è¿ä¸ªå§ï¼ççè¿ç¨å¾®æç¹å¯ä»¥ï¼ä»£ç åçµè·¯é½ç»ä½ äºï¼æ²¡æåä¸åºæ¥ççç±ï¼æé®é¢å æQQ11422376745
#include "d:\c51\reg51.h"
#include "d:\c51\intrins.h"
sbit LCM_RS=P3^0;
sbit LCM_RW=P3^1;
sbit LCM_EN=P3^7;
#define BUSY 0x80 //常éå®ä¹
#define DATAPORT P1
#define uchar unsigned char
#define uint unsigned int
#define L 50
uchar str0[16],str1[16],count;
uint speed;
unsigned long time;
void ddelay(uint);
void lcd_wait(void);
void display();
void initLCM();
void WriteCommandLCM(uchar WCLCM,uchar BusyC);
void STR();
void account();
/*********延æ¶K*1ms,12.000mhz**********/
void int0_isr(void) interrupt 0 /*é¥æ§ä½¿ç¨å¤é¨ä¸æ0,æ¥P3.2å£*/
{
unsigned int temp;
time=count;
TR0=0;
temp=TH0;
temp=((temp << 8) | TL0);
TH0=0x3c;
TL0=0xaf;
count=0;
TR0=1;
time=time*50000+temp;
}
void time0_isr(void) interrupt 1 /*é¥æ§ä½¿ç¨å®æ¶è®¡æ°å¨1 */
{
TH0 =0x3c;
TL0 =0xaf;
count++;
}
void main(void)
{
TMOD=0x01; /*TMOD T0éç¨æ¹å¼1(16ä½å®æ¶) */
IP|=0x01; /*INT0 ä¸æä¼å */
TCON|=0x11; /*TCON EX0ä¸é沿触å,å¯å¨T0*/
IE|=0x83;
TH0=0x3c;
TL0=0xaf;
initLCM();
WriteCommandLCM(0x01,1); //æ¸ æ¾ç¤ºå±
for(;;)
{
account();
display();
}
}
void account()
{
unsigned long a;
if (time!=0)
{
a=L*360000000/time;
}
speed=a;
}
void STR()
{
str0[0]='S';
str0[1]='p';
str0[2]='e';
str0[3]='e';
str0[4]='d';
str0[5]=' ';
str0[6]=(speed%100000)/10000+0x30;
str0[7]=(speed%10000)/1000+0x30;
str0[8]=(speed%1000)/100+0x30;
str0[9]='.';
str0[10]=(speed%100)/10+0x30;
str0[11]=speed%10+0x30;
str0[12]='k';
str0[13]='m';
str0[14]='/';
str0[15]='h';
}
void ddelay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
{
for(j=0;j<60;j++)
{;}
}
}
/**********åæ令å°LCDåå½æ°************/
void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
if(BusyC)lcd_wait();
DATAPORT=WCLCM;
LCM_RS=0; /* éä¸æ令å¯åå¨*/
LCM_RW=0; // å模å¼
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/**********åæ°æ®å°LCDåå½æ°************/
void WriteDataLCM(uchar WDLCM)
{
lcd_wait( ); //æ£æµå¿ä¿¡å·
DATAPORT=WDLCM;
LCM_RS=1; /* éä¸æ°æ®å¯åå¨ */
LCM_RW=0; // å模å¼
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/***********lcdå é¨çå¾ å½æ°*************/
void lcd_wait(void)
{
DATAPORT=0xff; //读LCDåè¥åçæºè¾åºä½çµå¹³,è读åºLCD为é«çµå¹³,åå²çª,Proteus仿çä¼ææ¾ç¤ºé»è¾é»è²
LCM_EN=1;
LCM_RS=0;
LCM_RW=1;
_nop_();
_nop_();
_nop_();
while(DATAPORT&BUSY)
{ LCM_EN=0;
_nop_();
_nop_();
LCM_EN=1;
_nop_();
_nop_();
}
LCM_EN=0;
}
/**********LCDåå§ååå½æ°***********/
void initLCM( )
{
DATAPORT=0;
ddelay(15);
WriteCommandLCM(0x38,0); //ä¸æ¬¡æ¾ç¤ºæ¨¡å¼è®¾ç½®ï¼ä¸æ£æµå¿ä¿¡å·
ddelay(5);
WriteCommandLCM(0x38,0);
ddelay(5);
WriteCommandLCM(0x38,0);
ddelay(5);
WriteCommandLCM(0x38,1); //8bitæ°æ®ä¼ éï¼2è¡æ¾ç¤ºï¼5*7ååï¼æ£æµå¿ä¿¡å·
WriteCommandLCM(0x08,1); //å ³éæ¾ç¤ºï¼æ£æµå¿ä¿¡å·
WriteCommandLCM(0x01,1); //æ¸ å±ï¼æ£æµå¿ä¿¡å·
WriteCommandLCM(0x06,1); //æ¾ç¤ºå æ å³ç§»è®¾ç½®ï¼æ£æµå¿ä¿¡å·
WriteCommandLCM(0x0c,1); //æ¾ç¤ºå±æå¼ï¼å æ ä¸æ¾ç¤ºï¼ä¸éªçï¼æ£æµå¿ä¿¡å·
}
/****æ¾ç¤ºæå®åæ çä¸ä¸ªå符åå½æ°****/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40; //è¥y为1ï¼æ¾ç¤ºç¬¬äºè¡ï¼ï¼å°åç +0X40
X|=0x80; //æ令ç 为å°åç +0X80
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
/*******æ¾ç¤ºæå®åæ çä¸ä¸²å符åå½æ°*****/
void DisplayListChar(uchar X,uchar Y,uchar *DData)
{
uchar ListLength=0;
Y&=0x01;
X&=0x0f;
while(X<16)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
void display()
{
STR();
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
}
(1)被测频率fx<110Hz,采用测周法,显示频率×××. ×××;fx>110Hz,采用测频法,显示频率××××××。
(2)利用键盘分段测量和自动分段测量。(3)完成单脉冲测量,输入脉冲宽度范围是100ms~0.1s。
(4)显示脉冲宽度要求如下。
Tx<1000ms,显示脉冲宽度×××。
Tx>1000ms,显示脉冲宽度××××。