7269|14

1

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

ds18b20温度传感器的使用问题,mcu为PIC24FJ64GA006 [复制链接]

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

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

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

代码如下:
#include
#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();
        }
}

最新回复

现在调好了,别人程序借鉴的,延时时间长短的问题。  详情 回复 发表于 2009-8-7 20:19
点赞 关注
 

回复
举报

1

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
同意楼上的观点
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
不知道是不是时序的问题,我也是按照datasheet上的时序编写的.....
请各位大侠看看吧

51成功,改为pic就不行了,也调了很久,想不出啥好的测试办法了..
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

4
 
应该是时序的问题,毕竟51的时钟和pic的时钟是有区别的,记得以前都是在时序上有问题才读错的。
既然你的51的可以,你就可以拿两个时序一点一点的对别下来,怎么也能找出问题的。
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
引用 3 楼 zyzhang365 的回复:
你使用的是什么调试方式,是ICD/ICSP吗?如果是你不能使用PGD1/PGC1了,否则IO也就是RB0就不可用了。




看看配置字设置和硬件原理图吧,也就是说如果你使用了PGD1/PGC1,那么RB0就不能用作IO了。
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

6
 
引用 3 楼 zyzhang365 的回复:
你使用的是什么调试方式,是ICD/ICSP吗?如果是你不能使用PGD1/PGC1了,否则IO也就是RB0就不可用了。



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

 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

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


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

回复

1

帖子

0

TA的资源

禁止访问

8
 
提示: 作者被禁止或删除 内容自动屏蔽
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

9
 
DS18B20的IO要加上拉,有了吗?

 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

10
 
你使用的是什么调试方式,是ICD/ICSP吗?如果是你不能使用PGD1/PGC1了,否则IO也就是RB0就不可用了。

 
 
 

回复

1

帖子

0

TA的资源

禁止访问

11
 
提示: 作者被禁止或删除 内容自动屏蔽
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 9 楼 lbing7 的回复:
DS18B20的IO要加上拉,有了吗?




当然有了,按datasheet的 4.7k
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

13
 
LZ也不要说51上没问题什么的,毕竟换了芯片和编译器。考虑下面几个问题,
1. 时序,可以说时序肯定不正常,因为如果正常得到的数据就应该是正确的,温度芯片看到的就是时序;
2. 芯片控制是否正确,个人觉得microchip这个东东很讨厌;
3. 芯片是否有bug,microchip芯片bug比较多;
4. 开发环境如编译器等,是否有bug,上官方论坛看看;
5. 代码本身以及其他的代码是不是有问题,特别是有中断的系统,延时是否符合要求。

祝你好运
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

14
 
有没有示波器,有的话用示波器打一下,看时序与51上面有没有什么差别。
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

15
 
现在调好了,别人程序借鉴的,延时时间长短的问题。
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表