stm32f103采集DS18B20温度驱动程序
温度传感器DS18B20驱动程序
TempDelay(20); //20
_nop_();
_nop_();
D18B20 = 1;
}
void WriteByte (unsigned char wr) //单字节写入
}
void Star18b20(void)
{
Res18b20();
WriteByte(0xcc);
WriteByte(0x44);
}
void Config18b20 (void) //重新配置报警限定值和分辨率
{
Res18b20();
WriteByte(0xcc); //skip rom
_nop_();
_nop_();
D18B20=1;
wr >>= 1;
}
}
unsigned char ReadByte (void) //读取单字节
{
unsigned char i,u=0;
void RedaByte (void);
void ReadRAM (unsigned char j);
float GetTemp (void);
void Config18b20 (void);
void Star18b20 (void);
void TempDelay (unsigned char us)
TempDelay(14); //delay 100 uS//14
_nop_();
_nop_();
_nop_();
if(D18B20==0)
flag = 1; //detect 1820 success!
DS18B20温度采集和显示程序
这个是我自己制作的51单片机板上的DS18B20温度采集和显示程序,你如果有现成的51板稍微修改一下可以用,在我这里是可以用没问题的。
环境是KEIL。
我这个51板也完全符合你的要求。
#pragma db code#include<AT89X52.H>//#include "reg52.h"#include "INTRINS.H"// 此实验是使用18B20检测温度,然后在数码管上显示#define uchar unsigned char#define uint unsigned int#define BUSY1 (DQ1==0)sbit LED_0=P1^0;sbit LED_1=P1^1;sbit LED_2=P1^2;sbit LED_3=P1^3;sbit DQ1=P1^6;//void delay(uint x);void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);void ds_reset_1(void);void wr_ds18_1(char dat);void time_delay(unsigned char time);int get_temp_1(void);void delay(unsigned int x);void read_ROM(void);int get_temp_d(void);/*=====0-9=====A-G=====*/uchar a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0x86,0x8e,0x82}; unsigned char ResultSignal;int ResultTemperatureLH,ResultT emperatureLL,ResultTemperatureH; unsigned char ROM[8];unsigned char idata TMP;unsigned char idata TMP_d;unsigned char f;unsigned char rd_ds18_1();unsigned int TemH,TemL;void main(){unsigned int TemH,TemL,k=0;ds_reset_1();ds_reset_1(); //resetwr_ds18_1(0xcc); //skip rom_nop_();wr_ds18_1(0x7f);ds_reset_1();wr_ds18_1(0xcc);_nop_();wr_ds18_1(0x44);for(k=0;k<11000;k++)time_delay(255);ds_reset_1();while(1){wr_ds18_1(0xcc);wr_ds18_1(0xbe);TemH=get_temp_1();TemL=get_temp_d();TemH&=0x00ff;TemL&=0x00ff;display((TemH/10),(T emH%10),(TemL/10),(TemL%10));}}/***************延时程序,单位us,大于10us*************/ void time_delay(unsigned char time){time=time-10;time=time/6;while(time!=0)time--;}/*****************************************************//* reset ds18b20 */ /*****************************************************/void ds_reset_1(void){unsigned char idata count=0;DQ1=0;time_delay(240);time_delay(240);DQ1=1;return;}void check_pre_1(void){while(DQ1);while(~DQ1);time_delay(30);}void read_ROM(void){int n;check_pre_1();wr_ds18_1(0x33);for(n=0;n<8;n++){ROM[n]=rd_ds18_1();}}/*****************************************************//* Read a bit from 1820 位读取*/ /*****************************************************/bit tmrbit_1(void){idata char i=0;bit dat;DQ1=0;_nop_();DQ1=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();dat = DQ1;time_delay(50);return dat;}/*****************************************************//* read a bety from ds18b20 字节读取*/ /*****************************************************/unsigned char rd_ds18_1(){unsigned char idata i,j,dat=0;for(i=1;i<=8;i++){j=tmrbit_1();dat=(j<<(i-1))|dat;}return dat;}/*****************************************************//* write a bety from ds18b20 写字节*/ /****************************************************/void wr_ds18_1(char dat){signed char idata i=0;unsigned char idata j;bit testb;for(j=1;j<=8;j++){testb=dat & 0x01;dat = dat>>1;if(testb){DQ1=0;_nop_();_nop_();DQ1=1;time_delay(60);}else{DQ1=0;time_delay(50);DQ1=1;_nop_();_nop_();}}}int get_temp_1(void){unsigned char idata a=0,b=0; unsigned char idata i;EA=0;ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4));a=(a&0x0f);if (a>8){TMP=(TMP+1);}}else{f=1;a=a>>4;b=b<<4;TMP=(a|b);TMP=~TMP;TMP=(TMP+1);}EA=1;return(TMP);}int get_temp_d(void){unsigned char idata a=0,b=0; unsigned char idata i,m;EA=0;ds_reset_1();//复位check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0x44);while(BUSY1);ds_reset_1();check_pre_1();wr_ds18_1(0xcc);wr_ds18_1(0xbe);a=rd_ds18_1();b=rd_ds18_1();i=b; /*若b为1则为负温*/ i=(i>>4);if(i==0){f=0;TMP=((a>>4)|(b<<4)); a=(a&0x0f);TMP_d=a;}else{f=1;a=~a;a=(a+1);b=~b;b=(b+1);m=a;a=a>>4;b=b<<4;TMP=(a|b);m=(m&0x0f);TMP_d=m;}EA=1;return(TMP_d);}void delay(unsigned int x) {unsigned int i;for(i=0;i<x;i++);}void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4) {P2=a[d1];LED_0=0;delay(100);LED_0=1;P2=a[d2];LED_1=0;delay(100);LED_1=1;P2=a[d3];LED_2=0;delay(100);LED_2=1;P2=a[d4];LED_3=0;delay(100);LED_3=1;}。
STM32下DS18B20驱动程序,适用于ucos系统
#include "bsp.h"
HAL_DS18B20_T HAL_DS18B20;
/*********************************
硬件配置DATA:PC1
*********************************/
#define DS18B20GPIO GPIOA
#define DS18B20PIN GPIO_Pin_7
*形参:无
*返回值:无
*********************************************************************************************************
*/
int DS18B20_read_bit(void)
{
int ret;
return ret;
}
/*
*********************************************************************************************************
*函数名: DS18B20_write_byte
*功能说明: DS18B20写1个字节,低字节先写;
{
int i;
for(i=0; i<8; i++)
{
DS18B20_write_bit((data>>i)&0x01);
}
}
/*
*********************************************************************************************************
stm32--温度传感器DS18B20使用
void Delay_us(u32 Nus)
{
SysTick->LOAD=Nus*9;
//时间加载
SysTick->CTRL|=0x01;
//开始倒数
while(!(SysTick->CTRL&(1<<16))); //等待时间到达
SysTick->CTRL=0X00000000;
//关闭计数器
SysTick->VAL=0X00000000;
//清空计数器
}
unsigned char ResetDS18B20(void) { unsigned char resport; SetDQ(); Delay_us(50);
ResetDQ(); Delay_us(500); //500us (该时间的时间范围可以从480到960微秒) SetDQ(); Delay_us(40); //40us //resport = GetDQ(); while(GetDQ()); Delay_us(500); //500us SetDQ(); return resport; }
void DS18B20WriteByte(unsigned char Dat) { unsigned char i; for(i=8;i>0;i--) {
ResetDQ(); //在15u内送数到数据线上,DS18B20在15-60u读数 Delay_us(5); //5us if(Dat & 0x01) SetDQ(); else ResetDQ(); Delay_us(65); //65us SetDQ(); Delay_us(2); //连续两位间应大于1us Dat >>= 1; } }
温度传感器DS18B20检测程序说明
DS18B20美国达拉斯公司生产的单总线协议的数字温度检测芯片,数据的写入与读取都在一根总线上进行操作,在总线上可以连接多个DS18B20,因为每个DS18B20都有唯一的光刻ROM序列号,所以可以进行ROM匹配,搜索指令进行选择相应的从机序列号。
编写DS18B20的检测程序主要包括:初始化函数(复位脉冲+存在脉冲),写数据函数,读取数据的函数。
对DS18B20的操作包括:初始化函数,ROM指令,RAM指令这三个部分。
接下来我先说一下这三个部分所对应的时序图的理解吧。
初始化:由于上拉电阻的存在,总线默认状态是高电平,接着主机将总线拉低,维持480us 到960us的时间,再接着就是释放总线,维持时间为15us到60us,接着就由从机发出一个低电平信号,将总线拉低,表示该DS18B20是正常地,或者说是存在的,其维持时间为60us 到240us。
上面一图是写入数据的时序图。
写时序:默认状态为高电平,先将总线拉低,至少维持1us 的延时时间,接着就往总线上进行写数据操作,接着DS18B20就开始采样数据了,整个过程时间为60us到120us。
下面一图是读取数据的时序图。
读时序:默认状态为高电平,先将总线拉低,接着在15us 之前,主机进行数据采样,其维持时间也为60us到120us。
下面是我在理解了DS18B20的原理之后所写的程序,调试成功了,且能实时读取外界温度的功能,这里是不读取小数部分的温度,只读取温度的正数值。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit DQ=P2^2;sbit duan=P2^6;sbit wei=P2^7;//是在11.0592M赫兹的频率下void delay_ms(uint t){uint i;for(;t>0;t--)for(i=110;i>0;i--);} //约为tms的延时程序void delay(uint x){while(x--);}void init_ds18b20(){uchar n;DQ=1;delay(2); //约为38usDQ=0;delay(80); //约为800usDQ=1;delay(4); //约为58usn=DQ;delay(10); //约为110us}void write_byte(uchar dat){uchar i;for(i=0;i<8;i++){DQ=0; //无论是写0或写1都要有至少1us的低电平DQ=dat&0x01;//总线直接等于写入的数据(低位在前,高位在后)delay(4); //约为58usDQ=1; //释放总线,为下一步的数据变换做准备dat>>=1;//数据进行移位操作}delay(4);}uchar read_byte(){uchar i,value;for(i=0;i<8;i++){DQ=0;value>>=1; //移位7次DQ=1; //先要释放总线,那样才能采样到有效数据if(DQ) //判断8次{value|=0x80;}delay(6); //约为78us}return value;}uchar read_temperature(){uchar a,b;init_ds18b20(); //每次操作指令前,都必须进行初始化设置write_byte(0xcc);//跳过ROM指令write_byte(0x44);//进行温度转换处理delay(300);//进行一定地延时约为3ms左右init_ds18b20();write_byte(0xcc);//跳过ROM操作write_byte(0xbe);//读取温度a=read_byte();//温度低字节b=read_byte();//温度高字节b<<=4;//b左移四位,低四位为0000b=b+(a&0xf0)>>4;//将a的低四位屏蔽,不取小数点,进行右移四位,合并成一个字节的数据return b;}void display(uchar aa,uchar bb) {duan=1;P0=table[aa];duan=0;P0=0xff;wei=1;P0=0xfe;wei=0;delay_ms(5);duan=1;P0=table[bb];duan=0;P0=0xff;wei=1;P0=0xfd;wei=0;delay_ms(5);}void main(){uchar num,shi,ge;while(1){num=read_temperature();shi=num/10; //分离出十位ge=num%10; //分离出个位display(shi,ge);}}。
(完整word版)DS18B20水温控制系统+电路图程序
水温控制系统摘要:该水温控制系统采用单片机进行温度实时采集与控制。
温度信号由“一线总线”数字化温度传感器DS18B20提供,DS18B20在-10~+85°C范围内,固有测温分辨率为0.5 ℃。
水温实时控制采用继电器控制电热丝和风扇进行升温、降温控制.系统具备较高的测量精度和控制精度,能完成升温和降温控制。
关键字:AT89C51 DS18B20 水温控制Abstract: This water temperature control system uses the Single Chip Microcomputer to carry on temperature real-time gathering and controling。
DS18B20,digitized temperature sensor, provides the temperature signal by "a main line”. In -10~+85℃the scope,DS18B20’s inherent measuring accuracy is 0.5 ℃. The water temperature real-time control system uses the electricity nichrome wire carring on temperature increiseament and operates the electric fan to realize the temperature decrease control。
The system has the higher measuring accuracy and the control precision,it also can complete the elevation of temperature and the temperature decrease control. Key Words:AT89C51 DS18B20 Water temperature control目录1.系统方案选择和论证 (2)1。
DS18B20驱动程序
DS18B20驱动程序作者: 嵌入式应用软件园目录第1章程序功能 (3)第2章程序代码 (4)第3章DS18B20简介 (11)3.1 DS18B20概述 (11)3.2 DS18B20的内部结构 (11)3.3 DS18B20温度传感器的存储器 (12)3.4 DS18B20使用中注意事项 (13)3.4 DS18B20常用命令详述 (14)DS18B20驱动程序DS18B20_MAIN,您可以直接在你的应用当中使用,直接返回温度的BCD码值。
BCD码值可以直接在数码管或LCD 上显示出来。
驱动程序中包含DS18B20温度传感器用到的全部函数。
如,DS18B20的复位函数(RESET_18B20)、写函数(WRITE_18B20)、读函数(READ_18B20),读出ROM中64的ID函数(READ_18B20ID),搜索DS18B20的ID函数(CHECK_18B20ID),警报搜索(ALARM_18B20ID)。
直接调用函数RE_TEMP,会返回当前的温度值。
再经过函数CONV_TEMP转换后,可以返回温度值的BCD码值。
我们的辛勤付出,需要您的肯定,请访问: 嵌入式应用软件园。
如需源代码/此代码技术支持,请访问: 嵌入式应用软件园。
第3章DS18B20简介3.1 DS18B20概述DS18B20 “一线总线”数字化温度传感器是DALLAS最新单线数字温度传感器,测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。
现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。
适合于恶劣环境的现场温度测量,支持3V~5.5V的电压范围,使系统设计更灵活、方便。
而且新一代产品更便宜,体积更小。
DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。
可选更小的封装方式,更宽的电压适用范围。
完整DS18B20温度测控程序
#include<reg52.h>sbit s2=P0^0;sbit led=P1^3;unsigned char wendushangxian=0;sbit DQ=P1^6;sbit wei1=P3^0;sbit wei2=P3^1;sbit wei3=P3^2;sbit wei4=P3^3;sbit key_Max_jia=P0^0;sbit key_Max_jian=P0^1;sbit key_Min_jia=P0^2;sbit key_Min_jian=P0^3;sbit dianji_jian=P1^2;sbit dianji_jia=P1^7;sbit Led_tempreture_Max=P1^3;sbit Led_tempreture_Min=P1^4;sbit Led_normal=P1^5;unsigned char num[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; int tempreture_Max=40;int tempreture_Min=-10;void delay_mylself(int temp){unsigned int i,j;for(i=0;i<temp;i++)for(j=0;j<1140;j++);}void delay(unsigned int i) //如果i是unsigend char类型,则会出现错误结果{while(i--);}void DS18B20_Init(void)//初始化{unsigned char flag=0;DQ = 1; //DQ复位delay(1);DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480us小于960usDQ = 1; //拉高总线delay(6);while(DQ);while(!DQ);//flag=DQ; //稍做延时后如果flag=0则初始化成功flag=1则初始化失败//delay(30);}unsigned char Read(void)//读字节{unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay(5);}return(dat);}void Write(unsigned char dat)//写字节{unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}}void init(){wei1=0;wei2=0;wei3=0;wei4=0;}void Display(unsigned int temp){unsigned char one,two,three,four;int wendu=0;if(temp<=0xf000){ temp>>=4; //右移4位,相当于乘0.0625,将温度化为十进制//temp*=10; //扩大10倍,显示一位小数one=temp/1000; //千位two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位wendu=temp;}else{temp=~temp;temp+=1;temp>>=4;one=10; //负数two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位wendu=-temp;}if(wendu>tempreture_Max){Led_tempreture_Max=0;Led_tempreture_Min=1;Led_normal=1;dianji_jian=1;dianji_jia=0;}else if(wendu<tempreture_Min){Led_tempreture_Max=1;Led_tempreture_Min=0;Led_normal=1;dianji_jia=1;dianji_jian=0;}else{Led_tempreture_Max=1;Led_tempreture_Min=1;Led_normal=0;dianji_jian=0;dianji_jia=0;}//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[one];delay_mylself(1);//第2位wei1=0;wei2=1;wei3=0;wei4=0;P2=num[two];delay_mylself(1);//第3位wei1=0;wei2=0;wei3=1;wei4=0;P2=num[three];delay_mylself(1);//第4位wei1=0;wei2=0;wei3=0;wei4=1;P2=num[four];delay_mylself(10);}void common_display(int temp){unsigned char one,two,three,four;one=temp/1000; //千位two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位if(temp<0){temp=-temp;two=temp%1000/100; //百位three=temp%1000%100/10; //十位four=temp%1000%100%10; //个位//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[10];delay_mylself(50);}else{//第1位wei1=1;wei2=0;wei3=0;wei4=0;P2=num[one];delay_mylself(50);}//第2位wei1=0;wei2=1;wei3=0;wei4=0;P2=num[two];delay_mylself(50);//第3位wei1=0;wei2=0;wei3=1;wei4=0;P2=num[three];delay_mylself(50);//第4位wei1=0;wei2=0;wei3=0;wei4=1;P2=num[four];delay_mylself(60);}void key(){unsigned char flag=0;if(key_Max_jia==0){flag=1;tempreture_Max+=1;if(tempreture_Max>125){tempreture_Max=125;}while(!key_Max_jia); //按键松手检测}else if(key_Max_jian==0){flag=2;tempreture_Max-=1;if(tempreture_Max<tempreture_Min){tempreture_Max=tempreture_Min;}while(!key_Max_jian); //按键松手检测}else if(key_Min_jia==0){flag=3;tempreture_Min+=1;if(tempreture_Min>tempreture_Max){tempreture_Min=tempreture_Max;}while(!key_Min_jia); //按键松手检测}else if(key_Min_jian==0){flag=4;tempreture_Min-=1;if(tempreture_Min<-55){tempreture_Min=-55;}while(!key_Min_jian); //按键松手检测}if(flag==1||flag==2){common_display(tempreture_Max);delay_mylself(200);flag=0;}else if(flag==4||flag==3){common_display(tempreture_Min);delay_mylself(200);flag=0;}}void main(){unsigned int temp;unsigned char tl=0,th=0;while(1){DS18B20_Init();Write(0xCC); // 跳过读序号列号的操作Write(0x44); // 启动温度转换delay(100);DS18B20_Init();Write(0xCC); //跳过读序号列号的操作Write(0xBE); //读取温度寄存器等delay(100);tl=Read(); //读取温度值低位th=Read(); //读取温度值高位temp=th<<8;temp|=tl;Display(temp);key();}}。
18b20在stm32上驱动并附18b20详细资料[1]
光刻 rom 中的 64 位序列号是出厂前被光刻好的,它可以看作是该 ds18b20 的地址序列码。64 位光刻 rom 的排列是:开始 8 位(地址: 28h )是产品类 型标号,接着的 48 位是该 ds18b20 自身的序列号,并且每个 ds18b20 的序 列号都不相同,因此它可以看作是该 ds18b20 的地址序列码;最后 8 位则是 前面 56 位的循环冗余校验码( crc=x8+x5+x4+1 )。由于每一个 ds18b20 的 rom 数据都各不相同,因此微控制器就可以通过单总线对多个 ds18b20 进行寻 址,从而实现一根总线上挂接多个 ds18b20 的目的。
配置寄存器
配置寄存器是配置不同的位数来确定温度和数字的转化。
TM
R1
RO
1
1
1
1
1
低五位一直都是"1",TM 是测试模式位,用于设置 DS18B20 在工作模式还是 在测试模式。在 DS18B20 出厂时该位被设置为 0,用 户不要去改动。R1 和 R0 用来设置分辨率(DS18B20 出厂时被设置为 12 位)
二、DS18B20 结构.............................................................................................. 4 1.DS18B20 芯片封装结构:........................................................................... 4 2.DS18B20 内部结构: ................................................................................. 5
DS18B20温度计完整单片机程序(汇编语言)
end
sjmp dis1
dis :
movc a,@a+dptr
CLR P2.2
clr P2.1 ;低位灭
mov p0,a
call delay3
dis1:
mov a,b
movc a,@a+dptr
setb P2.2
clr P2.1 ;高位灭
mov p0,a
call delay3
djnz r1,write_bit
ret
;*****************************************
;读一个字节(内容放在在A中)
read_byte:
mov r2,#8
read_bit:
clr p1.7
nop
nop
nop
nop
setb p1.7 ;释放总线的目的是为了读18b20发出的数据,低电平是不能读的。
sjmp f1
f:clr 20h.0 ;初始化失败置0
f1:
ret
;*****************************************
;写一个字节(内容在A中)
write_byte:
mov r1,#8
;写一位
write_bit:
rrc a ;先写低位
clr 20h.0
mov a, #0cch ;跳过序列号
call write_byte
mov a,#0BEH ;送入读内部ram命令
call write_byte
call read_byte
mov r6,a
call read_byte
DS18B20测温程序
//温度高于26摄氏度则蜂鸣器响#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbitdula=P2^6;sbitwela=P2^7;sbit beer=P2^3; //控制蜂鸣器sbitdsb=P2^2; //ds18b20的数据总线sbitrs=P3^5; //液晶显示数据命令选择端口sbitlcme=P3^4; //液晶显示使能信号sbit key=P3^7;uint temp; //温度传感器测得的温度uchar code listone[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};ucharcodelisttwo[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; ucharcodelistthree[]={"The temp is under:"};void delay(uchari){while(--i);}Voiddelayone(uint z){uintx,y;for(x=100;x>0;x--)for(y=z;y>0;y--);}/*液晶显示写命令初始化*/ Voidwritecom(uchar com) {rs=0;delayone(2);lcme=0;P0=com;lcme=1;delayone(2);lcme=0;}/*液晶显示写数据初始化*/ void writebyte(uchar byte) {rs=1;delayone(2);lcme=0;P0=byte;lcme=1;delayone(2);lcme=0;}/*液晶显示初始化*/ void ds18b20init() {uinttempone;uinti;dula=0;wela=0;lcme=0;writecom(0x38);writecom(0x0f);writecom(0x06);writecom(0x80);for(i=0;i<16;i++){writebyte(listthree[i]);delayone(2);}writecom(0x80+0x40);for(i=0;i<16;i++){tempone=temp&0x80;writebyte(tempone);delay(2);temp<<=1;}writecom(0x0c);}/*温度传感器初始化*/ voidtempinit(){dsb=1;delay(1);dsb=0;delay(250);dsb=1;delay(100);}voidwritedata(uchardat) {uinti;for(i=0;i<8;i++){dsb=1;_nop_();dsb=0;_nop_();_nop_();dsb=dat&0x01;delay(10);dat>>=1;delay(1);}dsb=1;}ucharreaddata(){uinti;for(i=0;i<8;i++){dsb=1;_nop_();dsb=0;_nop_();_nop_();// date>>=1;dsb=1;delay(1);date>>=1; //右移放于此处也可以if(dsb==1)date|=0x80;delay(10);}return date;}uint control(){floattt;// uint temp;tempinit();writedata(0xcc);writedata(0x44);tempinit();writedata(0xcc);writedata(0xbe);a =readdata();b = readdata();temp = b;temp<<= 8;temp = temp|a;tt = temp*0.0625;temp = tt*100+0.05;return temp;}voidshuma(uint temp) {ucharbai,shi,ge,xiaoshu; bai=(temp/1000);shi=temp%1000/100; ge=temp%100/10; xiaoshu=temp%10;dula=1;P0=listone[bai];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delayone(1);dula=1;P0=listtwo[shi];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delayone(1);dula=1;P0=listone[ge];dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delayone(1);dula=1;P0=listone[xiaoshu];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(10);}void warning(uint temp){if((temp>=2600)&&(temp<2800)&&(key==1)){beer=0;P1=0x55;delayone(4);}if((key==0)||(temp<2600)){delayone(5);if((key==0)||(temp<2600)){beer=1;P1=0xff;}}}void main(){while(1){if(temp<2600){shuma(control());}if((temp>=2600)&&(temp<2800)){shuma(control());warning(temp);}if(temp>=2800){dula=0;wela=0;P0=0xff;}}}。
stm32基于ds18b20的温度测量实例 实验原理
stm32基于ds18b20的温度测量实例实验原理
DS18B20是一款数字温度传感器,其测温范围为-55℃到+125℃,在-10℃到+85℃范围内误差为±°。
主机和从机通信使用单总线,即使用单线进行数据的发送和接收,在使用中不需要任何外围元件,独立芯片即可完成工作。
每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值。
单总线即只有一根数据线,系统中的数据交换,控制都由这根线完成。
One-Wire总线利用一根线实现双向通信,其协议对时序的要求较严格,如应答等时序都有明确的时间要求。
基本的时序包括复位及应答时序,写一位时序,读一位时序。
在复位及应答时序中,主器件发出复位信号后,要求从器件在规定的时间内送回应答信号;在位读和位写时序中,主器件要在规定的时间内读回或写出数据。
DS18B20的原理是基于以上这些特性的。
如果需要更详细的实验原理,可
以查阅相关资料或咨询专业人士获取帮助。
DS18B20温度传感器的C语言程序
下面是DS18B20的子程序,#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar a;sbit DQ=P2^0;void reset(); //DS18B20复位函数void write_byte(uchar val); //DS18B20写命令函数uchar read_byte(void); //DS18B20读1字节函数void read_temp(); //温度读取函数void work_temp(); //温度数据处理函数uchar data temp_data[2]={0x00,0x00};uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //对于温度显示值值uchar codeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//温度小数部分查表main(){while(1){reset();write_byte(a);read_byte();read_temp();work_temp();}}void delay1(uint t) {for(;t>0;t--);}///////温度控制子函数void reset(){uchar presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_(); DQ=0; delay1(50);DQ=1;delay1(6);presence=DQ;}delay1(45);presence=~DQ;}DQ=1;}void write_byte(uchar val){uchar i;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_(); DQ=val&0x01; delay1(6);val=val/2;}DQ=1;_nop_();}uchar read_byte(void){uchar i;uchar value=0;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ=0;_nop_();_nop_();_nop_();_nop_();DQ=1;_nop_();_nop_();_nop_();_nop_(); if(DQ)value|=0x80; delay1(6);}DQ=1;return(value);}void read_temp(){reset();write_byte(0xcc);write_byte(0xbe);temp_data[0]=read_byte();temp_data[1]=read_byte();reset();write_byte(0xcc);write_byte(0x44);}void work_temp(){if(temp_data[1]>127){temp_data[1]=(256-temp_data[1]);temp_data[0]=(256-temp_data[0]);}display[4]=temp_data[0]&0x0f; //低位的低4位display[0]=ditab[display[4]]; //小数点后的数值display[4]=((temp_data[0]&0xf0) >>4)|((temp_data[1]&0x0f)<<4); //小数点前的数值display[3]=display[4] / 100;display[1]=display[4] % 100;display[2]=display[1] / 10;display[1]=display[1] % 10;}。
温度传感器DS18B20驱动程序(C语言)
#include <main.h>
sbit DQ =P3^4; //定义通信端口
//延时函数
/*void delay(unsigned int i)
{
while(i--);
}
*/
//初始化函数
void DS18B20_Set()
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//读一个字节
uchar ReadOneChar()
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
WriteOneChar(0x4e);
WriteOneChar(0x88);
WriteOneChar(0x44);
WriteOneChar(Set_bit);
DS18B20_Set();
Delay_100ms;
DS18B20_Set();
WriteOneChar(0xcc);
WriteOneChar(0x48);
}
*/
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(100); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(14);
{
uchar a,b;
uchar minus_flag;
基于STM32的 DS18b20 驱动程序
基于STM32的 DS18b20 驱动程序//=========================DS18b20.h=========================// /*-----------------------------------------------DS18b20驱动程序------------------------------------------------*/#ifndef __DS18B20_H#define __DS18B20_Htypedef enum{FAILED = 0 ,PASSED = !FAILED} TestStatus ;#define DQ_GPIO GPIOD#define DQ_GPIO_Pin GPIO_Pin_5//REGISTER COMMANDS#define REGISTER_9_BITS 0x1F#define REGISTER_10_BITS 0x3F#define REGISTER_11_BITS 0x5F#define REGISTER_12_BIT2 0x7F//ROM COMMANDS#define ROM_Search_Cmd 0xF0#define ROM_Read_Cmd 0x33#define ROM_Match_Cmd 0x55#define ROM_Skip_Cmd 0xCC#define ROM_AlarmSearch_Cmd 0xEC //DS18b20 FUNCTION COMMANDS#define Convert_T 0x44 #define Write_Scratchpad 0x4E#define Read_Scratchpad 0xBE#define Copy_Scratchpad 0x48#define Recall_EEPROM 0x88#define Read_PowerSupply 0x84#define DQ_Write_1() GPIO_SetBits(DQ_GPIO ,DQ_GPIO_Pin) //写1#define DQ_Write_0() GPIO_ResetBits(DQ_GPIO ,DQ_GPIO_Pin)//写0 #define DQ_ReadBit() GPIO_ReadInputDataBit(DQ_GPIO ,DQ_GPIO_Pin) //读DQ上的值extern void GPIO_DQ_Out_Mode(void) ; //DQ输出模式extern void GPIO_DQ_Input_Mode(void) ; //DQ输入模式extern void Tx_ResetPulse(void) ; //发送复位脉冲extern void Rx_PresencePulse(void) ; //接受应答信号extern void Write_OneByte_ToDS18b20(unsigned char data) ; //写一个字节到18b20 extern unsigned char Read_OneByte_FromDS18b20(void) ; //从18b20读一个字节 extern void Read_Temperature(unsigned char*sign ,unsigned char *interger ,unsigned int *decimal) ; //读温度//写配置参数TH,TL和初始化配置寄存器extern void Write_EEPROM(unsigned char Th,unsigned char Tl,unsigned charRegister_Con );void DS18B20_Init(void) ; //初始化#endif /*DS18B20*///=================================================================/ ///=========================DS18b20.c================================ //#include "stm32f10x_lib.h"#include "DS18b20.h"#include "SysTick_Delay.h"/****************************************** 函数名称:GPIO_DQ_Out_Mode功能:设置DQ引脚为开漏输出模式参数:无返回值 :无*******************************************/ voidGPIO_DQ_Out_Mode(void){GPIO_InitTypeDef GPIO_InitStructure ;GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ; }/****************************************** 函数名称:GPIO_DQ_Input_Mode功能:设置DQ引脚为浮空输入模式参数:无返回值 :无*******************************************/ voidGPIO_DQ_Input_Mode(void){GPIO_InitTypeDef GPIO_InitStructure ;GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; //浮空输入GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ; }/****************************************** 函数名称:Tx_ResetPulse 功能:发送复位脉冲参数:无返回值 :无*******************************************/ void Tx_ResetPulse(void) {GPIO_DQ_Out_Mode() ;DQ_Write_0() ; //复位脉冲Delay_Nus(500) ; //至少保持480usDQ_Write_1() ; //加速上升沿速度Delay_Nus(1) ;}/****************************************** 函数名称:Rx_PresencePulse功能:接受应答信号参数:无返回值 :无*******************************************/ voidRx_PresencePulse(void){GPIO_DQ_Input_Mode() ;while( DQ_ReadBit()) ; //等待DS18b20应答while( DQ_ReadBit() == 0) ; //DS18b20将总线拉低60~240us ,然后总线由上拉电阻拉高Delay_Nus(300) ;GPIO_DQ_Out_Mode() ; //接受完成,主机重新控制总线}/****************************************** 函数名称:Write_OneByte_ToDS18b20功能:写一个字节到DS18b20参数:无返回值 :无*******************************************/ voidWrite_OneByte_ToDS18b20(unsigned char data) {unsigned char i ;GPIO_DQ_Out_Mode() ;for(i=0 ;i<8 ;i++){if(data&0x01) //低位在前{//写1DQ_Write_0() ; //写时间空隙总是从总线的低电平开始Delay_Nus(8) ; //15us内拉高DQ_Write_1() ;Delay_Nus(80) ; //整个写1时隙不低于60us}else{//写0DQ_Write_0() ;Delay_Nus(110) ; //保持在60us到120us之间DQ_Write_1() ;Delay_Nus(5) ;}data >>= 1 ;}}/******************************************函数名称:Read_OneByte_FromDS18b20 功能:从DS18b20读一个字节参数:无返回值 :读出的数据*******************************************/unsigned char Read_OneByte_FromDS18b20(void){unsigned char i ,data = 0 ;for(i=0 ;i<8 ;i++){GPIO_DQ_Out_Mode() ;data >>= 1 ;DQ_Write_0() ;Delay_Nus(2) ;GPIO_DQ_Input_Mode() ;Delay_Nus(1) ;if(DQ_ReadBit()){data |= 0x80 ;}Delay_Nus(70) ; //等待这一位数据完成传输}GPIO_DQ_Out_Mode() ;return data ;}/****************************************** 函数名称:Read_Temperature功能:读取温度信息参数:*sign - 保存符号(零上或零下)*integer - 保存整数部分*decimal - 保存小数部分返回值 :无*******************************************/ voidRead_Temperature(unsigned char *sign ,unsigned char *interger ,unsigned int *decimal) {unsigned char a=0;unsigned char b=0;//volatile unsigned char c=0;//volatile unsigned char d=0;//volatile unsigned char e=0;unsigned int tmp ;DS18B20_Init();Write_OneByte_ToDS18b20(ROM_Read_Cmd);DS18B20_Init();Write_OneByte_ToDS18b20(ROM_Skip_Cmd);//跳过读序列号操作Write_OneByte_ToDS18b20(Convert_T); //启动温度转换Delay_Nms(780);//等待DS18b20转换完成DS18B20_Init();Write_OneByte_ToDS18b20(ROM_Skip_Cmd);Write_OneByte_ToDS18b20(Read_Scratchpad); //读取寄存器内容(可以从寄存器0读到寄存器8)a= Read_OneByte_FromDS18b20(); //温度低8位b= Read_OneByte_FromDS18b20(); //温度高8位//c= Read_OneByte_FromDS18B20(); //TH//d= Read_OneByte_FromDS18B20(); //TL//e= Read_OneByte_FromDS18B20(); //Configuration RegisterTx_ResetPulse(); //中断数据读取tmp = (b<<8) | a ;if(b & 0xF0){*sign = 1 ; //符号部分tmp = ~tmp+1 ;}else{sign = 0 ;}*interger = (tmp>>4) & 0x00FF; //整数部分*decimal = (tmp & 0x000F) * 625 ; //小数部分}/****************************************** 函数名称:Write_EEPROM 功能:写配置参数参数:Th - 报警温度上限Tl - 报警温度下限Register_Con - 控制寄存器的值返回值 :读出的数据*******************************************/ voidWrite_EEPROM(unsigned char Th,unsigned char Tl,unsigned charRegister_Con ){DS18B20_Init();Write_OneByte_ToDS18b20(ROM_Skip_Cmd);Write_OneByte_ToDS18b20(Write_Scratchpad);Write_OneByte_ToDS18b20(Th);//Th=7FWrite_OneByte_ToDS18b20(Tl);//Tl=FF 最高位符号位Write_OneByte_ToDS18b20(Register_Con);//12位模式Delay_Nms(700);DS18B20_Init();Write_OneByte_ToDS18b20(ROM_Skip_Cmd);Write_OneByte_ToDS18b20(Copy_Scratchpad);//将寄存器的配置值写入EEPROMDelay_Nms(300);}/****************************************** 函数名称:DS18B20_Init 功能:初始化DS18b20参数:无返回值 :无*******************************************/ void DS18B20_Init(void) {Tx_ResetPulse();Rx_PresencePulse();}//=================================================================////========================要用到的其他文件============================////===========================Systick_Delay.h==========================// /*--------------------------------------------------利用SysTick进行精确定时---------------------------------------------------*/ #ifndef__SYSTICKDELAY_H#define __SYSTICKDELAY_H#include "stm32f10x_lib.h"extern void Delay_Nms(u16 Nms);extern void Delay_Nus(u32 Nus);#endif /*SYSTICKDELAY_H*///=================================================================////=========================Systick_Delay.c============================//#include "stm32f10x_lib.h"#include "SysTick_Delay.h"//延时Nms//注意Nms的范围//Nms<=0xffffff*8/SYSCLK//对72M条件下,Nms<=1864void Delay_Nms(u16 Nms){SysTick->LOAD=(u32)Nms*9000; //给重装载寄存器赋值,9000时,将产生1ms的时基SysTick->CTRL|=0x01; //开始倒数while(!(SysTick->CTRL&(1<<16))); //等待时间到达SysTick->CTRL=0X00000000; //关闭计数器SysTick->VAL=0X00000000; //清空计数器}//延时usvoid Delay_Nus(u32 Nus){SysTick->LOAD=Nus*9; //时间加载SysTick->CTRL|=0x01; //开始倒数while(!(SysTick->CTRL&(1<<16)));//等待时间到达SysTick->CTRL=0X00000000; //关闭计数器SysTick->VAL=0X00000000; //清空计数器}//=================================================================/ //* 写得一般,希望大家能给点建议! */。
STM32制作DS18B20-温度传感器
折腾了一晚上,才把DS18B20的驱动移植到STM32上来。
以前在51上使用过单个和多个连接的DS18B20,有现成的程序了,以为很快就能弄好,结果还是被卡住了,下面说下几个关键点吧:首先是延时的问题,STM32上若用软件延时的话不太好算时间,所以要么用定时器要么用SysTick这个定时器来完成延时的计算。
相比之下用SysTick来的简单方便点。
接着是STM32 IO脚的配置问题,因为51是双向的IO,所以作为输入输出都比较方便。
STM32的IO是准双向的IO,网上查了下资料,说将STM32的IO配置成开漏输出,然后外接上拉即可实现双向IO。
于是我也按规定做了,但调了老半天都不成功,是因为DS18B20没有响应的信号。
在烦躁之际只有试下将接DQ的IO分别拉低和拉高看能不能读入正确的信号。
结果果然是读入数据不对,原来我将IO配成开漏输出后相当然的以为读数据是用GPIO_ReadOutputDataBit(),这正是问题所在,后来将读入的函数改为GPIO_ReadInputDataBit()就OK了。
现在温度是现实出来了,但跟我家里那台德胜收音机上显示的温度相差2度,都不知道是哪个准了,改天再找个温度计验证下。
下面引用一段DS18B20的时序描述,写的很详细:DS18B20的控制流程根据DS18B20的通信协议,DS18B20只能作为从机,而单片机系统作为主机,单片机控制DS18B20完成一次温度转换必须经过3个步骤:复位、发送ROM指令、发送RAM指令。
每次对DS18B20的操作都要进行以上三个步骤。
复位过程为:单片机将数据线拉低至少480uS,然后释放数据线,等待15-60uS让DS18B20接收信号,DS18B20接收到信号后,会把数据线拉低60-240uS,主机检测到数据线被拉低后标识复位成功;发送ROM指令:ROM指令表示主机对系统上所接的全部DS18B20进行寻址,以确定对那一个DS18B20进行操作,或者是读取某个DS18B20的ROM序列号。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "delay.h"
#define DQ_READ GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)
//功能描述:DS18B20初始化
void DS18B20_Init(void)
{
temp =(~temp+1)&0xffff;
}
else
temp = temp*625/1000; //温度值
void DQ_Mode(u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
if(mode==DOUT)
{
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; // 配置IO为开漏输出模式
ack = DQ_READ;
Delay(250);
return ack;
}
// 函数名称:DS18B20_Write
//功能描述:向DS18B20写入一个字节
void DS18B20_Write (u8 dat )
return (u16)temp;
}
int MAIN(viod)
{
DS18B20_Init();
while(1)
{
Temperature4=Get_DS18B20_Tmp()/10;
}
}
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
// 配置IO口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
Delay(7);
if(DQ_READ)
{
dat |= 0x80;
}
Delay(60);
}
return dat;
DS18B20_Write(0x44);
if(DS18B20_Reset()) return 0;
DS18B20_Write(0xCC);
DS18B20_Write(0xBE);
a[0] = DS18B20_Read();
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //配置IO口的输出速率是50M
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_WriteBit(GPIOC,GPIO_Pin_5,Bit_RESET);
a[1]= DS18B20_Read();
temp = (a[1]<<8)|a[0];
if(temp&0xF000)
{
temp=(~temp+1)&0xffff;
temp = temp*625/1000;
}
}
//功能描述:DS18B20 初始化序列
u8 DS18B20_Reset(void)
{
u8 ack = 1;
DQ_Mode(DOUT);
Delay(480);
DQ_Mode(DIN);
Delay(60);
}
//功能描述:读DS18B20 的温度
u16 Get_DS18B20_Tmp(void)
{
u8 a[2];
u32 temp;
if(DS18B20_Reset()) return 0;
DS18B20_Write(0xCC);
DQ_Mode(DIN);
dat >>= 1;
Delay(1);
}
}
//功能描述:读DS18B20 的数据
u8 DS18B20_Read (void)
{
u8 i = 0;
if(dat&0x01)
DQ_Mode(DIN);
else DQ_Mode(DOUT);
Delay(40);
{ Leabharlann u8 i = 0; for(i=0;i<8;i++)
{
DQ_Mode(DOUT);
Delay(1);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //配置IO为浮空输入模式
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
//函数名称:DQ_Mode
// 功能描述:DS18B20 IO控制脚
}
else
{
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC,&GPIO_InitStructure);
u8 dat = 0;
for(i=0;i<8;i++)
{
DQ_Mode(DOUT);
Delay(1);
DQ_Mode(DIN);
dat >>= 1;