代码如下:
/************************************
频率部分
************************************/
#include <reg51.h>
#include <intrins.h>
#define out P0
#define send P2
unsigned int ADresult[11];
sbit DATOUT=P1^0;
sbit DATIN=P1^1;
sbit CS=P1^2;
sbit IOCLK=P1^3;
sbit EOC=P1^4;
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^5;
sfr16 DPTR=0x82;//定义寄存器DPTR(频率部分)
unsigned char cnt_t0,cnt_t1,qian,bai,shi,ge;
unsigned char freq;
unsigned char code digit[10]={"0123456789"};
unsigned char code Str_V[]={"V="};
unsigned char code Str_U[]={"Vm="};
unsigned char code Str_F[]={"F="};
void delay_ms(unsigned int z)
{
unsigned char i,j;
for(i=0;i<z;i++)
for(j=0;j<110;j++);
}
/**********************************
定时器的初始化
**********************************/
void init()
{
freq=0;//赋频率初值
cnt_t1=0;
cnt_t0=0;
IE=0x8a;//开T0,T1中断
TMOD=0x15;//T0为定时器方式1,T1为计数器方式1
TH1=0x3c;//T1定时50ms
TL1=0xb0;
TH0=0;//T0清0
TL0=0;
TR0=1;//开启定时器T0
}
/********************************
lcd1602的准备工作
********************************/
void check_busy()//检测忙函数
{
unsigned char dt;
do{
dt=0xff;//dt作为变量单元,初值为0xff
E=0;
RS=0;//按照读写操作规定RS=0,E=1时才可以读忙标志
RW=1;
E=1;
dt=out;
}while(dt&0x80);
E=0;
}
void write_command(unsigned char com)//写命令函数
{
check_busy();
E=0;
RS=0;
RW=0;
out=com;
E=1;
_nop_();
_nop_();
E=0;
delay_ms(10);
}
void write_data(unsigned char dat)//写数据函数
{
check_busy();
E=0;
RS=1;
RW=0;
out=dat;
E=1;
_nop_();
E=0;
delay_ms(10);
}
void LCD_initial(void)//液晶显示器的初始化函数
{
write_command(0x38);//写入0x38(命令6):两行显示,5*7点阵,8位数据
_nop_(); //空操作,给硬件反应时间
write_command(0x0C);//写入0x0C(命令4):开整体显示,光标关,无闪烁
_nop_(); //空操作,给硬件反应时间
write_command(0x06);//写入0x06(命令3),写入一个字符后,地址指针加1
_nop_(); //空操作,给硬件反应时间
write_command(0x01);//写入(命令1):清屏
delay_ms(10);
}
/****************************
lcd1602上符号的显示
****************************/
void display_V(void)//显示‘V=’
{
unsigned char i;
write_command(0x80);
i=0;
while(Str_V[i]!='\0')
{
write_data(Str_V[i]);
i++;
}
}
void display_U(void)//显示‘Vm=’
{
unsigned char i;
write_command(0x88);
i=0;
while(Str_U[i]!='\0')
{
write_data(Str_U[i]);
i++;
}
}
void display_F(void)//显示‘F=’
{
unsigned char i;
write_command(0x40+0x80);
i=0;
while(Str_F[i]!='\0')
{
write_data(Str_F[i]);
i++;
}
}
void display_Hz(void)//频率的单位‘Hz’的显示
{
write_command(0x47+0x80);
write_data('H');
write_command(0x48+0x80);
write_data('z');
}
void display_mV(void)
{
write_command(0x05+0x80);//V的单位‘mv’的显示
write_data('m');
write_command(0x06+0x80);
write_data('v');
write_command(0x0e+0x80);//Vm的单位'mv'的显示
write_data('m');
write_command(0x0f+0x80);
write_data('v');
}
/********************************
将数据输出到lcd1602上
********************************/
void displayV(unsigned char x)//V值送lcd1602
{
unsigned char i,j,k;
i=x/100;
j=x/10%10;
k=x%10;
write_command(0x05+0x80);
write_command(0x04+0x80);
write_command(0x03+0x80);
write_data(digit[i]);
write_data(digit[j]);
write_data(digit[k]);
}
void displayU(unsigned char x)//Vm值送lcd1602
{
unsigned char l,w,n;
l=x*141/100/100;
w=x*141/100/10%10;
n=x*141/100%10;
write_command(0x0d+0x80);
write_command(0x0b+0x80);
write_data(digit[l]);
write_data(digit[w]);
write_data(digit[n]);
}
void displayF(unsigned char x)//频率值送lcd1602
{
qian=x/1000 ;
bai= x/100%10 ;
shi=x/10%10;
ge=x%10 ;
write_command(0x46+0x80);
write_command(0x45+0x80);
write_command(0x44+0x80);
write_command(0x43+0x80);
write_data(digit[qian]);
write_data(digit[bai]);
write_data(digit[shi]);
write_data(digit[ge]);
}
/**********************************
中断函数(频率部分)
**********************************/
void t1_func() interrupt 3
{
TH1=0x3c;
TL1=0xb0;
cnt_t1++;
}
void t0_func() interrupt 1
{
cnt_t0++;
}
/*********************************
电压数据获取函数
*********************************/
unsigned int getdata(unsigned char channel)//channel是通道号
{
unsigned char i,temp;
unsigned int read_ad_data=0;
channel=channel<<4;
IOCLK=0;
CS=0;
temp=channel;
for(i=0;i<12;i++)
{
if(DATOUT)read_ad_data=read_ad_data|0x01;//读入第一次的数据
DATIN=(bit)(temp&0x80);//写入方式/通道命令字
IOCLK=1; //IOCLK上跳沿
_nop_(); //空操作延时
_nop_();
_nop_();
IOCLK=0; //IOCLK下跳沿
_nop_(); //空操作延时
_nop_();
_nop_();
temp=temp<<1; //丢弃最高位,读取第二高位的值
read_ad_data<<=1; //转换结果左移一位
}
CS=1; //CS上跳沿
read_ad_data<<=1; //抵消第12次左移,得到12位转换结果
return(read_ad_data);
}
/*********************************
主函数
*********************************/
main(void)
{
init();//定时器初始化
LCD_initial();//lcd1602初始化
display_Hz();//各类字符的显示
_nop_();
display_F();
_nop_();
display_V();
_nop_();
display_U();
_nop_();
display_mV();
_nop_();
/************************
主函中频率部分
************************/
while(1)
{
if(cnt_t1==19)//定时1s
{
cnt_t1=0;
TR1=0;
delay_ms(141);
TR0=0;
DPL=TL0;
DPH=TH0;
freq=cnt_t0*65535;
freq=freq+DPTR;
}
send=freq;//数据送到P2口
displayF(send);//通过P2发出去
_nop_();
}
/***********************
主函数中电压部分
************************/
while(1)
{
_nop_();
_nop_();
_nop_();
ADresult[2]=getdata(2);
while(!EOC);
out=ADresult[2]*122;//数据送到P0口
displayV(out);//改成1602的显示方式
_nop_();
_nop_();
displayU(out);//通过P0发出去
_nop_();
}
}
|