| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5097 人关注过本帖
标题:基于AT89S52单片机的双路频率计的程序源码
只看楼主 加入收藏
hlmzrdongdong
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:湖北武汉
等 级:版主
威 望:1
帖 子:99
专家分:145
注 册:2008-10-24
结帖率:100%
收藏
 问题点数:0 回复次数:11 
基于AT89S52单片机的双路频率计的程序源码
#include <REG51.H>
#include<INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
uint time1=0,time2=0,frequency1=0,frequency2=0;
uint test_error1,test_error2,test_button;
uchar Fw,Fq,Fb,Fs,Fg;
#define DataPort P0        //定义液晶数据传输口
sbit LCM_RS=P1^0;          //定义液晶显示控制口
sbit LCM_RW=P1^1;
sbit LCM_EN=P1^2;
sbit Switch_button1=P1^3;   //定义第一路频率计开关控制口
sbit Switch_button2=P1^4;   //定义第二路频率计开关控制口

uchar code Welcome_str[]={"--Welcome!--  "};
uchar code Startcommand_str[]={"Switch--Start!  "};
uchar code Error_str[]={"Error! "};
uchar code Freq_str[]={" Freq1    Freq2 "};
uchar code Hz_str[]={"00000Hz  00000Hz"};

/**********************************************************
函数名:Delay5ms
功能:延时约5ms
参数:无
返回值:无
***********************************************************/
void Delay5ms(void)
{
     uint i=2000;
     while (i !=0)
     {i--;}
}
/**********************************************************

/**********************************************************
函数名:Wait_Enable
功能:等待1602液晶完成内部操作
参数:无
返回值:无
***********************************************************/
void Wait_Enable(void)
{
 DataPort=0xff;                      //DataPort=11111111切换PO口为输入状态
 LCM_RS=0;                           //RS为低电平,RW为高电平时才可以读忙信号
 LCM_RW=1;
 _nop_();
 LCM_EN=1;
 _nop_();
 _nop_();
 while(DataPort&0x80){};            //相与等于0,说明BF为0,不忙;等于1,BF=1,忙碌
 LCM_EN=0;                          //判断忙碌之后,置位EN=0,液晶不执行任何操作
}

/**********************************************************
函数名:Write_Command
功能:向液晶模块写入命令
参数:cmd--命令
      chk--是否判忙的标志,1:判忙,0:不判
返回值:无
***********************************************************/
void Write_Command(uchar cmd,uchar chk)
{
 if(chk)Wait_Enable();
 LCM_RS=0;                      //当RS和RW都为低电平时才可以写入指令或者显示地址
 LCM_RW=0;
 _nop_();
 DataPort=cmd;                  //将命令置入数据总线
 _nop_();
 LCM_EN=1;
 _nop_();
 _nop_();
 LCM_EN=0;                      //EN由高电平到低电平,液晶执行写指令操作
}

/**********************************************************
函数名:Write_Data
功能:向液晶显示的当前地址写入显示数据
参数:data--显示字符数据
返回值:无
***********************************************************/
void Write_Data (uchar datas)
{
 Wait_Enable();
 LCM_RS=1;                          //RS高电平,RW低电平时可以写入数据
 LCM_RW=0;
 _nop_();
 DataPort=datas;                    //置数据到数据总线
 _nop_();
 LCM_EN=1;
 _nop_();
 _nop_();
 LCM_EN=0;
}

/**********************************************************
函数名:void InitLcd()
功能:对LCD1602进行初始化
参数:无
返回值:无
**********************************************************/
void InitLcd()
{
 Write_Command(0x3c,1);              //设置显示模式:8位2行5*7点阵
 Write_Command(0x08,1);              //显示器关,不显示光标,光标不闪烁
 Write_Command(0x01,1);              //清屏并光标复位
 Write_Command(0x06,1);              //文字不动,光标自动右移
 Write_Command(0x0c,1);              //显示开,不开光标,不闪烁
}

/**********************************************************
函数名:void DisplayOneChar(uchar X,uchar Y,uchar Data)
功能:在指定位置第y行第x列显示一个字符
参数:X--列坐标  Y--行坐标  Data--欲显示字符
返回值:无
**********************************************************/
void DisplayOneChar(uchar X,uchar Y,uchar Datas)
{
 Y&=1;
 X&=15;
 if(Y)X|=0x40;
 X|=0x80;
 Write_Command(X,0);
 Write_Data(Datas);
}

/**********************************************************
函数名:void DisplayListChar(uchar X,uchar Y,uchar code *Data
功能:以起始位置第Y行第X列开始显示一串字符
参数:X--起始列坐标  Y--起始行坐标  Data--欲显示字符串首地址
返回值:无
**********************************************************/
void DisplayListChar(uchar X,uchar Y,uchar code *Datas)
{
 uchar ListLength=0;
 Y&=0x1;
 X&=0xF;
 while(X<=15)
 {
 DisplayOneChar(X,Y,Datas[ListLength]);
 ListLength++;
 X++;
}
}

/**********************************************************
函数名:void display()
功能:提取欲显示数字各位送显示
参数:k--欲显示的行  kk--显示的最后一位列地址
返回值:无
**********************************************************/
void display(uint count ,uint k )
{
 Fw=count/10000+0x30;             //提取万位
 Fq=count/1000%10+0x30;           //提取千位
 Fb=count/100%10+0x30;            //提取百位
 Fs=count/10%10+0x30;             // 提取十位
 Fg=count%10+0x30;                //提取个位

 DisplayOneChar(k,1,Fg);
 DisplayOneChar(--k,1,Fs);
 DisplayOneChar(--k,1,Fb);
 DisplayOneChar(--k,1,Fq);
 DisplayOneChar(--k,1,Fw);
}

/********************************************************
函数名:void Set_singlechip(void)
功能: 单片机中断设置
参数:无
返回值:无
**********************************************************/
void Set_singlechip(void)
 {
   TCON=0x05;          //外中断INT0、INT1工作于下跳沿触发方式
   TMOD=0x11;          //定时计数器T0、T1工作在16位定时器方式
   EA=1;               //设置CPU开放中断
   ET0=1;ET1=1;        //定时器T0、T1中断允许
   PT0=1;PT1=1;        //设定定时器T0、T1为高优先级
}

/*********************************************************
函数名:void Set_Interrupt(void)
功能:根据二路测频开关开闭情况对对应中断与定时器设置
参数:无
返回值:无
***********************************************************/
void Set_Interrupt(void)
{
 if((Switch_button1==0)&(Switch_button2==1))
 {

  EX0=1;TR0=1;
  EX1=0;TR1=0;
 }
 else if((Switch_button1==1)&(Switch_button2==0))
 {

  EX1=1;TR1=1;
  EX0=0;TR0=0;
 }
 else if((Switch_button1==0)&(Switch_button2==0))
 {
  EX1=1;TR1=1;
  EX0=1;TR0=1;
 }
 else if((Switch_button1==1)&(Switch_button2==1))
 {
 while(1){;}
 }
}

/**********************************************************
函数名:void Interrupt_counter1(void)small interrupt 0
功能:外中断INT0服务模块,进入中断则计数单元加一
参数:无
返回值:无
**********************************************************/
void Interrupt_counter1(void)small interrupt 0
{
frequency1+=1;
if(frequency1==0)test_error1+=1;
}

/**********************************************************
函数名:void Interrupt_counter2(void)small interrupt 2
功能:外中断INT1服务模块,进入中断则计数单元加一
参数:无
返回值:无
**********************************************************/
void Interrupt_counter2(void)small interrupt 2
{
frequency2+=1;
if(frequency2==0)test_error2+=1;
}

/**********************************************************
函数名:void Interrupt_timer1(void)small interrupt 1
功能:让定时器T0以10000us每次工作100次,总定时1s
参数:无
返回值:无
**********************************************************/
void Interrupt_timer1(void)small interrupt 1
{
if(time1>100)
 {
 TR0=0;
 EX0=0;
 if(test_error1)
 {
 test_error1=0;
 DisplayListChar(0, 1,Error_str);
 }
 else
  {
  frequency1=((uint)(((float)frequency1)/1024.0*1000.0))+1;
  display(frequency1,4);
  TH0=0xD8;TL0=0xF0;
  time1=0;
  frequency1=0;
  Set_Interrupt();
  }
 }
else
 {
 TH0=0xD8;TL0=0xF0;
 time1++;
 }
}

/**********************************************************
函数名:void Interrupt_timer2(void)small interrupt 3
功能:让定时器T1以10000us每次工作100次,总定时1s
参数:无
返回值:无
**********************************************************/
void Interrupt_timer2(void)small interrupt 3
{
if(time2>100)
 {
 TR1=0;
 EX1=0;
 if(test_error2)
 {
 test_error2=0;
 DisplayListChar(9, 1,Error_str);
 }
 else
  {
  frequency2=((uint)(((float)frequency2)/1024.0*1000.0))+1;
  display(frequency2,13);
  TH1=0xD8;TL1=0xF0;
  time2=0;
  frequency2=0;
  Set_Interrupt();
  }
 }
else
 {
 TH1=0xD8;TL1=0xF0;
 time2++;
 }
}

/**********************************************************
函数名:void main(void)
作用:主函数
**********************************************************/
void main(void)
{
 InitLcd();                                    //LCD初始化设置

 DisplayListChar(2,0,Welcome_str);             //显示“欢迎”界面
 DisplayListChar(1,1,Startcommand_str);        //显示“开启记数”提示


 Set_singlechip();                             //单片机中断设置

 TH0=0xD8;TL0=0xF0;                            //定时器装入初值
 TH1=0xD8;TL1=0xF0;

 while((Switch_button1==1)&(Switch_button2==1)){;}   //等待计数开关开启
 InitLcd();                                    //液晶复位
 DisplayListChar(0,0,Freq_str);
 DisplayListChar(0,1,Hz_str);
 Set_Interrupt();
 while(1){;}
}
电路图见附件

[[it] 本帖最后由 hlmzrdongdong 于 2008-10-24 23:14 编辑 [/it]]

电路图.JPG (52.18 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册


电路图.JPG (52.18 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册
收到的鲜花
  • WSY3792008-10-25 19:14 送鲜花  10朵   附言:呵呵 强悍
搜索更多相关主题的帖子: 频率 源码 单片机 
2008-10-24 23:10
WSY379
Rank: 6Rank: 6
来 自:网络农民
等 级:贵宾
威 望:28
帖 子:1293
专家分:3
注 册:2007-6-24
收藏
得分:0 
支持…………

/祈福/如果生命以如残喘~!那我活着的唯一意义就是你!~所以我封存了所有的记忆~!等你回来~!!!!!!!
2008-10-25 19:14
WSY379
Rank: 6Rank: 6
来 自:网络农民
等 级:贵宾
威 望:28
帖 子:1293
专家分:3
注 册:2007-6-24
收藏
得分:0 
做了一个检测喂狗程序 可是依然死机?经常性单片机数据采集不到 有时候通讯失败 为什么?程序代码无法发过来 麻烦有经验的帮忙处处类似的现象解决办法 理论上是不可能单片机在死机了?我的单片机有问题?

/祈福/如果生命以如残喘~!那我活着的唯一意义就是你!~所以我封存了所有的记忆~!等你回来~!!!!!!!
2008-10-25 19:18
hlmzrdongdong
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:湖北武汉
等 级:版主
威 望:1
帖 子:99
专家分:145
注 册:2008-10-24
收藏
得分:0 
回复 3# WSY379 的帖子
提共的症状有点简单,我猜猜吧。
AD是否有问题,时序是否正确,接口芯片是否有问题?
仅供参考。
收到的鲜花
  • WSY3792008-10-31 13:59 送鲜花  5朵   附言:谢谢了 你基本猜对了-_-! 我的晶振用错型号 ...
2008-10-25 22:03
WSY379
Rank: 6Rank: 6
来 自:网络农民
等 级:贵宾
威 望:28
帖 子:1293
专家分:3
注 册:2007-6-24
收藏
得分:0 
谢谢楼上  问题找到了  数据采集不到是频率错误 但是手哆嗦了敲错了 外部晶振也不对

/祈福/如果生命以如残喘~!那我活着的唯一意义就是你!~所以我封存了所有的记忆~!等你回来~!!!!!!!
2008-10-31 14:00
a331333835
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2009-8-19
收藏
得分:0 
不错 !!~
2009-08-19 10:26
longwang
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2009-7-20
收藏
得分:0 
好样的
2009-08-27 17:19
l13hq
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2010-5-14
收藏
得分:0 
2010-05-14 12:40
kjyhaohbv
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2010-10-25
收藏
得分:0 
顶!!!!!!!
2010-10-25 19:37
zxd1965
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2011-6-5
收藏
得分:0 
不错,顶
2011-06-06 01:00
快速回复:基于AT89S52单片机的双路频率计的程序源码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019566 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved