打印
[51单片机]

打算用51的定时器和外部中断做个频率计,为什么总是实现不了呢,求大神给看一下

[复制链接]
8410|47
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
灯火阑珊处|  楼主 | 2014-8-4 10:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1602的部分就不用看了

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

void delayms(unsigned char ms)                //延时程序

{                                               
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i < 120; i++);
        }
}

sbit rs=P2^5;                //1602                                  
sbit rw=P2^6;                //
sbit e=P2^7;                //


uchar table1[]="0123456789";
long int k=0,m,n,flag=0;
long int g,s,b,q,w;
long double i,t;

void display();                   //显示函数

void write_com(uchar com)                          //1602写入指令
{
  e=0;
  rs=0;
  rw=0;
  P0=com;
  delayms(1);
  e=1;
  delayms(5);
  e=0;

}


void write_data(uchar dat)                          //1602写入数据
{
  e=0;
  rs=1;
  rw=0;
  P0=dat;
  delayms(1);
  e=1;
  delayms(5);
  e=0;
}

void init(void)                                                         //1602初始化设置程序
{
  delayms(15);
  write_com(0x38);
  delayms(5);
  write_com(0x38);
  delayms(5);
  write_com(0x38);
  write_com(0x38);
  write_com(0x08);
  write_com(0x01);
  write_com(0x06);
  write_com(0x0c);
  

}




main()                                  //主函数
{
       
        EA=1;                //中断总开关
        EX0=1;           //外部中断
        IT0=1;           //负跳变沿触发

                TMOD=0x01;         //定时器0 方式1
                TH0=0;                  //初值 高8位
                TL0=0;                  //初值低8位
                EA=1;
        //        ET0=1;                 //打开定时器中断
        //        TR0=1;                 //启动定时器
        while(1)
        {       
                display();
        }
               

}

void timer0() interrupt 1
{
               k++;                 //计数器溢出值
                   TH0=0;
                   TL0=0;
                  
                  
                  
}

void int0() interrupt 0
{
          if(flag==0)                 //第一次中断
          {
                  i=0;
                k=0;
                TH0=0;
                TL0=0;
                ET0=1;                //打开定时器中断
                TR0=1;                //
                flag++;
          }
          
          if(flag==1)           //第二次中断
          {                                                 
          m=TH0;
          n=TL0;
          
          ET0=0;          //关闭定时器中断
          TR0=0;           //
          flag=0;
         
          t=k*65536+256*m+n;          //被测频率的一个周期
          
          i=100000/t;                           //频率                                                          
                        
         }                       
                                                                                      
}

void display()
{                                               
                               
                               
                       
                           g=(long int)i%10;                        //        个位
                           s=(long int)i/10%10;                        //         十
                           b=(long int)i/100%10;           //          百
                           q=(long int)i/1000%10;                  //   千               
                           w=(long int)i/10000;                        //          万
                               
                                init();
                                   write_com(0x80);                           //显示
                                   write_data(table1[w]);
                                   delayms(10);
   
                                   write_com(0x81);
                                   write_data(table1[q]);
                                   delayms(10);
   
                                   write_com(0x82);
                                   write_data(table1);
                                   delayms(10);
   
                                   write_com(0x83);
                                   write_data(table1);
                                   delayms(10);
                               
                                write_com(0x84);
                                   write_data(table1[g]);
                                   delayms(10);

                        while(1);                                                                                                          
                  
       
}




相关下载

相关帖子

沙发
灯火阑珊处|  楼主 | 2014-8-4 10:19 | 只看该作者
求大神啊,上午在线等

使用特权

评论回复
板凳
灯火阑珊处|  楼主 | 2014-8-4 10:38 | 只看该作者
木有人来啊

使用特权

评论回复
地板
灯火阑珊处|  楼主 | 2014-8-4 10:45 | 只看该作者
自己顶一下,别沉了啊

使用特权

评论回复
5
灯火阑珊处|  楼主 | 2014-8-4 11:13 | 只看该作者

使用特权

评论回复
6
cjseng| | 2014-8-4 11:16 | 只看该作者
t=k*65536+256*m+n;          //被测频率的一个周期
         
          i=100000/t;                           //频率     

这两句要耗费大量的时间,导致中断程序耗时过长,不能及时响应下一个中断,最终频率测量不准。
其它的没细看。

使用特权

评论回复
7
灯火阑珊处|  楼主 | 2014-8-4 11:23 | 只看该作者
cjseng 发表于 2014-8-4 11:16
t=k*65536+256*m+n;          //被测频率的一个周期
         
          i=100000/t;                    ...

额,,, 为什么这两句要用好长时间呢?

使用特权

评论回复
8
longmaodo| | 2014-8-4 13:50 | 只看该作者
if(flag==0)                 //第一次中断
          {
                  i=0;
                k=0;
                TH0=0;
                TL0=0;
                ET0=1;                //打开定时器中断
                TR0=1;                //
                flag++;
          }
         
          if(flag==1)   
这里  一次中断两个IF都执行了 。。。

使用特权

评论回复
9
longmaodo| | 2014-8-4 13:52 | 只看该作者
应该是
if(flag == 0)
{
code;
flag++;
}
else if(flag == 1)
{
code;
flag = 0;
}

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
灯火阑珊处 + 1 很给力!
10
longmaodo| | 2014-8-4 13:56 | 只看该作者
灯火阑珊处 发表于 2014-8-4 11:23
额,,,  为什么这两句要用好长时间呢?

单片机计算* /用时长 建议不要这个用,可试试使用移位操作 而且最好判断除数是否为0  

使用特权

评论回复
11
很忙| | 2014-8-4 14:05 | 只看该作者
楼上的很对。
觉得这个t=k*65536+256*m+n;    时间长的话就用移位来做,时间就很短了。
t=(k<<16)|(m<<8)|n;

使用特权

评论回复
12
灯火阑珊处|  楼主 | 2014-8-4 15:56 | 只看该作者
longmaodo 发表于 2014-8-4 13:52
应该是
if(flag == 0)
{

有道理  这确实是有问题啊

使用特权

评论回复
13
灯火阑珊处|  楼主 | 2014-8-4 16:00 | 只看该作者
很忙 发表于 2014-8-4 14:05
楼上的很对。
觉得这个t=k*65536+256*m+n;    时间长的话就用移位来做,时间就很短了。
t=(k ...

有道理啊 懂的真多呀

使用特权

评论回复
14
灯火阑珊处|  楼主 | 2014-8-4 16:15 | 只看该作者
一些问题修改之后1602还是输出00000,是不是哪里有更大的问题啊[em:24:][em:24:][em:24:][em:24:][em:24:][em:24:][em:24:][em:24:][em:24:][em:24:]

使用特权

评论回复
15
longmaodo| | 2014-8-4 16:25 | 只看该作者
灯火阑珊处 发表于 2014-8-4 16:15
一些问题修改之后1602还是输出00000,是不是哪里有更大的问题啊[ ...

你可以断点调试吗  
如果可以  那你就幸福了 只要一步一步的检测那个地方出错了就行了
如果不行 你最好先确定问题的位置  一步步排除 比如先测试1206显示没问题
再确定你的采集回来的数据  
PS:顺便问一下 你的时钟是多少 你这样设计是基于你的频率不能很大的

使用特权

评论回复
16
灯火阑珊处|  楼主 | 2014-8-4 16:33 | 只看该作者
longmaodo 发表于 2014-8-4 16:25
你可以断点调试吗  
如果可以  那你就幸福了 只要一步一步的检测那个地方出错了就行了
如果不行 你最好 ...

12M晶振啊,这种用外部中断+定时器的做法是不是有问题啊,好多人都是定时器+计数器做出来的

使用特权

评论回复
17
longmaodo| | 2014-8-4 16:41 | 只看该作者
灯火阑珊处 发表于 2014-8-4 16:33
12M晶振啊,这种用外部中断+定时器的做法是不是有问题啊,好多人都是定时器+计数器做出来的 ...

刚才没怎么仔细看你的要求  我觉得你的思路有点问题   
计算频率 你可以看成是计算1S时间内波的个数  
所以只要定义一个1S中的定时器 和一个外部中断就可以了
在外部中断中循环计算  在1S定时中判断个数
这样就没有除法了  最简单 只是提供思路 代码请自编

使用特权

评论回复
18
灯火阑珊处|  楼主 | 2014-8-4 16:48 | 只看该作者
longmaodo 发表于 2014-8-4 16:41
刚才没怎么仔细看你的要求  我觉得你的思路有点问题   
计算频率 你可以看成是计算1S时间内波的个数  
所 ...

对呀,思路稍微变一下就可以,我怎么就没想到呢,还在测周期,容易出错还不准,,,大神能不能留个扣扣

使用特权

评论回复
19
longmaodo| | 2014-8-4 16:58 | 只看该作者
灯火阑珊处 发表于 2014-8-4 16:48
对呀,思路稍微变一下就可以,我怎么就没想到呢,还在测周期,容易出错还不准,,,大神能不能留 ...

不要叫大神  都是从百度和论坛上过来的人
见到了就说一下 QQ就不要了  一个人的力量是有限的  
多问问论坛上的人就成了 我只能解答初级问题

使用特权

评论回复
20
xg3469| | 2014-8-4 17:23 | 只看该作者
不知道你的频率计测频范围准备做多高?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

52

帖子

0

粉丝