ds18b20温度传感器的使用问题,mcu为PIC24FJ64GA006

2019-03-25 19:50发布

我用PIC24FJ64GA006作为MCU,控制ds18b20温度传感器

虽然mcu发送复位信号给ds18b20,有应答信号,即复位时成功的,但是读出来的温度都是0,不知道为什么?  我延时也调过了很多次了。
各位帮忙看下是为什么把

ds18b20先前已经测试时好的了,因为我在用51控制它是可以正常使用的,而且所有的延时我都是直接用数字示波器看的,所以延时也没有错!

代码如下:
#include <p24FJ64GA006.h>
#define DATA_CON        TRISBbits.TRISB0
#define DATA_OUT LATBbits.LATB0
#define DATA_IN PORTBbits.RB0

unsigned char RESERED[100];
unsigned char temperature;
///////////////////////////////////////////////////////////////////////////
//函数功能:延时程序(毫秒级)
//入口参数:del(数值范围:16位整型)
//延时del ms
///////////////////////////////////////////////////////////////////////////
void Delay_Ms(unsigned int del)
{
        unsigned int j;
        while(del--)
                for(j=0;j<1600;j++);
}
///////////////////////////////////////////////////////////////////////////
//函数功能:延时程序(微秒级)
//入口参数:del(数值范围:16位整型)
//延时时间最好是用示波器测试
//del=1,延时2.5us
//del=2,延时3.1us
//del=3,延时3.7us
//del=4,延时4.2us
//del=5,延时5us
//del=6,延时5.64us
///////////////////////////////////////////////////////////////////////////
void Delay_Us(unsigned int del)
{
        while(del--) ;                                                      
}

void IO_Init()
{
        AD1PCFGbits.PCFG0 = 1;                //关闭RB0的模拟功能
}

unsigned char DS18b20_Init()
{
        unsigned char temp_flag = 0x00;
        DATA_CON = 0;                                //RB0为输出
        DATA_OUT = 1;                                //准备复位
        Delay_Us(30);                                  //稍做延时,20.6us
        Nop();
        Nop();
        DATA_OUT = 0;                                    //单片机将总线拉低,产生复位信号
        Delay_Us(1200);                         //精确延时 大于 480us,本次取750us
        Nop();
        Nop();
        //DATA_OUT = 1;                           //拉高总线
        DATA_CON = 1;                                //RB0为输入,单片机释放总线
        Delay_Us(45);                                //30us
        Nop();
        Nop();
        Delay_Us(45);
        Nop();
        Nop();
        Delay_Us(45);
        Nop();
        Nop();
        if(DATA_IN == 0)
                temp_flag = 0x00;
        else
                temp_flag = 0x01;                 //稍做延时后 如果temp_flag = 0x00则初始化成功 temp_flag = 0x01则初始化失败
        Delay_Us(500);                                //注意:ds18b20应答脉冲要持续60——240us本次取316us
        Nop();
        Nop();
        if (temp_flag == 0x00)
        {
                return 1;                                //初始化成功
        }
        else
        {
                return 0;                                //初始化失败
        }
}

//读一个字节
unsigned char Temp_Readbyte(void)
{
        unsigned char i = 0;
        unsigned char read_data = 0;
       
        for (i = 8; i > 0; i --)
        {
                DATA_CON = 0;                        //RB0为输出
                  DATA_OUT = 0;                 // 给脉冲信号
                read_data >>= 1;
                  //DATA_OUT = 1;
                Delay_Us(18);                        //13.2us
                 DATA_CON = 1;                        //RB0为输入
                 if(DATA_IN)
                           read_data |= 0x80;
                  else
                           read_data &= 0x7f;
                  Delay_Us(75);                        //44us
        }
        return(read_data);
}

//写一个字节
void Temp_Writebyte(unsigned char write_data)
{
        unsigned char i = 0;
        for (i = 8; i > 0; i --)
        {
                DATA_CON = 0;                        //RB0为输出
                  DATA_OUT = 0;                        //给个脉冲
                Delay_Us(12);                        //9.4us
                  if(write_data &0x01)
                        DATA_CON = 1;                //将RB0口配置为输入,由上拉电阻使总线变为高电平
                else
                        ;
                  Delay_Us(22);                        //15.6us
                Delay_Us(45);                        //30us
                  DATA_CON = 1;                        //由上拉电阻使总线为高电平
                  write_data >>= 1;
        }
        Delay_Us(60);                                //40us
}

//读取温度
unsigned char Read_Temperature(void)
{
        unsigned char temp_l = 0;
        unsigned char temp_h = 0;
        unsigned char temp = 0;
        unsigned char ds18b20_exist = 0;
        unsigned char ds18b20_exist1 = 0;
        ds18b20_exist = DS18b20_Init();
        Nop();
        Nop();
        if(ds18b20_exist)
        {
                Temp_Writebyte(0xCC); // 跳过读序号列号的操作
                Nop();
                Nop();
                Temp_Writebyte(0x44); // 启动温度转换
                Nop();
                Nop();
              Delay_Ms(750);
                Nop();
                Nop();
                ds18b20_exist1 = DS18b20_Init();
                Nop();
                Nop();
                Temp_Writebyte(0xCC); //跳过读序号列号的操作
                Nop();
                Nop();
                Temp_Writebyte(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
                Nop();
                Nop();
                temp_l = Temp_Readbyte();
                Nop();
                Nop();
                temp_h = Temp_Readbyte();
                Nop();
                Nop();

                temp_h <<= 4;
                temp_h += ((temp_l & 0xf0) >> 4);
                temp = temp_h;

                return(temp);
        }
        else
                return 0;
}

int main()
{
        //temperature = 0x80;
        DATA_CON = 0;
        IO_Init();
        while(1)
        {
                temperature = Read_Temperature();
                Nop();
                Nop();
        }
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
jason870805
1楼-- · 2019-03-26 00:46
同意楼上的观点
ssyz2003
2楼-- · 2019-03-26 06:00
不知道是不是时序的问题,我也是按照datasheet上的时序编写的.....
请各位大侠看看吧

51成功,改为pic就不行了,也调了很久,想不出啥好的测试办法了..
黑放节奏
3楼-- · 2019-03-26 10:44
应该是时序的问题,毕竟51的时钟和pic的时钟是有区别的,记得以前都是在时序上有问题才读错的。
既然你的51的可以,你就可以拿两个时序一点一点的对别下来,怎么也能找出问题的。
caoxiaotao
4楼-- · 2019-03-26 16:05
 精彩回答 2  元偷偷看……
mmeiyuan
5楼-- · 2019-03-26 20:21
引用 3 楼 zyzhang365 的回复:
你使用的是什么调试方式,是ICD/ICSP吗?如果是你不能使用PGD1/PGC1了,否则IO也就是RB0就不可用了。

我用的是ICD的方式,而占用的是PGC/PGD是RB6和RB7,不是RB0和RB1。

wangzhimei
6楼-- · 2019-03-27 02:10
引用 2 楼 congyue123 的回复:
应该是时序的问题,毕竟51的时钟和pic的时钟是有区别的,记得以前都是在时序上有问题才读错的。
既然你的51的可以,你就可以拿两个时序一点一点的对别下来,怎么也能找出问题的。


我已经拿2个程序再对比了,直接用示波器测51的延时时间,然后用同样的时间放在PIC上,依然不行....
无语了..

一周热门 更多>