长汀无线电厂交流论坛

 找回密码
 注册
查看: 3932|回复: 5
打印 上一主题 下一主题

求教:用单片机测频率,使用计数器,读出值不稳。

[复制链接]
跳转到指定楼层
楼主
发表于 2011-5-9 10:34:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用热敏电阻和555做了个震荡电路,输出给单片机的计数器脚(外部计数)
用定时器定1秒,到一秒后读一次计数器里面的值,然后把计数器清零,在计数。
再把读出的值查表换成温度值。

现在的问题是读出的值不稳定,
昨天试的,常温下,7105~7280之间跳动,
这样的精度别说0.1度了,就是正负1度也做不到。
是不是555电路本身输出的频率就不稳定呢?

我看有的资料上面写的是用中断去测量频率周期,
难道测量周期的方法要好些?
回复

使用道具 举报

沙发
 楼主| 发表于 2011-5-9 10:36:59 | 只看该作者
/*******************************************************************/
/*利用热敏电阻特性使555改变振荡频率计算当前的频率,查表出当前温度值*/
/*       */
/*       */
/*       */
/*      */
/*******************************************************************/

#include <AT89X52.H>
#define dula P2_6 //U1锁存位
#define wela P2_7 //U2锁存位
#define uint unsigned int
#define uchar unsigned char
sbit led1=P1^0;
sbit buzz=P2^3;
uint shu;
uint time,pinlv,ID;
uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//共阳0-9的LED笔划
uchar temp,t0,t1,wan,qian,bai,shi,ge;
void init();              //函数声明
void display(uchar aa,uchar wan,uchar qian,uchar bai,uchar shi,uchar ge);

void delay(uint z)     //延时子函数
{
uint x,y;
for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void main()          //主函数
{ uint val;
init();
while(1)
{
if(time==50)
{
  val=TH1*256+TL1;       //谁帮我讲一下,这里为啥要*256在加TL1?
   pinlv=val;
  time=0;
  TH1=0;
  TL1=0;
  
ID=pinlv/2;
switch(ID)
   {
  
    case 620:
            shu=330;
            break;   
    case 619:
            shu=320;
            break;   
    case 618:
            shu=310;
            break;   
    case 617:
            shu=300;
            break;   
    case 616:
            shu=290;
            break;   
    case 615:
            shu=280;
            break;   
    case 614:
            shu=278;
            break;   
    case 613:
            shu=277;
            break;
    case 612:
            shu=276;
            break;
    case 611:
   shu=275;
     break;
    case 610:
            shu=274;
            break;
    case 609:
   shu=273;
     break;
    case 608:
            shu=272;
            break;
    case 607:
   shu=271;
   break;
    case 606:
            shu=270;
            break;
    case 605:
   shu=269;
     break;
    case 604:
            shu=268;
            break;
    case 603:
   shu=267;
     break;
    case 602:
            shu=266;
            break;
    case 601:
   shu=265;
   break;
    case 600:
            shu=264;
            break;
    case 599:
            shu=263;
            break;
    case 598:
   shu=262;
    break;
    case 597:
            shu=261;
            break;   
       case 596:
            shu=260;
            break;
    case 595:
            shu=259;
            break;
    case 594:
   shu=258;
    break;
    case 593:
            shu=257;
            break;
   }}
   
   display(0,wan,qian,bai,shi,ge);

}
}
void init()          //初始化函数
{
TMOD = 0x51; //设计数器1  和  0为工作方式1(0101-LED 0001)
TH0=(65536-13333)/256;//0xB1;
TL0=(65536-13333)%256;//0xDF; //设定时值为20000us(20ms)
TH1=0;
TL1=0;//设
EA = 1; //允许CPU中断
ET0 = 1; //定时器0中断打开
ET1 = 1;//计数器1中断打开
TR0 = 1; //启动定时器0
TR1 = 1; //启动计数器1
}
//
void KeyAndDis_Time0(void) interrupt 1
{
TH0=(65536-13333)/256;//0xB1;
TL0=(65536-13333)%256;//0xDF; //设定时值为20000us(20ms)
time++;
}

void display(uchar aa,uchar wan,uchar qian,uchar bai,uchar shi,uchar ge) //显示子函数
{

   wan=shu/10000;
   qian=shu%10000/1000;
   bai=shu%1000/100;
   shi=shu%100/10;
   ge=shu%10;
        dula=1;
  P0=table[aa];
  dula=0;
  P0=0x00;
  wela=1;
  P0=0x01;
  wela=0;
  delay(1);
        dula=1;
  P0=table[wan];
  dula=0;
  P0=0x00;
  wela=1;
  P0=0x02;
  wela=0;
  delay(1);
       dula=1;
  P0=table[qian];
  dula=0;
  P0=0x00;
  wela=1;
  P0=0x04;
  wela=0;
  delay(1);
        dula=1;
  P0=table[bai];
  dula=0;
  P0=0x00;
  wela=1;
  P0=0x08;
  wela=0;
  delay(1);
  dula=1;
  P0=table[shi];
  dula=0;
  P0=0x00;
  wela=1;
  P0=0x10;
  wela=0;
  delay(1);
  dula=1;
  P0=table[ge];
  dula=0;
  P0=0x00;
  wela=1;
  P0=0x20;
  wela=0;
  delay(1);
}

回复 支持 反对

使用道具 举报

板凳
发表于 2011-5-9 21:52:45 | 只看该作者
C不熟悉,单片机测频比较低的,另外你要按照翻转两次的方法来测比较准确点。
回复 支持 反对

使用道具 举报

地板
发表于 2011-5-10 16:23:41 | 只看该作者
先用固定电阻替换热敏电阻试下看稳定否,毕竟常温不是恒温,温度还是会有些许浮动的。
回复 支持 反对

使用道具 举报

5#
 楼主| 发表于 2011-5-12 09:59:26 | 只看该作者
已经弄好了把这一段放到中断函数里面就可以了
现在末尾数  1230    +- 1跳动也就是29 30 31
不过这样子还是有些问题,经常会出现,如28.1,28.2之间跳动,其实频率现在很稳了。
不知道这个数据怎么处理。
if(time==50)
{
  val=TH1*256+TL1;      
   pinlv=val;
  time=0;
  TH1=0;
  TL1=0;
回复 支持 反对

使用道具 举报

6#
发表于 2011-5-12 22:19:33 | 只看该作者
本帖最后由 夕阳踏歌 于 2011-5-13 14:23 编辑

变量val为整型数(16位)。TH1,TL1为字符型数(8位)。
val=TH1*256+TL1       //这个语句是将两个8位字符型整合成16位整型.高8位是TH1,低8位是TL1.
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|Archiver|长汀无线电厂交流论坛  

GMT+8, 2024-4-28 19:12 , Processed in 0.650311 second(s), 19 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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