我的做的頻率計仿真遇到問題了,希望大家幫幫我。問題1:按鍵切換到待機狀態時,我要顯示的是:PIN LV JI 可后面還有一串數字,我不知道怎么去掉。如下
QQ截圖20180507105449.png (9.58 KB, 下載次數: 36)
下載附件
2018-5-7 10:53 上傳
問題2:我要求測量頻率最大值為10k,為什么測不出來呢,頻率越大l602 顯示的時間越長,甚至顯示不出來。如下
2.png (49.17 KB, 下載次數: 38)
下載附件
2018-5-7 10:58 上傳
程序如下:
#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++;
}
|