STM32F103ZET6读取一根总线上的多个DS18B20温度

/************************************************************************************************************* 
 * 文件:     ds18b20.c 
 * 功能:     基于STM32的DS18B20单总线 
*************************************************************************************************************/  
#include "sys.h"  
#include "delay.h"  
#include "ds18b20.h"
#include "usart.h" 
/************************************************************************************************************************* 
*函数名:int DS18B20_Reset(void) 
*功能  :复位DS18B20总线 
*参数  :无 
*返回  :TRUE:成功;FALSE:失败 
*************************************************************************************************************************/  
int DS18B20_Reset(void)  
{  
    u8 i = 0;  
      
    Set18b20IOout();        //设置总线端口为输出模式
		DS18B20_OUT=1;					//拉高总线电平,为复位做准备  
    delay_us(1);						//延时1us为  
    DS18B20_OUT=0;	        //拉低总线480us~240us  
    delay_us(500);          //延时>480us  
    DS18B20_OUT=1;					//拉高总线  
    delay_us(2);            //复位完成  
    Set18b20IOin();         //设置总线端口为输入模式
    while(DS18B20_IN)    //等待从机应答信号  
    {  
        i ++;  
        delay_us(1);  
        if(i > 100)  
        {  
            printf("DS18B20 error!\r\n");  
            return FALSE;   //等待超时,初始化失败,返回FALSE;  
        }  
    }  
    delay_us(250);          //跳过回复信号
    return TRUE;            //复位完成DS18B20,返回TRUE 
} 

/************************************************************************************************************************* 
*函数名:u8 DS18B20_Init(void) 
*功能  :初始化DS18B20数据总线 
*参数  :无 
*返回  :TRUE:成功;FALSE:失败 
*************************************************************************************************************************/  
u8 DS18B20_Init(void)
{
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);	 //使能GPIOG时钟 
	
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;				//设置PG11位推挽输出
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOG, &GPIO_InitStructure);
 	GPIO_SetBits(GPIOG,GPIO_Pin_11);    //输出1

	return DS18B20_Reset();
} 
  
/************************************************************************************************************************* 
*函数名:u8 DS18B20_Read_Bit(void)   
*功能  :从DS18B20读取1位的数据 
*参数  :无 
*返回  :data
*************************************************************************************************************************/  
u8 DS18B20_ReadBit(void) 	 
{
    u8 data=0;
		Set18b20IOout();	//设置数据总线接口为输出
    DS18B20_OUT=0;		//拉低总线 
		delay_us(12);			//延时10-15us
    DS18B20_OUT=1;		//释放总线 
		Set18b20IOin();	  //设置数据总线接口为输入
		delay_us(10);
		if(DS18B20_IN)		//读取数据
		{
			data=1;
		}
    delay_us(42);			//延时40-45us           
    return data;			//返回数据
}

/************************************************************************************************************************* 
*函数名:u8 DS18B20_ReadData(void)   
*功能  :从DS18B20读取一个字节的数据 
*参数  :无 
*返回  :data
*************************************************************************************************************************/  
u8 DS18B20_ReadData(void)  
{  
	u8 i,j,data=0;
	for (i=1;i<=8;i++) 
	{
		j=DS18B20_ReadBit();
		data=(j<<7)|(data>>1);
  }						    
	return data;  
}  
  
/************************************************************************************************************************* 
*函数名:void DS18B20_WriteBit(u8 bit)   
*功能  :向DS18B20写入1bit的数据 
*参数  :bit 
*返回  :无
*************************************************************************************************************************/  
void DS18B20_WriteBit(u8 bit)  
{  
    Set18b20IOout();    //设置数据总线接口为输出
    DS18B20_OUT=0;      //拉低数据总线
    delay_us(12);				//延时10-15us  
    DS18B20_OUT= bit&0x01;   //写入数据,
    delay_us(30);				//延时20-45us  
    DS18B20_OUT=1;			//释放总线
    delay_us(5);  
}  
  
/************************************************************************************************************************* 
*函数名:void DS18B20_WriteData(u8 data)    
*功能  :向DS18B20写入1字节的数据 
*参数  :data 
*返回  :无
*************************************************************************************************************************/  
void DS18B20_WriteData(u8 data)  
{  
    u8 i;    
    for(i=0;i< 8;i++)  
    {  
        DS18B20_WriteBit(data);  
        data >>= 1;  
    }  
}  
  
/************************************************************************************************************************* 
*函数名:s16 DS18B20_ReadTemper(void)    
*功能  :读取温度值
*参数  :无 
*返回  :温度值*100
*************************************************************************************************************************/  
s16 DS18B20_ReadTemper(void)  
{  
    u8 th, tl;  
    s16 data;  
	
    if(DS18B20_Reset() == FALSE)				//错误判断      
    {  
        return 0xffff;									//返回错误特征值
    }
    DS18B20_WriteData(SKIP_ROM);    		//跳过ROM  
    DS18B20_WriteData(CONVERT_T);    		//启动温度转换  
    DS18B20_Reset();  
    DS18B20_WriteData(SKIP_ROM);    		//跳过ROM    
    DS18B20_WriteData(READ_SCRATCHPAD); //温度读取指令 
    tl = DS18B20_ReadData();    				//低8位数据
    th = DS18B20_ReadData();    				//高8位数据
    data = th; 
		data = data<<8;
    data = data|tl;  
    data = data*6.25;           				//数值精确到小数点后两位  
      
    return data;												//返回值=温度*100;  
}  
  
/************************************************************************************************************************* 
*函数名:u8 DS18B20_Read2Bit(void)    
*功能  :读取2bit数据
*参数  :无 
*返回  :data
*************************************************************************************************************************/  

u8 DS18B20_Read2Bit(void)  
{  
    u8 i,data = 0;   
    for(i = 0;i < 2;i ++)  
    {  
        data <<= 1;  
        if(DS18B20_ReadBit())
				{
					data = data|1;
				}					  
    }  
    return data;  
}
 
//------------------------------------------------------------------------------
//-----------------------后面的代码使用于多个DS18B20的环境下--------------------
//------------------------------------------------------------------------------
  


/************************************************************************************************************************* 
*函数名:u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)   
*功能  :查询DS18B20的ROM
*参数  :(1)、 pIN:总线上DS18B20的ID存储的缓冲区指针
				(2)、 Num:DS18B20的个数,在MAXNUM中有定义
*返回  :搜索到总线上DS18B20的个数
*************************************************************************************************************************/  

u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)  
{   
    unsigned char k,l=0,ConflictBit,m,n;  
    unsigned char BUFFER[MAXNUM]={0};  
    unsigned char ss[64];
		unsigned char s=0;  
    u8 num = 0;      
    do  
    {  
        DS18B20_Reset();								//复位DS18B20总线  
        DS18B20_WriteData(SEARCH_ROM);	//搜索ROM      
        for(m=0;m<8;m++)  
        {  
//            unsigned char s=0;  
            for(n=0;n<8;n++)  
            {  
                k=DS18B20_Read2Bit();		// 读两位数据
                k=k&0x03;  
                s= s>>1;  
                if(k==0x01)							//0000 0001 如果读到的数据为0
                {             
                    DS18B20_WriteBit(0);//写0,使总线上为0的器件响应  
                    ss[(m*8+n)]=0;  
                }  
                else if(k==0x02)				//0000 0010 如果读到的数据为1
                {  
                    s=s|0x80;  
                    DS18B20_WriteBit (1);//写1,使总线上为1的器件响应    
                    ss[(m*8+n)]=1;  
                }  
                else if(k==0x00)//如果读取到的数据为00,则有冲突,需进行冲突位判断  
                {                
                    ConflictBit=m*8+n+1;                   
                    if(ConflictBit>BUFFER[l])//如果冲突位大于栈顶,则写0   
                    {                         
                        DS18B20_WriteBit (0);  
                        ss[(m*8+n)]=0;                                                
                        BUFFER[++l]=ConflictBit;                         
                    }  
                    else if(ConflictBit
#include "sys.h" 

#ifndef DS18B20_H_  
#define DS18B20_H_
//定义总线上的DS18B20的最大个数MAXNUM
#define MAXNUM 4
  
//DS18B20指令
typedef enum   
{  
    SEARCH_ROM          =   0xf0,   //搜索ROM指令  
    READ_ROM            =   0x33,   //读取ROM指令
    MATH_ROM            =   0x55,   //匹配ROM指令
    SKIP_ROM            =   0xcc,   //跳过ROM指令
    ALARM_SEARCH        =   0xec,   //报警搜索指令 
    CONVERT_T           =   0x44,   //温度转换指令
    WRITE_SCRATCHPAD    =   0x4e,   //写暂存器指令
    READ_SCRATCHPAD     =   0xbe,   //读取转存器指令
    COPY_SCRATCHPAD     =   0x48,   //拷贝暂存器指令  
    RECALL_E2           =   0xb8,   //召回EEPROM指令
    READ_POWER_SUPPLY   =   0xb4,   //读取电源模式指令  
} DS18B20_CMD;  
  
  
  
//DS18B20 ROM编码 
typedef struct  
{  
    u8  DS18B20_CODE;   //DS18B20单总线编码:0x19  
    u8  SN_1;           //序列号第1字节  
    u8  SN_2;           //序列号第2字节
    u8  SN_3;           //序列号第3字节
    u8  SN_4;           //序列号第4字节  
    u8  SN_5;           //序列号第5字节 
    u8  SN_6;           //序列号第6字节
    u8  crc8;           //CRC8校验    
} DS18B20_ROM_CODE;   
  
#define TRUE 0xff
#define FALSE 0X00

//IO方向设置
#define Set18b20IOin()  {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}
#define Set18b20IOout() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}
////IO操作函数											   
#define	DS18B20_OUT PGout(11) //数据端口	PG11 
#define	DS18B20_IN  PGin(11)  //数据端口	PG11

//函数使用申明
int DS18B20_Reset(void);
u8 DS18B20_Init(void);
u8 DS18B20_ReadBit(void);
u8 DS18B20_ReadData(void) ;
void DS18B20_WriteBit(u8 bit);
void DS18B20_WriteData(u8 data);
s16 DS18B20_ReadTemper(void);
u8 DS18B20_Read2Bit(void);
u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num);
s16 DS18B20_ReadDesignateTemper(u8 pID[8]);
#endif /*DS18B20_H_*/

你可能感兴趣的:(STM32F103ZET6)