我的做的频率计仿真遇到问题了,希望大家帮帮我。问题1:按键切换到待机状态时,我要显示的是:PIN LV JI 可后面还有一串数字,我不知道怎么去掉。如下
问题2:我要求测量频率最大值为10k,为什么测不出来呢,频率越大l602 显示的时间越长,甚至显示不出来。如下
程序如下:
#include <reg52.h>
# define uchar unsigned char
# define uint unsigned int
# define ulong unsigned long
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_EN=P1^2;
sbit Q0=P2^0; //计数器0位
sbit Q1=P2^1; //计数器1位
sbit Q2=P2^2; //计数器2位
sbit Q3=P2^3; //计数器3位
sbit Q4=P2^4; //计数器4位
sbit Q5=P2^5; //计数器5位
sbit Q6=P2^6; //计数器6位
sbit Q7=P2^7; //计数器7位
sbit kaishi=P3^0; //频率计数的逻辑开关
sbit qingling=P3^1; //计数器清零信号端
sbit KEY0=P1^3; //待机功能键
sbit KEY1=P1^4; //测频率功能键
sbit KEY2=P1^5; //测周期功能键
sbit KEY3=P1^6; //测占空比功能键
sbit LED1=P3^2; //功能指示灯
sbit LED2=P3^4;
sbit LED3=P3^6;
sbit LED0=P1^7;
sbit t1in=P3^3; //测占空比信号的输入引脚
sbit lcden=P3^5;
uchar i,table[10],q0,q1,q2,q3,q4,q5,q6,q7,table2[9],
table1[]={"PIN LV JI"},dis[5],T0num,T1num,th1,tl1;
uint num,bizhi;
ulong pinglv,time1,time0;
bit zq=0; //频率周期标志位
void delay(uint time)
{
uint i,j;
for(i=time;i>0;i--)
for(j=110;j>0;j--);
}
void write_com(uchar com)
{
LCD_RS=0; //写命令
LCD_RW=0;
P0=com;
delay(2);
LCD_EN=1;
delay(2);
LCD_EN=0;
}
void write_date(uchar date)
{
LCD_RS=1; //写数据
LCD_RW=0;
P0=date;
delay(2);
LCD_EN=1;
delay(2);
LCD_EN=0;
}
void LCD_init()
{
write_com(0x38); //设置16x2显示,5x7点阵,8位数据接口
write_com(0x0c); //开显示,不显示光标,光标不闪烁
// write_com(0x06); //写入一个字符后指针地址加1,写一个字符时整屏不移动
write_com(0x01); //清屏显示,数据指针清零,所以显示清零
}
void key() //按键扫描程序
{
if(KEY0==0) //检测到待机功能键按下
{
delay(5);
if(KEY0==0)
{
while(!KEY0);
LED0=0;
LED1=1;
LED2=1;
LED3=1;
LCD_init();
write_com(0x80); //液晶显示"pinlvji"
for(i=0;i<16;i++)
{
write_date(table1);
}
while(1)
{
if((KEY1==0)|(KEY2==0)|(KEY3==0)) //如果有别的键按下,退出该功能
break;
}
}
}
if(KEY1==0) //频率功能键按下
{
delay(5);
if(KEY1==0)
{
while(!KEY1);
LED0=1;
LED1=0; //频率指示灯亮,其余灯灭
LED2=1;
LED3=1;
zq=0; //处于测量频率功能
LCD_init();
qingling=0;
TMOD=0x51; //定义T0工作计时模式,方式1,T1工作于计数模式,方式1计数最大65536
TH0=(65536-50000)/256; //给T0装初值,定时50毫秒中断
TL0=(65536-50000)%256;
TH1=0; //给T1装初值
TL1=0;
ET0=1; //开T0中断
ET1=0; //关闭T1中断
TR0=1; //T0开始计时
TR1=1; //T1开始计数
while(1)
{ //检测到有别的键按下,退出该功能
if((KEY0==0)|(KEY2==0)|(KEY3==0))
break;
}
}
}
if(KEY2==0) //周期功能键按下
{
delay(5);
if(KEY2==0)
{
while(!KEY2);
LED0=1;
LED2=0; //周期指示灯亮,其余灭
LED1=1;
LED3=1;
zq=1; //处于周期测量功能
LCD_init();
qingling=0;
TMOD=0x51; //定义T0工作计时模式,T1工作于计数模式
TH0=(65536-50000)/256; //给T0装初值,定时50毫秒中断
TL0=(65536-50000)%256;
TH1=0; //给T1装初值
TL1=0;
ET0=1; //开T0中断
ET1=0; //关T1中断
TR0=1; //T0开始计时
TR1=1; //T1开始计数
while(1)
{ //如果有别的键按下,退出该功能
if((KEY0==0)|(KEY1==0)|(KEY3==0))
break;
}
}
}
if(KEY3==0) //占空比功能键按下
{
delay(5);
if(KEY3==0);
{
while(!KEY3);
LED0=1;
LED3=0; //占空比指示灯亮,其余灭
LED1=1;
LED2=1;
TMOD=0x10; //T0不工作,T1为定时器模式,方式2,8位自动重装初值
ET0=0; //T0中断关闭
ET1=1; //打开T1中断
TH1=0; //给T1装初值
TL1=0;
LCD_init(); //液晶清屏
while(1)
{
while(!t1in); //确认输入信号处于低电平
// while(t1in); //检测到高电平
TR1=1; //开始计时 '
while(!t1in); //高电平变低电平
tl1=TL1; //读取T1的值
th1=TH1;
T1num=T0num;
//while(t1in); //再次检测到高电平
TR1=0; //停止计时
time0=T0num*65536+TH1*256+TL1; //一个周期的时间
time1=T1num*65536+th1*256+tl1; //高电平的时间
bizhi=time1*1000/time0; //计算占空比
dis[0]=bizhi/100+0x30; //数据处理
dis[1]=bizhi%100/10+0x30;
dis[2]=0x2e;
dis[3]=bizhi%10+0x30;
dis[4]=0x25;
write_com(0x80);
for(i=0;i<5;i++) //数据显示
{
write_date(dis);
}
delay(5); //延时
T1num=0;
th1=0;
tl1=0;
T0num=0;
TH1=0;
TL1=0;
while(1)
{
if((KEY0==0)|(KEY1==0)|(KEY2==0))
break;
} //如果检测到有别的键按下,退出该功能
}
}
}
}
void main()
{
int i ;
LCD_init(); //LCD1602初始化
write_com(0x80);
for(i=0;i<14;i++)
{
write_date(table1);
delay(2);
}
EA=1;
while(1)
{
key(); //按键扫描
}
}
void T0_time()interrupt 1 //定时器T0中断函数
{
TH0=(65536-50000)/256; //装初值
TL0=(65536-50000)%256;
num++;
if(num==2) //时间到
{
TR1=0; //停止计数
kaishi=0; //计数停止
TR0=0; //停止计时
q0=Q0; //读取计数器的值
q1=Q1;
q2=Q2;
q3=Q3;
q4=Q4;
q5=Q5;
q6=Q6;
q7=Q7;
pinglv=TH1*65536+TL1*256+q7*128+q6 //计算频率
*64+q5*32+q4*16+q3*8+q2*4+q1*2+q0;
if(zq==0) //如果处于频率测量
{ //频率数据处理
table[0]=pinglv/10000000;
table[1]=pinglv%10000000/1000000;
table[2]=pinglv%1000000/100000;
table[3]=pinglv%100000/10000;
table[4]=pinglv%10000/1000;
table[5]=pinglv%1000/100;
table[6]=pinglv%100/10;
table[7]=pinglv%10;
table[8]='H';
table[9]='z';
write_com(0x80);
for(i=0;i<8;i++) //显示频率
{
write_date(table+0x30);
}
write_date(table[8]);
write_date(table[9]);
}
if(zq==1) //处于周期测量
{
if(pinglv<=1000) //频率小于等于1000
{ //周期数据处理
table2[0]=10000/pinglv/10000+0x30;
table2[1]=10000/pinglv%10000/1000+0x30;
table2[2]=10000/pinglv%1000/100+0x30;
table2[3]=10000/pinglv%100/10+0x30;
table2[4]=0x2e;
table2[5]=10000/pinglv%10+0x30;
table2[6]=100000/pinglv%10+0x30;
table2[7]=0x6d;
table2[8]=0x73;
}
if(pinglv>1000) //频率大于1000
{ //周期数据处理
table2[0]=0+0x30;
table2[1]=10000000/pinglv/1000+0x30;
table2[2]=10000000/pinglv%1000/100+0x30;
table2[3]=10000000/pinglv%100/10+0x30;
table2[4]=0x2e;
table2[5]=10000000/pinglv%10+0x30;
table2[6]=100000000/pinglv%10+0x30;
table2[7]=0x75;
table2[8]=0x73;
}
write_com(0x80); //显示周期
for(i=0;i<9;i++)
write_date(table2);
}
delay(10);
TH1=0; //给T1装初值
TL1=0;
TH0=(65536-50000)/256; //给T0装初值
TL0=(65536-50000)%256;
num=0;
qingling=1; //计数器清零
delay(10);
qingling=0;
kaishi=1; //再次开始测量
TR0=1; //T0开始计时
TR1=1; //T1开始计数
}
}
void T1_time()interrupt 3 //定时器T1中断函数
{
T0num++;
}
|