DS18B20读取温度,序号匹配
时间:2019-07-04
本文章向大家介绍DS18B20读取温度,序号匹配,主要包括DS18B20读取温度,序号匹配使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1 /* DS18B20时钟端口、引脚定义 */ 2 #define DS18B20 GPIOC 3 #define DS18B20_Onboard (GPIO_Pin_15) 4 #define DS18B20_PORT_RCC RCC_APB2Periph_GPIOC 5 #define ds_count 20 6 7 ///IO操作函数 8 #define DS18B20_DQ_OUT PCout(15) 9 #define DS18B20_DQ_IN PCin(15) 10 11 #define dsmax 6 //最多允许温度传感器的数量
配置DS18B20初始化函数,输入配置,输出配置,参考DS18B20数据手册:
1 void DS18B20_Reset(void) 2 { 3 DS18B20_IO_OUT(); //SET PC15 OUTPUT 4 DS18B20_DQ_OUT=0; //拉低DQ 5 delay_us(750); //拉低750us 6 DS18B20_DQ_OUT=1; //DQ=1 7 delay_us(35); //35US 8 } 9 10 u8 DS18B20_Check(void) 11 { 12 u8 retry=0; 13 DS18B20_IO_IN();//SET PC15 INPUT 14 while(DS18B20_DQ_IN&&retry<200) 15 { 16 retry++; 17 delay_us(1); 18 }; 19 if(retry>=200) return 1; 20 else retry = 0; 21 while (!DS18B20_DQ_IN && retry <240) 22 { 23 retry++; 24 delay_us(1); 25 }; 26 if(retry>=240) return 1; 27 return 0; 28 } 29 30 u8 DS18B20_Init(void) 31 { 32 GPIO_InitTypeDef GPIO_InitStructure; 33 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE ); 34 PWR_BackupAccessCmd( ENABLE );/* 允许修改RTC和后备寄存器*/ 35 RCC_LSEConfig( RCC_LSE_OFF ); /* 关闭外部低速时钟,PC14+PC15可以用作普通IO*/ 36 BKP_TamperPinCmd(DISABLE); /* 关闭入侵检测功能,PC13可以用作普通IO*/ 37 38 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; 39 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 40 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 41 GPIO_Init(GPIOC, &GPIO_InitStructure); 42 43 PWR_BackupAccessCmd(DISABLE);/* 禁止修改RTC和后备寄存器*/ 44 //BKP_ITConfig(DISABLE); /* 禁止TAMPER 中断*/ 45 46 DS18B20_Reset(); 47 return DS18B20_Check(); 48 } 49 50 /******************************************************************************* 51 * 函 数 名 : DS18B20_IO_IN 52 * 函数功能 : DS18B20_IO输入输出配置 53 * 输 入 : 无 54 * 输 出 : 无 55 *******************************************************************************/ 56 void DS18B20_IO_IN(void) 57 { 58 GPIO_InitTypeDef GPIO_InitStructure; 59 PWR_BackupAccessCmd( ENABLE );/* 允许修改RTC和后备寄存器*/ 60 RCC_LSEConfig( RCC_LSE_OFF ); /* 关闭外部低速时钟,PC14+PC15可以用作普通IO*/ 61 BKP_TamperPinCmd(DISABLE); /* 关闭入侵检测功能,PC13可以用作普通IO*/ 62 63 GPIO_InitStructure.GPIO_Pin=DS18B20_Onboard; 64 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; 65 GPIO_Init(DS18B20,&GPIO_InitStructure); 66 67 PWR_BackupAccessCmd(DISABLE);/* 禁止修改RTC和后备寄存器*/ 68 } 69 70 void DS18B20_IO_OUT(void) 71 { 72 GPIO_InitTypeDef GPIO_InitStructure; 73 PWR_BackupAccessCmd( ENABLE );/* 允许修改RTC和后备寄存器*/ 74 RCC_LSEConfig( RCC_LSE_OFF ); /* 关闭外部低速时钟,PC14+PC15可以用作普通IO*/ 75 BKP_TamperPinCmd(DISABLE); /* 关闭入侵检测功能,PC13可以用作普通IO*/ 76 77 GPIO_InitStructure.GPIO_Pin=DS18B20_Onboard; 78 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz; 79 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 80 GPIO_Init(DS18B20,&GPIO_InitStructure); 81 82 PWR_BackupAccessCmd(DISABLE);/* 禁止修改RTC和后备寄存器*/ 83 }
对DS18B20,按位、按字节读取和写数据:
1 u8 DS18B20_Read_Bit(void) // read one bit 2 { 3 u8 data; 4 DS18B20_IO_OUT();//SET PC15 OUTPUT 5 DS18B20_DQ_OUT=0; 6 delay_us(2); 7 DS18B20_DQ_OUT=1; 8 DS18B20_IO_IN();//SET PC15 INPUT 9 delay_us(12); 10 if(DS18B20_DQ_IN)data=1; 11 else data=0; 12 delay_us(50); 13 return data; 14 } 15 16 u8 DS18B20_Read_Byte(void) // read one byte 17 { 18 u8 i,j,dat; 19 dat=0; 20 for (i=1; i<=8; i++) 21 { 22 j=DS18B20_Read_Bit(); 23 dat=(j<<7)|(dat>>1); 24 } 25 return dat; 26 } 27 28 u8 DS18B20_Read_2Bit(void) //read 2 bits 29 { 30 u8 i,dat; 31 dat=0; 32 for(i = 0;i < 2;i ++) 33 { 34 dat <<= 1; 35 if(DS18B20_Read_Bit()) 36 { 37 dat = dat|1; 38 } 39 } 40 return dat; 41 } 42 43 void DS18B20_Write_Bit(u8 dat) //write one bit 44 { 45 u8 testb; 46 DS18B20_IO_OUT();//SET PG11 OUTPUT; 47 testb=dat&0x01; 48 if (testb) 49 { 50 DS18B20_DQ_OUT=0;// Write 1 51 delay_us(2); 52 DS18B20_DQ_OUT=1; 53 delay_us(60); 54 } 55 else 56 { 57 DS18B20_DQ_OUT=0;// Write 0 58 delay_us(60); 59 DS18B20_DQ_OUT=1; 60 delay_us(2); 61 } 62 } 63 64 void DS18B20_Write_Byte(u8 dat) //write one byte 65 { 66 u8 j; 67 u8 testb; 68 DS18B20_IO_OUT();//SET PC15 OUTPUT; 69 for (j=1; j<=8; j++) 70 { 71 testb=dat&0x01; 72 dat=dat>>1; 73 if (testb) 74 { 75 DS18B20_DQ_OUT=0;// Write 1 76 delay_us(2); 77 DS18B20_DQ_OUT=1; 78 delay_us(60); 79 } 80 else 81 { 82 DS18B20_DQ_OUT=0;// Write 0 83 delay_us(60); 84 DS18B20_DQ_OUT=1; 85 delay_us(2); 86 } 87 } 88 }
不匹配序号读取温度:
1 u8 DS18B20_GetTemperature() 2 { 3 u16 temp; 4 u8 a,b; 5 u8 value; 6 7 DS18B20_Reset(); 8 DS18B20_Check(); 9 DS18B20_Write_Byte(0xcc);// skip rom 10 DS18B20_Write_Byte(0xbe);// 读存储器命令转换 11 12 a=DS18B20_Read_Byte(); // LSB 13 b=DS18B20_Read_Byte(); // MSB 14 15 temp=b; 16 temp=(temp<<8)+a; 17 18 if((temp&0xf800)==0xf800) 19 { 20 temp=(~temp)+1; 21 value=temp*0.0625 + 128; //如果小于0,则加128,负值范围:128~255 22 } 23 else 24 { 25 value=temp*0.0625; //正值的范围:0~127(ds18b20的测温范围:-55~125摄氏度) 26 } 27 return value; 28 }
读序号并匹配序号,读温度:
u8 dsnum = 0; //温度传感器的数量 u8 ds_ID[dsmax][8] = {0}; //ID u8 dstemp[dsmax] = {0}; //温度 /********************************************/ u8 DS18B20_SearchROM() //搜索18B20 { u8 n,i,j,temp,CTW,num; u8 rom[64]; u8 stack[dsmax]; u8 id=0; n = 0; num = 0; do { DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0xf0); for(i=0; i<dsmax; i++) //按字节 { for(j=0; j<8; j++) //按位 { temp = DS18B20_Read_2Bit(); temp &= 0x03; id >>=1; if(temp == 0x01) //这里先读的是0,后读的是1,表示有器件连接,并且它们这一位均是0 { DS18B20_Write_Bit(0); rom[(i*8+j)] = 0; } else if(temp ==0x02) { id |= 0x80; DS18B20_Write_Bit(1); rom[(i*8+j)] = 1; } else if(temp == 0x00) //有冲突位 { CTW = i*8+j+1; if(CTW > stack[n]) //冲突位大于栈顶,写0 { DS18B20_Write_Bit(0); rom[(i*8+j)] = 0; zhan[++n] = CTW; } else if(CTW < stack[n]) { id |= ((rom[(i*8+j)] & 0x01) << 7); DS18B20_Write_Bit(rom[(i*8+j)]); } else if(CTW == stack[n]) { id |= 0x80; DS18B20_Write_Bit(1); rom[(i*8+j)] = 1; n--; } } else { return num; } delay_us(5); } ds_ID[num][i] = id; //ds18B20的id64位 id = 0; } num++; } while((stack[n] != 0) && (num < dsmax)); dsnum = num; return num; } u8 DS18B20_GetDsTemperature(u8 dsID[8]) { u16 temp,n; u8 a,b; u8 value; DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0x44);// 启动温度转换 DS18B20_Reset(); DS18B20_Check(); DS18B20_Write_Byte(0x55); //发送匹配 for(n=0; n<8; n++) { DS18B20_Write_Byte(dsID[n]); } delay_us(10); DS18B20_Write_Byte(0xbe);// 读存储器命令转换 a=DS18B20_Read_Byte(); // LSB b=DS18B20_Read_Byte(); // MSB temp=b; temp=(temp<<8)+a; if((temp&0xf800)==0xf800) { temp=(~temp)+1; value=temp*0.0625 + 128; } else { value=temp*0.0625; } return value; }
注意点:精度,时延,求平均值时数据溢出
原文地址:https://www.cnblogs.com/qzwjer/p/11134376.html
- [快学Python3]List(列表)
- [快学Python3]Tuple(元组)
- HDU 1248 寒冰王座(完全背包裸题)
- [快学Python3]String(字符串)
- [快学Python3]XML解析处理 - Element Tree
- Educational Codeforces Round 21(A.暴力,B.前缀和,C.贪心)
- [快学Python3]JSON解析
- Codeforces 754A Lesha and array splitting(简单贪心)
- [快学Python3]日期和时间处理
- Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3)(A.B.C,3道暴力题,C可二分求解)
- [快学Python3]目录与文件操作
- Codeforces Round #411 (Div. 2)(A,B,C,D 四水题)
- [快学Python3]INI文件读写
- [快学Python3]迭代器和生成器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法