打印
[51单片机]

DS18B20的延时问题

[复制链接]
1951|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
电子happy|  楼主 | 2014-5-19 09:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int
#define DataPort P1                            //定义数据端口 程序中遇到DataPort 则用P1 替换

sbit DQ = P2^2;
sbit LATCH1=P2^0;                            //定义锁存使能端口 段锁存
sbit LATCH2=P2^1;                            //位锁存
sbit AAA = P3^5;                            //这是为了关闭开发板上的点阵实际应用去掉

static uint temp,temph,templ;
bit ReadTempFlag;                            //定义读时间标志

unsigned char code HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
                                                                            // 显示段码值0123456789
unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
                                                                            //分别对应相应的数码管点亮,即位码
unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};         //存储显示值的全局变量

void delay(uint z);
void init();
void write(uchar dat);
uchar read();
uint readtemp();
void display(unsigned char FirstBit,unsigned char Num);
void Init_Timer0(void);
void delay111(uint z);

void main()
{
   
    Init_Timer0();
    while(1)
    {
     
      if( ReadTempFlag)
      {
       ReadTempFlag = 0;
       temp = readtemp();     
       temph=temp>>4;                                //temph 为整数部分
       templ=temp&0x000f;                             //小数部分
       templ=templ*6/10;                             //小数近似处理
  
       TempData[3]=HEYAO_DuanMa[(temph/10)];     //十位温度
       TempData[4]=HEYAO_DuanMa[temph];          //十位温度
       TempData[5]=HEYAO_DuanMa[templ];            //十位温度
  
      }
    }
}

void init()
{
    uchar n;                                         //严格按照时序的要求进行延时,满足时序的要求                                   
    DQ = 1;
    delay(10);
    DQ = 0;
    delay(400);
    DQ = 1;
    delay(50);
    n = DQ;
    delay(25);                                      //这里采用一个芯片,而且本来我们的芯片是好使的,所以不用返回了,适当的延时就可以
}

void write(uchar dat)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        DQ = dat&0x01;
        delay(25);
        DQ = 1;
        dat = dat>>1;                                //低位在前,高位在后   
    }
    delay(25);
}

uchar read()
{
    uint i ,dat = 0;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        dat = dat >> 1 ;
        DQ = 1;                                        //线与关系,要释放总线
        if(DQ)
        dat = dat |0x80;
        delay(25);
    }
    return dat;
}

uint readtemp()
{
    uchar a=0;
     uint b=0;
     uint c=0;
     init();                                //需要初始化两次,否则实验不成功
     write(0xcc);                             //跳过ROM
     write(0x44);                             //启动温度测量
     delay111(10);
   
     init();
     write(0xcc);
     write(0xbe);
     a=read();
     b=read();
     //c=((b*256)+a)*6.25;
     b<<=8;
     c=a+b;
     return c;


}
void delay111(uint z)
{
    uint x ,y;
    for(x= z;x>0;x--)
    for(y=110;y>0;y--);
}
void delay(uint z)
{
    while(--z);
}

void display(unsigned char FirstBit,unsigned char Num)
{
      static unsigned char i=0;
     

       DataPort=0xff;                               //清空数据,防止有交替重影
       LATCH1=1;                                 //段锁存
       LATCH1=0;

       DataPort=HEYAO_WeiMa[i+FirstBit];         //取位码
       LATCH2=1;                                 //位锁存
       LATCH2=0;

       DataPort=TempData[i];                     //取显示数据,段码
       LATCH1=1;                                 //段锁存
       LATCH1=0;
      
       i++;
       if(i==Num)
          i=0;


}

void Init_Timer0(void)
{

TMOD |= 0x01;                                       //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响            
//TH0=0x00;                                       //给定初值
//TL0=0x00;
EA=1;                                             //总中断打开
ET0=1;                                            //定时器中断打开
TR0=1;                                            //定时器开关打开
AAA = 0;
}

void Timer0_isr(void) interrupt 1
{
static unsigned int num;
TH0=(65536-2000)/256;                             //重新赋值 2ms
TL0=(65536-2000)%6;

display(0,8);                                  // 调用数码管扫描
num++;
if(num==30)      
   {
    num=0;
    ReadTempFlag=1;                               //读标志位置1
    }
}



以上是我的单片机测温的程序,好使,在初始化函数中,我仿真过程中发现在仿真过程中delay(400);是好几千微妙,而不是几百微妙,相差很多倍,我想问,keil软件要看仿真时间要怎么设置,怎么仿真跟实际值查那么远,我的keil是第三版本的

相关帖子

沙发
ningling_21| | 2014-5-19 09:28 | 只看该作者
延时的时间长短和KEIL设置没关系,只与单片机主频和程序有关系...

使用特权

评论回复
板凳
ayb_ice| | 2014-5-19 10:06 | 只看该作者
KEIL里频率设置对了就OK了

使用特权

评论回复
地板
电子happy|  楼主 | 2014-5-19 17:48 | 只看该作者
我是仿真的时候跟实际的差很多

使用特权

评论回复
5
电子happy|  楼主 | 2014-5-19 19:04 | 只看该作者
ningling_21 发表于 2014-5-19 09:28
延时的时间长短和KEIL设置没关系,只与单片机主频和程序有关系...

怎么我会仿真跟实际的差别会那么大呢?

使用特权

评论回复
6
ningling_21| | 2014-5-19 19:08 | 只看该作者
电子happy 发表于 2014-5-19 19:04
怎么我会仿真跟实际的差别会那么大呢?

仿真和实物是有差别的...

使用特权

评论回复
7
电子happy|  楼主 | 2014-5-19 23:43 | 只看该作者
ningling_21 发表于 2014-5-19 19:08
仿真和实物是有差别的...

也不可能差别那么大的啊,要是差别那么大,那些delay(400),delay(50),都是要调试出来的啊,不是吗?或者是我软件哪里设置错了

使用特权

评论回复
8
okhuojia| | 2014-5-20 10:03 | 只看该作者
理论和现实就是有差距呀!!

使用特权

评论回复
9
nbldelnan| | 2014-5-20 11:25 | 只看该作者
在KEIL选项可以选择仿真频率,必须和你事物的晶振频率一样才谈得上相同

使用特权

评论回复
10
电子happy|  楼主 | 2014-5-23 16:53 | 只看该作者
有啊,设置同样是12MHZ

使用特权

评论回复
11
NE5532| | 2014-5-23 21:03 | 只看该作者
用示波器来调,没有示波器的用万用表频率档来校准。

使用特权

评论回复
12
cdf1214| | 2015-3-28 16:52 | 只看该作者
本公司主营TI. NXP. IR. ON. SiLicon                                                                                                       等著名世界品牌产品。
MSP430F一系列TI储存芯片 微控处理器
MSP430F149IPMR MSP430F5438AIPZR MSP430F5438IPZR等。
C8051F 一系列SILICON 单片机 微控处理器
C8051F020 C8051F120 C8051F340 C8051F040等
LPC一系列NXP单片机  
LPC2132FBD64 LPC2134FBD64 LPC2214FBD144  
LPC2378FBD144 LPC2292FBD144等一系列供应
专营:低压差 基准源 三 五 七端稳压 二三极管 场效应 快恢复 肖特基二极管 可控硅 达林顿 整流桥 TVS管 光藕 MAX AD 集成电路
                   北京长实拓展电子销售:陈冬锋
                                     QQ:2850327057
                      电话:15711002528,13641144498

使用特权

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

本版积分规则

3

主题

8

帖子

0

粉丝