|
简易频率计的仿真图:
频率计51单片机程序:
- #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 s0=P1^3; //待机功能键
- sbit s1=P1^4; //测频率功能键
- sbit s2=P1^5; //测周期功能键
- sbit s3=P1^6; //测占空比功能键
- sbit led1=P3^2; //功能指示灯
- sbit led2=P3^4;
- sbit led3=P3^6;
- sbit t1in=P3^3; //测占空比信号的输入引脚
- sbit lcden=P3^5;
- //uchar code table1[]={" Welcome "};
- uchar i,table[10],q0,q1,q2,q3,q4,q5,q6,q7,table2[9],
- table1[]={"welcome"},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);
- write_com(0x0c);
- write_com(0x01);
- }
-
-
- void key() //按键扫描程序
- {
- if(s0==0) //检测到待机功能键按下
- {
- delay(5);
- if(s0==0)
- {
- while(!s0);
- LCD_init();
- write_com(0x80); //液晶显示"welcome"
- for(i=0;i<8;i++)
- {
- write_date(table1[i]);
- }
- while(1)
- {
- if((s1==0)|(s2==0)|(s3==0)) //如果有别的键按下,退出该功能
- break;
- }
- }
- }
- if(s1==0) //频率功能键按下
- {
- delay(5);
- if(s1==0)
- {
- while(!s1);
- led1=0; //频率指示灯亮,其余灯灭
- led2=1;
- led3=1;
- zq=0; //处于测量频率功能
- LCD_init();
- qingling=0;
- TMOD=0x51; //定义T0工作计时模式,T1工作于计数模式
- TH0=(65536-50000)/256; //给T0装初值,定时5毫秒中断
- TL0=(65536-50000)%256;
- TH1=0; //给T1装初值
- TL1=0;
- ET0=1; //开T0中断
- ET1=0; //关闭T1中断
- TR0=1; //T0开始计时
- TR1=1; //T1开始计数
- while(1)
- { //检测到有别的键按下,退出该功能
- if((s0==0)|(s2==0)|(s3==0))
- break;
- }
- }
- }
- if(s2==0) //周期功能键按下
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- led2=0; //周期指示灯亮,其余灭
- led1=1;
- led3=1;
- zq=1; //处于周期测量功能
- LCD_init();
- qingling=0;
- TMOD=0x51; //定义T0工作计时模式,T1工作于计数模式
- TH0=(65536-50000)/256; //给T0装初值,定时5毫秒中断
- TL0=(65536-50000)%256;
- TH1=0; //给T1装初值
- TL1=0;
- ET0=1; //开T0中断
- ET1=0; //关T1中断
- TR0=1; //T0开始计时
- TR1=1; //T1开始计数
- while(1)
- { //如果有别的键按下,退出该功能
- if((s0==0)|(s1==0)|(s3==0))
- break;
- }
- }
- }
- if(s3==0) //占空比功能键按下
- {
- delay(5);
- if(s3==0);
- {
- while(!s3);
- led3=0; //占空比指示灯亮,其余灭
- led1=1;
- led2=1;
- TMOD=0x10; //T0不工作,T1为定时器模式
- 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[i]);
- }
- delay(5); //延时
- T1num=0;
- th1=0;
- tl1=0;
- T0num=0;
- TH1=0;
- TL1=0;
- if((s0==0)|(s1==0)|(s2==0))
- break; //如果检测到有别的键按下,退出该功能
- }
- }
- }
- }
- void main()
- {
- int i ;
- LCD_RW=0;
- LCD_init();
- write_com(0x80);
- for(i=0;i<14;i++)
- {
- write_date(table1[i]);
- delay(2);
- }
- //write_com(0x01);
- EA=1;
- while(1)
- {
- key(); //按键扫描
- }//(0xff!=key)
- }//main
- void T0_time()interrupt 1 //定时器T0中断函数
- {
- TH0=(65536-50000)/256; //装初值
- TL0=(65536-50000)%256;
- num++;
- if(num==20) //一秒时间到
- {
- 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[i]+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[i]);
- }
- 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++;
- }
复制代码
|
评分
-
查看全部评分
|