
/*********************************************************************  
*文件名:18B20.c
*功能：DS18B20温度采集 
* @data:2009.4.24
* by mchen
*********************************************************************/  
#include "Sensor_18B20.h"
#include "ioCC2430.h"

unsigned char sensor_data_value[2];
unsigned char flag;
unsigned int data_value;


static unsigned char get_serial[]={
  0x1C,0x00,0x00,0x02,0x02,0x68,0xd8,0x28,
  0x9E,0x00,0x00,0x02,0x02,0x93,0x34,0x28,
  0xE4,0x00,0x00,0x02,0x02,0x66,0x4D,0x28,
  0xE6,0x00,0x00,0x02,0x02,0x93,0x9B,0x28
  //0xF7,0x00,0x00,0x02,0x02,0x75,0xE1,0x28
 };


void Delay_nus(uint16 s) 
{
  while (s--)
  {
    asm("NOP");
    asm("NOP");
    asm("NOP");
  }
}

void write_1820(unsigned char x)  
{  unsigned char m;    
    SET_OUT;
    for(m=0;m<8;m++)  
    {  
       CL_DQ;
       if(x&(1<<m))    //写数据，从低位开始  
       SET_DQ; 
       else  
       CL_DQ;  
       Delay_nus(40);   //15~60us  
       SET_DQ;  
    }
    //SET_OUT;
    SET_DQ;  
}  

unsigned char read_1820(void)  
{   unsigned char temp,k,n;    
    temp=0;  
    for(n=0;n<8;n++)  
       {  
      CL_DQ;     
      SET_DQ; 
      SET_IN;  
      k=IN_DQ;    //读数据,从低位开始  
      if(k)  
      temp|=(1<<n);  
      else  
      temp&=~(1<<n);  
      Delay_nus(70); //60~120us      
      SET_OUT;

   }  
   return (temp);  
}  

/*功能匹配*/
BYTE match_rom(unsigned char *rom)
{
 unsigned char i;
 init_1820();
 write_1820(0x55);
 for(i=8;i>0;i--)
 {
          write_1820(*(rom+i-1));
 }
 return 1;
}

void init_1820(void) 
{
   //cli(); 
  SET_OUT; 
  SET_DQ;//输出1
  CL_DQ; 
  Delay_nus(550);//拉低一段时间 
  SET_DQ;//释放 
  SET_IN;//输入 
  Delay_nus(40); //释放总线后等待15-60us
  while(IN_DQ)  {;}//等待回复 
  Delay_nus(240);//回复的低电平在60到240us  
  SET_OUT; 
  SET_DQ;//回到初始DQ=1；
 }
 
void read_data(unsigned char *serial)
 {
    unsigned int j; 
    unsigned char temh,teml; 
    unsigned char a,b,c;
 
    init_1820();  //复位18b20  
    write_1820(0xcc);   // 发出转换命令 搜索器件 
    write_1820(0x44);     //启动 
    for(j=20;j>1;j--)  
    Delay_nus(50000);
    init_1820();  
    write_1820(0xcc);
    //match_rom(serial);   //匹配
    write_1820(0xbe); 
         
    teml=read_1820();  //读数据  
    temh=read_1820();  
    if(temh&0x80)//判断正负
    {
      flag=1;
      c=0;
      c=c|temh;
      c=c&0x00ff;
      c=c<<8;
      a=c;
  
      a=c|teml;
 
      a=(a^0xffff);//异或
      a=a+1;  //取反加1
      teml=a&0x0f;
      temh=a>>4;
    }
    else
    {
      flag=0;   //为正
      a=temh<<4;
      a+=(teml&0xf0)>>4; //得到高位的值
      b=teml&0x0f;
      temh=a;
      teml=b&0x00ff;
    }
    sensor_data_value[0]=teml;
    sensor_data_value[1]=temh;
 }

 
unsigned int read_data_value(void)
 {
//    unsigned int j; 
    unsigned char temh,teml; 
//    unsigned char a,b,c;
//    unsigned int data_value;
 
    init_1820();  //复位18b20  
    write_1820(0xcc);   // 发出转换命令 搜索器件 
    write_1820(0x44);     //启动 
//    for(j=20;j>1;j--)  
//    Delay_nus(500);
    init_1820();  
    write_1820(0xcc);
    //match_rom(serial);   //匹配
    write_1820(0xbe); 
         
    teml=read_1820();  //读数据  
    temh=read_1820();  

    sensor_data_value[0]=teml;
    sensor_data_value[1]=temh;
    
    data_value = temh;
    data_value = ( data_value << 8 )| teml;

    return data_value;
    
 }
   
////////////处理数据部分/////////////////
 void DataChange(unsigned char Temp_channel)
 {
   unsigned char temh,teml;
   unsigned char ch[9];
   unsigned int num;
   unsigned i;
   
   teml=sensor_data_value[0];
   temh=sensor_data_value[1];
   i=(Temp_channel-0x31)*2;
   ch[0]=Temp_channel;//当前显示的传感器的编号
   ch[1]=' ';
   num=teml*625;          //小数部分的取值每位代表0.0625（精度）
   if(flag==1)            //判断正负温度
   {
     ch[2]='-';              //+0x2d 为变"-"ASCII码
   }
   else ch[2]='+';   
   if(temh/100==0)
     ch[3]=' ';
   else ch[3]=temh/100+0x30;      //+0x30 为变 0~9 ASCII码
   if((temh/10%10==0)&&(temh/100==0))
     ch[4]=' ';
   else ch[4]=temh/10%10+0x30;
   ch[5]=temh%10+0x30;
   ch[6]='.';
   ch[7]=num/1000+0x30;//忽略小数点后1位的数
   ch[8]='\0';
 //  Print(i,15,ch,1);   //显示温度值
 //  Print(i,80,"℃",1); //显示摄氏度标示  ℃
}


void ds18b20_main()
{
  unsigned char i=0;
  while(1){
    read_data(get_serial+i*8);// 读取温度
    DataChange(i+0x31); //数据处理 
    i++ ;
    if(i==4) i=0;
  }
}

