#include "DS18B20.h"
#include "delay.h"
#include "timer.h"
//////////////////////////////////////////////////
//			2203/4/X GHz_ljw 初版
// 			2203/4/23 GHz_ljw 合并版 开启1-4通道 参考通道没有温度传感器							  
//////////////////////////////////////////////////////////////////////////////////
short DS18B20_Get_Temp_CH1=0;//通道1的DS18B20温度数据
short DS18B20_Get_Temp_CH2=0;
short DS18B20_Get_Temp_CH3=0;
short DS18B20_Get_Temp_CH4=0;

//复位DS18B20
void DS18B20_Rst(void)
{
    DS18B20_IO_OUT(); //SET PE2 OUTPUT
		DS18B20_IO_OUT_2();
		DS18B20_IO_OUT_3();
		DS18B20_IO_OUT_4();
	
    DS18B20_DQ_OUT=0; //拉低DQ
		DS18B20_DQ_OUT_2=0;
		DS18B20_DQ_OUT_3=0; //拉低DQ
		DS18B20_DQ_OUT_4=0;
    delay_us(750);    //拉低750us
	
    DS18B20_DQ_OUT=1; //DQ=1
		DS18B20_DQ_OUT_2=1;
		DS18B20_DQ_OUT_3=1;  
		DS18B20_DQ_OUT_4=1;
    delay_us(15);     //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(u8 channel)
{
    u8 retry=0;
		switch(channel)
		{
			default:
				DS18B20_IO_IN();//SET INPUT
				while (DS18B20_DQ_IN&&retry<200)
				{
						retry++;
						delay_us(1);
				};
				break;
			case 2:
				DS18B20_IO_IN_2();//SET INPUT
				while (DS18B20_DQ_IN_2&&retry<200)
				{
						retry++;
						delay_us(1);
				};
				break;
			case 3:
				DS18B20_IO_IN_3();//SET INPUT
				while (DS18B20_DQ_IN_3&&retry<200)
				{
						retry++;
						delay_us(1);
				};
				break;
			case 4:
				DS18B20_IO_IN_4();//SET INPUT
				while (DS18B20_DQ_IN_4&&retry<200)
				{
						retry++;
						delay_us(1);
				};
				break;
			
		}
   
   

    if(retry>=200)return 1;
    else retry=0;
		switch(channel)
		{
			default:
				while (!DS18B20_DQ_IN&&retry<240)
				{
						retry++;
						delay_us(1);
				};
				break;
			case 2:
				while (!DS18B20_DQ_IN_2&&retry<240)
				{
						retry++;
						delay_us(1);
				};
				break;
			case 3:
				while (!DS18B20_DQ_IN_3&&retry<240)
				{
						retry++;
						delay_us(1);
				};
				break;
			case 4:
				while (!DS18B20_DQ_IN_4&&retry<240)
				{
						retry++;
						delay_us(1);
				};
				break;
			
		}
    
    if(retry>=240)return 1;
    return 0;
}
//CH1 CH2 CH3 CH4分别从DS18B20读取一个位
//返回值：1/0
u8 DS18B20_Read_Bit_CH1(void) 			 // read one bit
{
		u8 bit=0;
    DS18B20_IO_OUT();//SET PE2 OUTPUT

    DS18B20_DQ_OUT=0;

    delay_us(2);
    DS18B20_DQ_OUT=1;

    DS18B20_IO_IN();//SET PE2 INPUT

    delay_us(12);
    if(DS18B20_DQ_IN)
			bit = 1;
    delay_us(50);
		return bit;
}
u8 DS18B20_Read_Bit_CH2(void) 			 // read one bit
{
		u8 bit=0;
    DS18B20_IO_OUT_2();//SET PE2 OUTPUT

    DS18B20_DQ_OUT_2=0;

    delay_us(2);
    DS18B20_DQ_OUT_2=1;

    DS18B20_IO_IN_2();//SET PE2 INPUT

    delay_us(12);
    if(DS18B20_DQ_IN_2)
			bit = 1;
    delay_us(50);
		return bit;
}

u8 DS18B20_Read_Bit_CH3(void) 			 // read one bit
{
		u8 bit=0;
    DS18B20_IO_OUT_3();//SET PE2 OUTPUT

    DS18B20_DQ_OUT_3=0;

    delay_us(2);
    DS18B20_DQ_OUT_3=1;

    DS18B20_IO_IN_3();//SET PE2 INPUT

    delay_us(12);
    if(DS18B20_DQ_IN_3)
			bit = 1;
    delay_us(50);
		return bit;
}

u8 DS18B20_Read_Bit_CH4(void) 			 // read one bit
{
		u8 bit=0;
    DS18B20_IO_OUT_4();//SET PE2 OUTPUT

    DS18B20_DQ_OUT_4=0;

    delay_us(2);
    DS18B20_DQ_OUT_4=1;

    DS18B20_IO_IN_4();//SET PE2 INPUT

    delay_us(12);
    if(DS18B20_DQ_IN_4)
			bit = 1;
    delay_us(50);
		return bit;
}

u16 DS18B20_Read12Bit(u8 chid)
{
	u8 i,bit;
	u16 result=0;
	for (i=0; i<12; i++)
	{
		if(chid == 2)
			bit = DS18B20_Read_Bit_CH2();
		else if (chid == 3)
			bit = DS18B20_Read_Bit_CH3();
		else if (chid == 4)
			bit = DS18B20_Read_Bit_CH4();
		else
			bit = DS18B20_Read_Bit_CH1();
		result|=(bit<<i);
	}
	return result;
}
//从DS18B20读取一个字节
//返回值：读到的数据
//u8 DS18B20_Read_Byte(void)    // read one byte
//{
//		u8 i,j1,dat1;

//    for (i=1; i<=8; i++)
//    {
//        j1=DS18B20_Read_Bit();
//        dat1=(j1<<7)|(dat1>>1);
//		dat2=(j2<<7)|(dat2>>1);
//		dat3=(j3<<7)|(dat3>>1);
//		dat4=(j4<<7)|(dat4>>1);
//    }

//    return dat1;
//}
//写一个字节到DS18B20
//dat：要写入的字节
void DS18B20_Write_Byte(u8 dat)
{
    u8 index;
    u8 testb;
    DS18B20_IO_OUT();//SET OUTPUT;
		DS18B20_IO_OUT_2();//SET OUTPUT;
		DS18B20_IO_OUT_3();//SET OUTPUT;
		DS18B20_IO_OUT_4();//SET OUTPUT;
    for (index=1; index<=8; index++)
    {
        testb=dat&0x01;
        dat=dat>>1;
        if (testb)
        {
            DS18B20_DQ_OUT=0;// Write 1
            DS18B20_DQ_OUT_2=0;// Write 1
						DS18B20_DQ_OUT_3=0;// Write 1
						DS18B20_DQ_OUT_4=0;// Write 1
					
            delay_us(2);
            DS18B20_DQ_OUT=1;
            DS18B20_DQ_OUT_2=1;
						DS18B20_DQ_OUT_3=1;
						DS18B20_DQ_OUT_4=1;
					
            delay_us(60);
        }
        else
        {
            DS18B20_DQ_OUT=0;// Write 0
						DS18B20_DQ_OUT_2=0;// Write 0
						DS18B20_DQ_OUT_3=0;// Write 0
						DS18B20_DQ_OUT_4=0;// Write 0
            delay_us(60);
            DS18B20_DQ_OUT=1;
						DS18B20_DQ_OUT_2=1;
						DS18B20_DQ_OUT_3=1;
						DS18B20_DQ_OUT_4=1;
            delay_us(2);
        }
    }
}
//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{
		DS18B20_Rst();
		DS18B20_Check(1);
		DS18B20_Check(2);
		DS18B20_Check(3);
		DS18B20_Check(4);
		DS18B20_Write_Byte(0xcc);// skip rom
		DS18B20_Write_Byte(0x44);// convert
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟

    //GPIOG9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化

    DS18B20_Rst();
		if(DS18B20_Check(1)!=1) return 0;
		if(DS18B20_Check(2)!=1) return 0;
		if(DS18B20_Check(3)!=1) return 0;
    return DS18B20_Check(4);
}
//从ds18b20得到温度值
//精度：0.1C
//返回值：温度值 （-550~1250）
short DS18B20_Get_Temp(void)
{
		short result=0;
	
    DS18B20_Start();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check(1);
		DS18B20_Check(2);
		DS18B20_Check(3);
		DS18B20_Check(4);
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert
	
	  result=(short)DS18B20_Read12Bit(1);
		result<<=4;
	  result/=16;
		DS18B20_Get_Temp_CH1=result;
	
	  result=(short)DS18B20_Read12Bit(2);
		result<<=4;
	  result/=16;
		DS18B20_Get_Temp_CH2=result;
	
	  result=(short)DS18B20_Read12Bit(3);
		result<<=4;
	  result/=16;
		DS18B20_Get_Temp_CH3=result;
		
	  result=(short)DS18B20_Read12Bit(4);
		result<<=4;
	  result/=16;
		DS18B20_Get_Temp_CH4=result;
		return result;
}
