OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8078|回复: 4

ds18b20 数码管显示温度数值不会变化

[复制链接]

17

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-8-5
在线时间
36 小时
发表于 2018-3-9 23:08:47 | 显示全部楼层 |阅读模式
1金钱
求助。我移植别的程序里的18b20模块,打算自己做个温度显示的功能出来先,在Proteus仿真一上电 就显示 27,然后一直不动.。 下面是代码~

#include "reg52.h"

#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x40};

uchar code smg_we[]={0x7f,0xbf,0xdf,0xef};


sbit dq=P3^5;

uchar temperature,flag_300ms;

void delay_1ms(uint q)
{
        uint i,j;
        for(i=0;i<q;i++)
                for(j=0;j<120;j++);
}

/***********************小延时函数*****************************/
void delay_uint(uint q)
{
        while(q--);
}


/***********************18b20初始化函数*****************************/
void init_18b20()
{
        bit q;
        dq = 1;                                //把总线拿高
        delay_uint(1);            //15us
        dq = 0;                                //给复位脉冲
        delay_uint(80);                //750us
        dq = 1;                                //把总线拿高 等待
        delay_uint(10);                //110us
        q = dq;                                //读取18b20初始化信号
        delay_uint(20);                //200us
        dq = 1;                                //把总线拿高 释放总线
}

/*************写18b20内的数据***************/
void write_18b20(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {                                         //写数据是低位开始
                dq = 0;                         //把总线拿低写时间隙开始
                dq = dat & 0x01; //向18b20总线写数据了
                delay_uint(5);         // 60us
                dq = 1;                         //释放总线
                dat >>= 1;
        }       
}

/*************读取18b20内的数据***************/
uchar read_18b20()
{
        uchar i,value;
        for(i=0;i<8;i++)
        {
                dq = 0;                         //把总线拿低读时间隙开始
                value >>= 1;         //读数据是低位开始
                dq = 1;                         //释放总线
                if(dq == 1)                 //开始读写数据
                        value |= 0x80;
                delay_uint(5);         //60us        读一个时间隙最少要保持60us的时间
        }
        return value;                 //返回数据
}

/*************读取温度的值 读出来的是小数***************/
uint read_temp()
{
        uint value;
        uchar low;                           //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
        init_18b20();                   //初始化18b20
        write_18b20(0xcc);           //跳过64位ROM
        write_18b20(0x44);           //启动一次温度转换命令
        delay_uint(50);                   //500us

        init_18b20();                   //初始化18b20
       
        write_18b20(0xcc);           //跳过64位ROM
        write_18b20(0xbe);           //发出读取暂存器命令
       
        EA = 0;
        low = read_18b20();           //读温度低字节
        value = read_18b20();  //读温度高字节
        EA = 1;
        value <<= 8;                   //把温度的高位左移8位
        value |= low;                   //把读出的温度低位放到value的低八位中
        value *= 0.0625;               //转换到温度值
        return value;                   //返回读出的温度
}



void display(uchar value)//显示子函数
{
        P2=smg_we[0];
        P1=table[0];
        delay_1ms(2);
       
        P2=smg_we[1];
        P1=table[0];
        delay_1ms(2);
       
        P2=smg_we[2];
        P1=table[value/10%10];
        delay_1ms(2);
       
        P2=smg_we[3];
        P1=table[value%10];
        delay_1ms(2);                                                                                                  
}


//void display(uchar value)
//{
//        uchar i;
//        for(i=0;i<8;i++)
//        {
//                P2=smg_we;
//                P1=table;
//        }
//}



void time_init()          
{
        EA   = 1;                   //开总中断
        TMOD = 0X01;          //定时器0、定时器1工作方式1
        ET0  = 1;                  //开定时器0中断
        TR0  = 1;                  //允许定时器0定时
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
}



void main()
{
       
        time_init();
        while(1)
        {
                if(flag_300ms ==1)
                        {
                                flag_300ms = 0;
                                temperature=read_temp;
               
                                display(temperature);
                        }
        }
       
       
}


void time0_int() interrupt 1
{       
        static uchar value;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;

        value ++;         
        display(temperature);          //数码管显示函数
        if(value % 6 == 0)
        {
                flag_300ms = 1;           //300ms
                value = 0;
        }
}

另外,在别的程序里有配套的电路仿真图,我试了一下是成功的,所以这个18B20的初始化之类的时序应该是没有问题的,晶振调了之后也没有变。求大神帮我看看是哪里出了问题




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-8-5
在线时间
36 小时
 楼主| 发表于 2018-3-9 23:10:34 | 显示全部楼层
回复

使用道具 举报

17

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-8-5
在线时间
36 小时
 楼主| 发表于 2018-3-9 23:10:52 | 显示全部楼层
挺急的 帮帮忙
回复

使用道具 举报

37

主题

204

帖子

0

精华

高级会员

Rank: 4

积分
717
金钱
717
注册时间
2016-6-10
在线时间
191 小时
发表于 2018-3-15 22:27:30 | 显示全部楼层
自己调试一下呗
回复

使用道具 举报

0

主题

15

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2017-8-6
在线时间
42 小时
发表于 2018-4-3 19:18:46 | 显示全部楼层
单片机型号选对不  temperature=read_temp;的read_temp后面有个()  
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-1 11:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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