以下程序在stm32f103开发板上运行可以成功显示多个ds18b20所测的温度值
ds18b20.h
#ifndef __DS18B20_H
#define __DS18B20_H#endif
ds18b20.c
#include "ds18b20.h"
#include "delay.h"
#define MaxSensorNum 8
//存检测到的传感器DS18B20_ID的数组,前面的维数代表单根线传感器数量上限
unsigned char DS18B20_ID[MaxSensorNum][8];
//检测到的传感器数量(从1开始,例如显示1代表1个,8代表8个)
unsigned char DS18B20_SensorNum;
//复位DS18B20
void DS18B20_Rst(void)
{
DS18B20_IO_OUT(); //SET PG11 OUTPUT
DS18B20_DQ_OUT=0; //拉低DQ
delay_us(750); //拉低750us
DS18B20_DQ_OUT=1; //DQ=1
delay_us(15); //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_IO_IN();//SET PG11 INPUT
while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void)
{
u8 data;
DS18B20_IO_OUT();//SET PG11 OUTPUT
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN();//SET PG11 INPUT
delay_us(12);
if(DS18B20_DQ_IN)data=1;
else data=0;
delay_us(50);
return data;
}
//从DS18B20读取2个位
u8 DS18B20_Read_2Bit(void)//读出2个位
{
u8 i;
u8 dat = 0;
for (i = 2; i > 0; i--)
{
dat = dat << 1;
DS18B20_IO_OUT();
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN();
delay_us(12);
if (DS18B20_DQ_IN) dat |= 0x01;
delay_us(50);
}
return dat;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)
{
u8 i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
// 写一位到DS18B20
void DS18B20_Write_Bit(u8 dat)
{
DS18B20_IO_OUT();
if (dat)
{
DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
DS18B20_DQ_OUT=1;
delay_us(2);
}
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)
{
u8 j;
u8 testb;
DS18B20_IO_OUT();//SET PG11 OUTPUT;
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
DS18B20_DQ_OUT=0; // Write 1
delay_us(2);
DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
DS18B20_DQ_OUT=0; // Write 0
delay_us(60);
DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}
//开始温度转换
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Check();
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_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);//使能PORTG口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PORTG.11 推挽输出
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
DS18B20_Rst();
return DS18B20_Check();
}
/*
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
short DS18B20_Get_Temp(void)
{
u8 temp;
u8 TL,TH;
short tem;
DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0xbe); // convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB
if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //温度为负
}else temp=1; //温度为正
tem=TH; //获得高八位
tem<<=8;
tem+=TL; //获得底八位
tem=(float)tem*0.625; //转换
if(temp)return tem; //返回温度值
else return -tem;
}
*/
//从DS18B20得到温度值,精度:0.1C,返回温度值(-55~125),temperature1返回浮点实际温度
float DS18B20_Get_Temp(u8 i)
{
//u8 flag;
u8 j;//匹配的字节
u8 TL, TH;
short Temperature;
float Temperature1;
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert 温度转换
DS18B20_Rst();
DS18B20_Check();
// DS18B20_Write_Byte(0xcc);// skip rom
//匹配ID,i为形参
DS18B20_Write_Byte(0x55); //发出符合ROM命令
for (j = 0; j < 8; j++)
{
DS18B20_Write_Byte(DS18B20_ID[i][j]);
}
DS18B20_Write_Byte(0xbe);// convert 读暂存存储器
TL = DS18B20_Read_Byte(); // LSB
TH = DS18B20_Read_Byte(); // MSB
if (TH > 7) //单片机的温度有11位,第12位是符号位,12-16位是同时变化的
{
//flag=1;
Temperature = (TH << 8) | TL;
Temperature1 = (~Temperature) + 1;
Temperature1 *= 0.0625;
}
else
{
//flag=0;
Temperature1 = ((TH << 8) | TL)*0.0625;
}
return Temperature1;
}
int DS18B20_Search_Rom(u8 Num)
{
unsigned char k,l=0,ConflictBit,m,n;
unsigned char BUFFER[64]={0};
unsigned char ss[64];
unsigned char s=0;
u8 num = 0;
do
{
DS18B20_Rst(); //注意:复位的延时不够
delay_us(480); //480、720
DS18B20_Write_Byte(0xf0);
for(m=0;m<8;m++)
{
// unsigned char s=0;
for(n=0;n<8;n++)
{
k = DS18B20_Read_2Bit();//读两位数据
k=k&0x03;
s= s>>1;
if(k==0x01) //0000 0001 如果读到的数据为0
{
DS18B20_Write_Bit(0); //写0,使总线上为0的器件响应
ss[(m*8+n)]=0;
}
else if(k==0x02) //0000 0010 如果读到的数据为1
{
s=s|0x80;
DS18B20_Write_Bit (1);//写1,使总线上为1的器件响应
ss[(m*8+n)]=1;
}
else if(k==0x00)//如果读取到的数据为00,则有冲突,需进行冲突位判断
{
ConflictBit=m*8+n+1;
if(ConflictBit>BUFFER[l])//如果冲突位大于栈顶,则写0
{
DS18B20_Write_Bit(0);
ss[(m*8+n)]=0;
BUFFER[++l]=ConflictBit;
}
else if(ConflictBit
s=s|((ss[(m*8+n)]&0x01)<<7);
DS18B20_Write_Bit(ss[(m*8+n)]);
}
else if(ConflictBit==BUFFER[l])//如果冲突位等于栈顶,则写1
{
s=s|0x80;
DS18B20_Write_Bit(1);
ss[(m*8+n)]=1;
l=l-1;
}
}
else//如果读到的数据为0x03(0000 0011),则说明单总线上不存在任何设备
{
return num; //搜索完成,返回搜索到的个数
}
delay_us(5);
}
DS18B20_ID[num][m] =s;
s=0;
}
num=num+1;
}
while(BUFFER[l]!=0&&(num<3));
return num; //返回搜索到的个数
}
main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "ds18b20.h"
#include "string.h"//strlen、memset用到
#include "stdio.h"
#include "stm32f10x.h"
//检测到的传感器ID存数组
extern unsigned char DS18B20_ID[8][8];
extern unsigned char DS18B20_SensorNum;
int main(void)
{
u8 num=0,i;
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为 9600
while(DS18B20_Init())//初始化DS18B20,18B20
{
printf("DS18B20 Check Failed!\r\n");
delay_ms(400);
}
printf("DS18B20 Ready!\r\n");
while(1)
{
//DS18B20_Search_Rom();
num = DS18B20_Search_Rom(2);
printf("总线上挂载的DS18B20数量为: %d\r\n",2);
printf("搜索到的DS18B20数量为: %d\r\n",num);
// printf("DS18B20_SensorNum:%d\r\n",DS18B20_SensorNum);
for(i=0;i
printf("ID:%02x%02x%02x%02x%02x%02x%02x%02x TM:%.2f\r\n",DS18B20_ID[i][0],DS18B20_ID[i][1],DS18B20_ID[i][2],DS18B20_ID[i][3],DS18B20_ID[i][4],DS18B20_ID[i][5],DS18B20_ID[i][6],DS18B20_ID[i][7],DS18B20_Get_Temp(i));
}
printf("\r\n");
delay_ms(1800);
}
}
串口上显示的信息为: