打印
[AVR单片机]

跪求指导!ds18b20读不到温度,用示波器打过,读那一段有问

[复制链接]
2608|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
paulful|  楼主 | 2013-6-20 20:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 paulful 于 2013-6-20 21:00 编辑

//用的是pic18f258,4M晶振,仿真和固化时候, Temperature[0]都是读出oxffff,一直找不到问题出在哪里


#include"pic18.h"
//-------------------------------------------------端口位定义--------------------------------------------
#define BIT0    0x01

#define DOUT        TRISA&=~BIT0   //RAO输出
#define DIN           TRISA|=BIT0     //RAO输入
#define DOUT_H    PORTA|=BIT0    //RA0输出为高
#define DOUT_L     PORTA&=~BIT0   //RA0输出为低

#define DE RA5 //接MAX485 DE脚,为1时发送,为0时接收

//-------------------------------------------------------------------------

unsigned int Temperature[6],Btem,Ttem,j;
//float T;
unsigned char Atemp;




//-----------------------------------------系统初始化-----------------------------------
void initial()
{
   INTCON=0X00;
   ADCON1=0X07;         //配置portA口为I/O口
   
   PIE1=0;
   PIE2=0;
   PIE3=0;
}


//.................................................串口初始化...................................................
void USARTini()        //定时器及USART的初始化
{
            
        RCSTA = 0x80;   //允许串行口工作使能
        TXSTA = 0x04;   //选择异步通信高速方式传输8位
        TRISC=TRISC|0X80;
        TRISC=TRISC&0XBF;    //配置RC7为输入,RC6为输出
        TRISA=TRISA&0XDE;    //配置RA5为0输出,RA0为输出
        TRISB=TRISB&0XEF;    //配置RB4为0输出
        SPBRG = 25;           // 9600 = 4M / ( 16 * ( 25+1 ) ) HIGH
        PIR1=0x00;             //清中断标志
         //PIE1=PIE1|0X20;
        // RCIP=0;                                    
              DE=1;                    //MAX485处于发送
        TXEN=1;                   // 允许发送

}


//.................................................延时函数........................................
/*void delay_nus(unsigned int n)      
{
  char i;
  for(i=0;i<n;i++);

}*/

void delay_nus(unsigned int n)
{while(--n);}


void delayn()   //6us
{
  asm("nop");
}

//N ms延时函数
void delay_nms(unsigned int n)      
{
      unsigned int a=0;
      unsigned int b=0;
      for (a=0;a<n;a++)
      for (b=0;b<655;b++);
}


/*------------------------------------------------Temprature------------------------------------------*/


//................................................................初始化DS18B20..........................................
void InitDS18B20()
{
        DOUT;
        DOUT_H;                                    // 释放(拉高)总线  
        DOUT_L;                          // 占领(拉低)总线
        delay_nus(60);                                  // 480us-960us ,786us
        DOUT_H;                          // 释放总线
        DIN;                    //切换到输入


        delay_nus(22);                  //10,136US;40,526us 25,331us            延时后被拉高  //跳过了低电平,等待被拉高
           
        DOUT;             //输出              
        DOUT_H;                                    // 释放(拉高)总线
       delay_nus(30);            //396us
   
}



//字写
void WriteDS18B20(unsigned int x)
{
        unsigned int a;
        for(a=0;a<8;a++)
        {  
             DOUT;
                DOUT_L;                                        //拉低总线1-15us ,大于1us
                asm("nop");                                    
             asm("nop");
            
         
                if( x & (1<<a) )
                {
                        DOUT_H;                                 //置高总线
                }
                else
                {
                        DOUT_L;                                //拉低总线
                }
                delay_nus(6);               // 大于60us   //1,19us;2,32us;3,45us;4,58us;8,110US
             DOUT_H;                                   // 完毕后释放(拉高)总线
         
        }
}


unsigned int ReadDS18B20()
{
        unsigned int Temp,n;
       Temp=0;
        for(n=0;n<8;n++)
        {
            
DOUT_H;    // 置高总线  输入为1
          asm("nop");  asm("nop");
           DOUT_L;   
                        
          DOUT_H;
asm("nop");asm("nop");asm("nop");
           DIN;
           asm("nop");                           
             if( PORTA& 0x01 )
                   {
                  
                        Temp |= (1<<n);
                }
                else
                {
                        Temp &= ~(1<<n);
                }
            delay_nus(6);                            //1,19us;2,32us;3,45us ,6,89us
        DOUT;
       DOUT_H;
        }                                         
        return(Temp);
}


void Get_Data()
{
       unsigned int temh,teml;
        InitDS18B20();
   
        WriteDS18B20(0xCC);                                //跳过ROM
        WriteDS18B20(0x44);                                 // 发出转换命
      delay_nms(150);         // 900多毫秒
           InitDS18B20();
           WriteDS18B20(0xCC);                 //跳过ROM
        WriteDS18B20(0xBE);                        //读18B20温度
delay_nus(60);                          // 700多微秒
                teml = ReadDS18B20();
                temh = ReadDS18B20();
            Temperature[0] = (temh << 8) + teml;
      
}

void DEAL()
{

  Temperature[1]=Temperature[0]/16;

}



void SENDDATA()
{
     RB4=0;
     TXREG=(char)Temperature[1];


}

//..............................................................主程序.................................................................

main()
{
   initial();
   USARTini();
   asm("nop");
   asm("nop");

   while(1)
        {

          Get_Data();
     //    delay_nus(6);
       DEAL();
     SENDDATA();

        }
}

相关帖子

沙发
paulful|  楼主 | 2013-6-20 20:45 | 只看该作者
我用的是PIC18F258,用的是RAO口,18b20的上拉电阻是4.7k。弄了半个月都没弄好,很急了,心里好郁闷,求指导。图中电容没有悍,也悍过100p过。

QQ截图20130620204429.jpg (129.96 KB )

QQ截图20130620204429.jpg

使用特权

评论回复
板凳
qin552011373| | 2013-6-20 22:46 | 只看该作者
我给你上一个avr写的18b20读取函数吧  

使用特权

评论回复
地板
qin552011373| | 2013-6-20 22:47 | 只看该作者


#include "../../include.h"

#if EXTERNAL_MODULE_SD2405_MODE != 0

void IIC_Init(void)
{
        SETBIT(IIC_DDR, IIC_SCL);              // Set SCL to output
        SETBIT(IIC_DDR, IIC_SDA);                   // Set SDA to output
        SETBIT(IIC_PORT, IIC_SCL);             // Set SCL high
        SETBIT(IIC_PORT, IIC_SDA);            // Set SDA high
}

void IIC_Delay(void)
{
        TARGET_Delayus(1, 0);       
}

void IIC_Start( void )
{
        SETBIT(IIC_PORT, IIC_SCL);            // Set SCL High
        SETBIT(IIC_PORT, IIC_SDA);            // Set SDA High
        SETBIT(IIC_DDR, IIC_SDA);              // Set SDA to output
        CLRBIT(IIC_PORT, IIC_SDA);             // Clear SDA
}

void IIC_Stop( void )
{
        SETBIT(IIC_DDR, IIC_SDA);              // Set SDA to output
        CLRBIT(IIC_PORT, IIC_SDA);             // Clear SDA
        CLRBIT(IIC_PORT, IIC_SCL);             // Clear SCL
        SETBIT(IIC_PORT, IIC_SCL);             // Set SCL High
        IIC_Delay();
        SETBIT(IIC_PORT, IIC_SDA);                   // Set SDA High
}

void IIC_Clock( void )
{
        SETBIT(IIC_PORT, IIC_SCL);            // Set SCL high
        IIC_Delay();
        CLRBIT(IIC_PORT, IIC_SCL);             // Set SCL low
}

uint8 IIC_Ackn( void )
{
        uint8 Ackn = 0;                                                      // Temp RAM for Ackn flag
        CLRBIT(IIC_PORT, IIC_SCL);
        CLRBIT(IIC_DDR, IIC_SDA);                       // Set SDA to input
        SETBIT(IIC_PORT, IIC_SCL);                                       // Clock the ACK bit
        if (CHKBIT(IIC_PIN, IIC_SDA)) Ackn = 1;         // Check the ACK bit on SDA
        CLRBIT(IIC_PORT, IIC_SCL);                                     // Clear the clock
        return Ackn;                                                              // Return our ACK bit
}

void IIC_WriteControl( uint8 u8_HardwareAddress, uint8 u8_ReadOrWrite )
{
        // *** Send the I2C device Control code *** //
        CLRBIT(IIC_PORT, IIC_SCL);                                                                                        // Clear SCL clock
        if( (u8_HardwareAddress & 0x80) == 0x80) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x40) == 0x40) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x20) == 0x20) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                              // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x10) == 0x10) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                  // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        // *** Send the I2C Control byte chip selects bits *** //
        if( (u8_HardwareAddress & 0x08) == 0x08) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x04) == 0x04) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                        // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        if( (u8_HardwareAddress & 0x02) == 0x02) SETBIT(IIC_PORT, IIC_SDA);          // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                       // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        // *** Set or Clear the read / write bit for I2C control *** //
        if(u8_ReadOrWrite) SETBIT(IIC_PORT, IIC_SDA);                                                       // Set I2C SDA PIN
        else CLRBIT(IIC_PORT, IIC_SDA);                                                                                      // Clear I2C SDA PIN
        IIC_Clock();                                                                                                      // Clock I2C bit
        IIC_Ackn();                                                                                                                              // Check for acknowledge from I2C device       
}

void IIC_WriteByte( uint8 u8_Data )
{
        uint8 i;
        SETBIT(IIC_DDR, IIC_SDA);                                                                        // Set SDA to output
        CLRBIT(IIC_PORT, IIC_SCL);
        for(i = 0; i < 8; i++)                                                                                // Loop for our 8 bits
        {
                // Set or Clear SDA pin
                if((u8_Data & 0x80) == 0x80) SETBIT(IIC_PORT, IIC_SDA);        // Set I2C SDA PIN
                else CLRBIT(IIC_PORT, IIC_SDA);                                                        // Clear I2C SDA PIN
                SETBIT(IIC_PORT, IIC_SCL);                                                 // Set SCL High, Clock data
                u8_Data = u8_Data << 1;                                                                        // Shift data in buffer right one
                CLRBIT(IIC_PORT, IIC_SCL);                                                 // Clear SCL
        }
        IIC_Ackn();                                                                                                // Check for acknowledge from I2C device       
}

uint8 IIC_ReadByte(void)
{
        uint8 i,buff = 0;
        for (i = 0; i < 8; i++)
        {
                buff = buff << 1;
                CLRBIT(IIC_DDR, IIC_SDA);                                                           // Set SDA to input
                SETBIT(IIC_PORT, IIC_SCL);                                                                    // Set SCL High,Clock bit out
                if (CHKBIT(IIC_PIN, IIC_SDA)) buff = buff | 0x01;                // Read data on SDA pin
                CLRBIT(IIC_PORT, IIC_SCL);                                                                    // Clear SCL
        }
        return buff;                                                                                                // Return our I2C byte
}

void IIC_WriteOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress, uint8 u8_Data)
{
        uint16 c;                                                                                              // Temp Ram used for write delay
       
        IIC_Start();                                                                                                 // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                        // Send the EEPROM control Byte
        IIC_WriteByte(u8_MemoryAddress);                                                      // Send the EEPROM internal Address
        IIC_WriteByte(u8_Data);                                                                              // Send the EEPROM Data
        IIC_Stop();                                                                                                        // Set I2C Stop condition       
        for(c = 0; c < 1000; c++);                                                      // Delay for EEPROM Write       
}

uint8 IIC_ReadOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress)
{
        uint8 Temp;                                                                                                           // Temp RAM for EEPROM Read
       
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                            // Send the EEPROM control Byte
        IIC_WriteByte(u8_MemoryAddress);                                                        // Send the EEPROM internal Address
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 1);                            // Send the EEPROM control Byte
        Temp = IIC_ReadByte();                                                                        // Read data from EEPROM
        IIC_Stop();                                                                                                          // Set I2C Stop condition
        return Temp;                                                                                                // Return data from EEPROM
}

void IIC_WriteTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress, uint8 u8_Data)
{
        uint16 c;       
                                                                                                                      // Temp Ram used for write delay
        uint8 u8_HighAddress;
        uint8 u8_LowAddress;
        u8_HighAddress = u16_MemoryAddress / 256;
        u8_LowAddress = u16_MemoryAddress % 256;
        IIC_Start();                                                                                                 // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                            // Send the EEPROM control Byte
        IIC_WriteByte(u8_HighAddress);
        IIC_WriteByte(u8_LowAddress);                                                              // Send the EEPROM internal Address
        IIC_WriteByte(u8_Data);                                                                              // Send the EEPROM Data
        IIC_Stop();                                                                                                        // Set I2C Stop condition       
        for(c = 0; c < 1000; c++);                                                      // Delay for EEPROM Write
       
}

uint8 IIC_ReadTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress)
{
        uint8 Temp;                                                                                                           // Temp RAM for EEPROM Read
        uint8 u8_HighAddress;
        uint8 u8_LowAddress;
       
        u8_HighAddress = u16_MemoryAddress / 256;
        u8_LowAddress = u16_MemoryAddress % 256;
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HardwareAddress, 0);                                        // Send the EEPROM control Byte
        IIC_WriteByte(u8_HighAddress);
        IIC_WriteByte(u8_LowAddress);                                                                // Send the EEPROM internal Address
        IIC_Start();                                                                                                   // Set I2C start condition
        IIC_WriteControl(u8_HighAddress, 1);                                                // Send the EEPROM control Byte
        Temp = IIC_ReadByte();                                                                        // Read data from EEPROM
        IIC_Stop();                                                                                                          // Set I2C Stop condition
        return Temp;                                                                                                // Return data from EEPROM
}

#endif

使用特权

评论回复
5
qin552011373| | 2013-6-20 22:47 | 只看该作者
#ifndef IIC_H_
#define IIC_H_

//函数原型声明
void IIC_Init(void);
void IIC_Delay(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Clock(void);
uint8 IIC_Ackn(void);
void IIC_WriteControl(uint8 u8_HardwareAddress, uint8 u8_ReadOrWrite);
void IIC_WriteByte(uint8 u8_Data);
uint8 IIC_ReadByte(void);
void IIC_WriteOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress, uint8 u8_Data);
uint8 IIC_ReadOneByteAddressDevice(uint8 u8_HardwareAddress, uint8 u8_MemoryAddress);
void IIC_WriteTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress, uint8 u8_Data);
uint8 IIC_ReadTwoOneByteAddressDevice(uint8 u8_HardwareAddress, uint16 u16_MemoryAddress);

#endif /* IIC_H_ */

使用特权

评论回复
6
qin552011373| | 2013-6-20 22:48 | 只看该作者
#ifndef IIC_CONFIG_H_
#define IIC_CONFIG_H_

#define IIC_PORT PORTD
#define IIC_DDR         DDRD
#define IIC_PIN         PIND

#define IIC_SCL         BIT2
#define IIC_SDA  BIT3

#endif /* IIC_CONFIG_H_ */

使用特权

评论回复
7
qin552011373| | 2013-6-20 22:50 | 只看该作者
这是用avr写的iic的读写函数  用的IO模拟的模式  没用过pic  你先对一下代码吧  估计差不多

使用特权

评论回复
8
ningling_21| | 2013-6-21 19:05 | 只看该作者
时间,其实关键还是延时时间...

使用特权

评论回复
9
seacore_2008| | 2013-6-21 22:20 | 只看该作者
你看看你DS18B20接的脚位对不对?呵呵,2脚是DQ

使用特权

评论回复
10
paulful|  楼主 | 2013-6-22 17:16 | 只看该作者
forgivexx 发表于 2013-6-21 21:28
楼上的,不是I2C,DS18B20是单总线的。调试起来主要还是看时序图。多说无益,你花了半个月太夸张了。仔细看 ...

恩 我也觉得太夸张了,所以来求救了,延时这些我都看过,一直不知道哪里出了问题。读写我也是按照时序来写还是不对

使用特权

评论回复
11
paulful|  楼主 | 2013-6-22 17:22 | 只看该作者
seacore_2008 发表于 2013-6-21 22:20
你看看你DS18B20接的脚位对不对?呵呵,2脚是DQ

恩 这个 必须不能出错的 检查过的

使用特权

评论回复
12
paulful|  楼主 | 2013-6-22 17:23 | 只看该作者
ningling_21 发表于 2013-6-21 19:05
时间,其实关键还是延时时间...

EN ,我在好好看看,真的还是需要点耐心的

使用特权

评论回复
13
paulful|  楼主 | 2013-6-23 11:27 | 只看该作者
其实 还是自己出现了问题,仿照了以前dsp用过的程序,以为释放总线就是输出高电平就行了,其实不是,pic18f258的释放总线只要把io口切换成输入就行了。希望后面的同学看到有所参考

使用特权

评论回复
14
qin552011373| | 2013-6-23 22:11 | 只看该作者
paulful 发表于 2013-6-23 11:27
其实 还是自己出现了问题,仿照了以前dsp用过的程序,以为释放总线就是输出高电平就行了,其实不是,pic18f ...

明白了就好

使用特权

评论回复
15
paulful|  楼主 | 2013-6-24 16:15 | 只看该作者
qin552011373 发表于 2013-6-23 22:11
明白了就好

谢谢版主了。

使用特权

评论回复
16
wentao0100| | 2013-7-3 22:20 | 只看该作者
进步了

使用特权

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

本版积分规则

2

主题

35

帖子

0

粉丝