找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4443|回复: 0
打印 上一主题 下一主题
收起左侧

51简单频率计设计程序

[复制链接]
跳转到指定楼层
楼主
ID:208888 发表于 2017-6-8 21:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序:
(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,' ');
}  

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表