程序:
(1)主程序:
#include <reg52.h>
#include <intrins.h>
#include "setVar.h"
#include "setvar.c"
#include "LCD1602.h"
#include "MeasureFrequency.h"
#define DATA_MODE_4
void main()
{//初始化各種參數
lcd_init();
while(1)
{ measure_freq(); }
}
(2)頻率測量控制程序:
#include "MeasureFrequency.h"
#include "reg52.h"
#include "setvar.h"
#include "lcd1602.h"
long freqCount1=0;//頻率計數
long freqCount0=0,temp_frecount=0;
uchar TimerCount0=0;
uchar TimerCount1=0;
float fr_float=0;
uchar tempTL1,tempTH1;
uchar level=2;//默認采用高頻測量
uchar timer_count_full=20;//1000ms:89C52+12MHz=20次
ulong freq=0; //測量得到脈沖數目
uchar OK,OK1,num;
uchar start=0;
//測量高頻
//T0定時1000ms,每次50ms/12,20*12次。T1計數,每次溢出65536
void measure_freq()
{ ////配置定時器////
TMOD=0x11;
TH0=0x3c;TL0=0xb0; 65536-50000=15536=3cb0
freqCount0=0;
level=1;
IT0 = 1; //外部中斷0采用邊沿觸發方式;邊沿觸發為1下降沿有效
EX0 = 1; //開外部中斷0
TR1=0;
EX1 = 0; //關閉定時器1和外部中斷1
TR0=1;
EA=1;
OK=0; level=2;
while(!OK);
if(level==1)
{ TR0=0;
EX0=0; //關閉定時器0和外部中斷0
ET1=1;//啟用定時器1中斷
TR1=0;//關閉定時器1
IT1=1; //外部中斷0采用電平觸發方式;邊沿觸發為1下降沿有效
EX1=1; //開外部中斷0
EA=1;
OK1=0;
}
}
void int0() interrupt 0
{ freqCount0++; }
void T0_int() interrupt 1
{ TH0=0x3c;TL0=0xb0;// 65536-50000=15536=3cb0
TimerCount0++;
if(level==2)
{ if(TimerCount0==20)//高頻模式
{ EX0 = 0; //關外部中斷0 temp_frecount=freqCount0;
EA=0; TR0=0;//關閉
TimerCount0=0;
if(temp_frecount>1000)//1K是高頻,低頻的分界線
{ level=2;
lcd_write_long(3,1,(temp_frecount)*0.9993);//若頻率不準,只許修改系數
}
else level=1;//低頻
freqCount0=0;
temp_frecount=0;
OK=1; //標志顯示完成
}
}
}
void int1() interrupt 2
{ freqCount1++;
if(num==1) //脈沖第一次進入
{ TH1=TL1=0;
TimerCount1=0;
TR1=1;//啟用定時器
num=2;
freqCount1=0;
}
if(freqCount1==5)
{ EX1 = 0; //關外部中斷1
TR1=0;//關閉定時器1
tempTH1=TH1;
tempTL1=TL1; fr_float=1000000.0/(TimerCount1*65536+tempTH1*256+tempTL1)*5*0.3334;
//若低頻頻率不準只需改系數1.0000
lcd_write_float(3,1,fr_float);
OK1=1; }
}
void T1_int() interrupt 3
{ TH1=TL1=0;
TimerCount1++; }
#include "LCD1602.h"
//啟動之前,首先延時一段時間
sbit lcd_port_rs=LCD_PORT_RS;
sbit lcd_port_e=LCD_PORT_E;
//LCD延時,等待命令執行完
void lcd_delay(char j)
{ int i=0;
while(j--)
for(i=0;i<300;i++);//i<50 }
//寫入命令,下降沿寫入
void lcd_en()
{ lcd_port_e=1;
lcd_delay(1);
lcd_port_e=0; }
#ifdef LCD_DATA_8_LINE
void lcd_write(char rs_mode,uchar value)
{ lcd_port_rs=rs_mode;
LCD_PORT_DATA=value;
lcd_en();
lcd_delay(10);
}
#endif
#ifdef LCD_DATA_4_LINE
void lcd_write(char rs_mode,uchar value)
{ lcd_port_rs=rs_mode;
//首先發送高4位
LCD_PORT_DATA&=0x0f;
LCD_PORT_DATA|=value&0xf0;//低4位不變,高4為賦值value的高4位
lcd_en();
lcd_delay(1);
LCD_PORT_DATA&=0x0f;
LCD_PORT_DATA|=value<<4; lcd_en();
lcd_delay(1); }
#endif
Void lcd_write_char(uchar x_pos,uchar y_pos,char value)
{ //寫入地址
x_pos&=0x0f;//
y_pos&=0x01;//
if(y_pos) x_pos+=0x40;
x_pos+=0x80;//
lcd_write(0,x_pos);
lcd_delay(10);
lcd_write(1,value); }
void lcd_init()
{ lcd_delay(30); //40ms,等待VDD>4.5V
#ifdef LCD_DATA_8_LINE
lcd_write(0,0x38); lcd_delay(20);//10ms
lcd_write(0,0x38); lcd_delay(2);//1ms
#endif
#ifdef LCD_DATA_4_LINE
lcd_write(0,0x33); lcd_delay(20);//10ms
lcd_write(0,0x32); lcd_delay(20);//10ms
lcd_write(0,0x28); lcd_delay(20);//10ms
#endif
lcd_write(0,0x01);
lcd_delay(10);
lcd_write(0,0x0c); lcd_write(0,0x06);
}
void lcd_write_str(char line,char* str)
{ char i=0;
while(*str)
{ lcd_write_char(i,line,*str);
str++; i++; } }
void lcd_write_long(char x,char y,ulong num)
{
lcd_write_char(x+0,y,char_table[(num/1000000)%10]);
lcd_write_char(x+1,y,char_table[(num/100000)%10]);
lcd_write_char(x+2,y,char_table[(num/10000)%10]);
lcd_write_char(x+3,y,char_table[(num/1000)%10]);
lcd_write_char(x+4,y,char_table[(num/100)%10]);
lcd_write_char(x+5,y,char_table[(num/10)%10]);
lcd_write_char(x+6,y,char_table[num%10]);
lcd_write(1,'H'); lcd_write(1,'Z');
lcd_write(1,' '); lcd_write(1,' ');lcd_write(1,' '); }
void lcd_write_float(char x,char y,float num)
{ lcd_write_char(x+0,y,char_table[((long)num/10000)%10]);
lcd_write_char(x+1,y,char_table[((long)num/10000)%10]);
lcd_write_char(x+2,y,char_table[((long)num/1000)%10]);
lcd_write_char(x+3,y,char_table[((long)num/100)%10]);
lcd_write_char(x+4,y,char_table[((long)num/10)%10]);
lcd_write_char(x+5,y,char_table[(long)num%10]);
lcd_write_char(x+6,y,'.'); lcd_write_char(x+7,y,char_table[(long)(num*10)%10]);
lcd_write(1,'H'); lcd_write(1,'Z');
lcd_write(1,' '); lcd_write(1,' ');lcd_write(1,' ');
}
|