DS18B20驅動程序源代碼如下:
#include 《ds18b20.h》
#include “delay.h”
#include “usart.h”
//ds18b20初始化
void init_ds18b20( void )
{
init_onewire_out();
GPIO_ResetBits(GPIOG,GPIO_Pin_9);
delay_us(480);
init_onewire_in();
delay_us(60);
if( !DQ_In)
{
delay_us(120);
}
}
//ds18b20 檢測
void chack_ds18b20( void )
{
init_onewire_out();
GPIO_ResetBits(GPIOG,GPIO_Pin_9);
delay_us(240);
init_onewire_in();
delay_us(60);
if( !DQ_In)
{
delay_us(80);
if( !DQ_In )
printf(“檢測到DS18B20! ”);
}
}
//設置為主設備寫總線,從設備讀總線
void init_onewire_out( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
}
//設置為主設備讀取總線,從設備寫總線
void init_onewire_in( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式
// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
}
void ds18b20_write_byte( u8 data )
{
u8 i;
u8 j=0;
init_onewire_out();
for(i=0;i《8;i++)
{
j=data & 0x01;
if(j)
{
DQ_Out=0; //寫1
delay_us(15);
DQ_Out=1;
delay_us(60);
}
else
{
DQ_Out=0; //寫0
delay_us(60);
DQ_Out=1;
delay_us(1);
}
data = data》》1;
}
}
//讀取DS18B20 的一位
u8 ds18b20_read_bit( void )
{
u8 bit;
init_onewire_out();
DQ_Out=0;
delay_us(2);
DQ_Out=1;
init_onewire_in();
delay_us(12);
if(DQ_In)
bit=1;
else
bit=0;
delay_us(50);
return bit;
}
//讀ds18b20的字節
u8 ds18b20_read_byte ( void )
{
u8 data=0;
u8 i;
u8 j=0;
for(i=0;i《8;i++)
{
j=ds18b20_read_bit();
if(j) //注意順序即可,ds18b20先發送地位到總線上
j=j《《i;
data |=j;
}
return data;
}
//獲取ds18b20的系列碼和48位唯一序列號
void ds18b20_read_rom_number()
{
u32 number=0;
u8 data,i,serial_num,ds18b20_crc;
init_ds18b20();
ds18b20_write_byte(0x33);
serial_num = ds18b20_read_byte();
for(i=0;i《6;i++)
{
data = ds18b20_read_byte();
number |= data;
number = number《《8;
}
ds18b20_crc = ds18b20_read_byte();
printf(“系列號是:%d ”,serial_num);
printf(“序列號是:%d ”,number);
printf(“CRC校驗為:%d ”,ds18b20_crc);
}
//開啟ds18b20溫度轉換
void tem_chage( void )
{
init_ds18b20();
ds18b20_write_byte(0xcc); //忽略rom指令
ds18b20_write_byte(0x44); //開啟轉換
}
short get_temp( void )
{
int temp=0;
u8 i,TH,TL;
short tem;
tem_chage();
delay_us(10);
init_ds18b20();
ds18b20_write_byte(0xcc); //忽略rom指令
ds18b20_write_byte(0xbe); //讀取溫度轉換值
TL=ds18b20_read_byte();
TH=ds18b20_read_byte();
if(TH 》 7) //通過判讀存儲器的高五位的0,1來判斷溫度的正負,
{
temp = 0; //為負
TH =~TH;
TL =~TL;
}
else
temp = 1; //為正
tem = TH;
tem =tem《《8;
tem =tem+TL;
tem = (double)tem * 0.625;
if(temp)
return tem;
else
return -tem;
}
void ds18b20_return_TH_TL_CONF( void )
{
char data,data_TH,data_TL,CONF;
init_ds18b20();
ds18b20_write_byte(0xcc); //忽略rom指令
ds18b20_write_byte(0xbe); //讀取溫度轉換值
data = ds18b20_read_byte();
data = ds18b20_read_byte();
data_TH = ds18b20_read_byte();
data_TL = ds18b20_read_byte();
CONF =ds18b20_read_byte();
printf(“過溫報警的溫度為:%d℃ ”,data_TH);
printf(“低溫報警的溫度為:%d℃ ”,-(data_TL-128));
CONF &=0x60 ;
CONF =CONF》》5;
switch (CONF) {
case 0:
printf(“ds18b20的測量精度為9位,精度為0.5℃ ”);
break;
case 1:
printf(“ds18b20的測量精度為10位,精度為0.25℃ ”);
break;
case 2:
printf(“ds18b20的測量精度為11位,精度為0.125℃ ”);
break;
case 3:
printf(“ds18b20的測量精度為12位,精度為0.0625℃ ”);
break;
default:
printf(“error!! ”);
break;
}
}
評論