Aspirant-GQ 2019-05-08 21:16 采纳率: 0%
浏览 819

DS18B20 时序问题,数码管显示的是乱码

我试了好多遍,还是有问题,我猜测是时序问题,请各位前辈指点一下。晶振是11.0592的

#include"reg52.h"
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P3^7;
sbit a=P2^1;
sbit b=P2^2;
sbit c=P2^3;
uchar duan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f},duan2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

void dy(uint x)
{
    while(x--);
}
void dy30(void)   //误差 -0.703125us
{
    unsigned char a;
    for(a=11;a>0;a--);
}

void dy15(void)   //误差 -0.894097222222us
{
    unsigned char a;
    for(a=4;a>0;a--);
}
void dy45(void)   //误差 -0.512152777778us
{
    unsigned char a;
    for(a=18;a>0;a--);
}

void dy500(void)   //误差 -0.868055555556us
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=227;a>0;a--);
}



uchar init()
{
    uchar i=0;
    DQ=0;
    dy500();    //至少480us
    DQ=1;
    while(DQ)  //等待拉低总线 15~60us内拉低
    {
        i++;
        if(i>50000)
            return 0;   
    }
    return 1;   
}

void write(uchar dat)            //发送一个字节数据
{
    uchar i;
    for(i=0;i<8;i++)
    {
        dy(1);   //写时序时先将总线拉低最少1us,写0时序总线必须保持低电平60~120us然后释放总线(即拉高电平),
        //写1时序时要在总线产生写时序后15us内把总线拉高,2次写周期之间至少间隔1us
        DQ=0;
        dy15();
        DQ=dat&0X01;  //向最低位看齐
        dy45();     
        //dy80();
        DQ=1;//施放总线至少1us
        dat>>=1;
    }
}

uchar read()   //读取一个字节数据 数据的传输时从最低位开始的
{//产生读时序时必须将总线拉低至少1us然后释放总线,在读信号开始15us内开始采集数据,
//读一位数据至少保持在60us以上,俩次读周期之间至少间隔1us                           

    uchar i,a=0X00,b=0;
    for(i=0;i<8;i++)
    {
        DQ=1;
        dy(2);
        DQ=0;
        dy(6);
        DQ=1;
        dy(4);
        a|=DQ;  
        dy30();   //便于检测 
        b=b>>1|a<<7;
    }
    return b;
}

void changetemp()    //转化温度
{
    init();
    dy(100);
    write(0Xcc);  //忽略64位ROM地址,直接向18B20发送温度变换命令,适用于一个从机工作
    write(0X44);  //启动18B20进行温度转换,结果存入内部9字节的RAM中
}

int gettemp()    //读取温度 ,作为返回值返回
{
    char templ,temph;
    float ft;
    int temp;
    init();
    dy(100);
    write(0Xcc);
    write(0Xbe);       //读取命令,温度以2字节补码的形式存放在RAM的第0和第1个字节,负数的补码是原码取反然后加一,读出来后要进行转换
    templ=read();          //读取低八位
    temph=read();          //读取高八位
    temp|=temph;
    temp=temp<<8|templ;
    ft=temp*0.0625*100+0.5; //转换为温度数据
    temp=ft;    //先试着只看整数部分
    return temp;
}

void xs(int temp)   //数码管显示温度
{
     uint i;
    for(i=0;i<6;i++)
    {
    switch(i)
    {
        case 0:a=0;b=0;c=0;break;
        case 1:a=1;b=0;c=0;;break;
        case 2:a=0;b=1;c=0;P0=duan[temp/1000%10];break;
        case 3:a=1;b=1;c=0;P0=duan2[temp/100%10];break;
        case 4:a=0;b=0;c=1;P0=duan[temp/10%10];break;
        case 5:a=1;b=0;c=1;P0=duan[temp%10];break;   //最低位

    }
    dy(100);
    P0=0X00;
    }
}

void main()
{
    while(1)
    {
        changetemp();
        xs(gettemp());
    //  xs(1232);
    }
}
  • 写回答

1条回答 默认 最新

  • zhangPC 2019-05-09 12:56
    关注

    xs(1232); 这个能显示出正确的值不?不能的话确认一下数码管的连接和位段定义是否匹配;

     84 uchar read()
     85 // 读取一个字节数据 数据的传输时从最低位开始的
     86 {
     87     // 产生读时序时必须将总线拉低至少1us然后释放总线,在读信号开始15us内开始采集数据,
     88     // 读一位数据至少保持在60us以上,俩次读周期之间至少间隔1us
     89     uchar i, a = 0X00, b = 0;
     90     for (i = 0; i < 8; i++) {
     91         DQ = 1;
     92         dy(2);
     93         DQ = 0;
     94         dy(6);
     95         DQ = 1;
     96         dy(4);
     97         a |= DQ;
     98         dy30();            -----   这里延时加大点试试
     99         // 便于检测
    100         b = b >> 1 | a << 7;                                                                                                    
    101     }
    102     return b;
    
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!