void main() { LED = 1; while(1) { DS18B20_Reset(); //设备复位 DS18B20_WriteByte(0xCC); //跳过ROM命令 DS18B20_WriteByte(0x44); //开始转换命令 while (!DQ); //等待转换完成 DS18B20_Reset(); //设备复位 DS18B20_WriteByte(0xCC); //跳过ROM命令 DS18B20_WriteByte(0xBE); //读暂存存储器命令 a = DS18B20_ReadByte(); //读温度低字节 b = DS18B20_ReadByte(); //读温度高字节 t = b; t <<= 8; t = t | a; tt = t * 0.0625; t = tt * 10 + 0.5; if((t % 100) > 32) LED = 0; else LED = 1; PrintString("温度: "); //提示用户码 //Tx1Send('0' + t / 1000); //用户码高字节的高半字节 Tx1Send('0' + (t / 100) % 10); //用户码高字节的低半字节 Tx1Send('0' + (t / 10) % 10); //用户码低字节的高半字节 Tx1Send('.'); Tx1Send('0' + t % 10); //用户码低字节的低半字节 PrintString("℃"); //提示用户码 Tx1Send(10); } }
/* ********************************************************************************************************* * 函 数 名: DS18B20_ReadTempByID * 功能说明: 读指定ID的温度寄存器的值(原始数据) * 形 参: 无 * 返 回 值: 温度寄存器数据 (除以16得到 1摄氏度单位, 也就是小数点前面的数字) ********************************************************************************************************* */ int16_t DS18B20_ReadTempByID(uint8_t *_id) { uint8_t temp1, temp2; uint8_t i; DS18B20_Reset(); /* 总线复位 */ DS18B20_WriteByte(0x55); /* 发命令 */ for (i = 0; i < 8; i++) { DS18B20_WriteByte(_id[i]); } DS18B20_WriteByte(0x44); /* 发转换命令 */ DS18B20_Reset(); /* 总线复位 */ DS18B20_WriteByte(0x55); /* 发命令 */ for (i = 0; i < 8; i++) { DS18B20_WriteByte(_id[i]); } DS18B20_WriteByte(0xbe); temp1 = DS18B20_ReadByte(); /* 读温度值低字节 */ temp2 = DS18B20_ReadByte(); /* 读温度值高字节 */ return ((temp2 << 8) | temp1); /* 返回16位寄存器值 */ }
s16 DS18B20_ReadDesignateTemper( u8 pID[8]) { u8 th, tl; s16 data; if(DS18B20_Reset() == FALSE) { return 0xffff; //返回错误 } DS18B20_WriteData(0xcc); //跳过读序列号 DS18B20_WriteData(0x44); //启动温度转换 DS18B20_Reset(); DS18B20_WriteData(0xcc); //跳过读序列号 #if 0 DS18B20_WriteData(0x55); //发送序列号匹配命令 for(data = 0;data < 8;data ++) //发送8byte的序列号 { DS18B20_WriteData(pID[data]); } Delay_US(10); #endif DS18B20_WriteData(0xbe); //读取温度 tl = DS18B20_ReadData(); //读取低八位 th = DS18B20_ReadData(); //读取高八位 data = th; data <<= 8; data |= tl; data *= 6.25; //温度值扩大100倍,精确到2位小数 return data; }
// 读取DS18B20温度,放大100倍。id为温度传感器编号(目前可以支持2个,主缸和底缸各一个) BaseType_t GetTemperature(uint8_t id, int16_t* pData) { uint8_t i; uint16_t temp; int32_t temperature; uint8_t crc; assert_param(pData); if ( !(DS18B20_Reset(id)) ) { return pdFALSE; } DS18B20_WriteByte(id, DS18B20_COMMAND_SKIPROM); DS18B20_WriteByte(id, DS18B20_COMMAND_CONVERTT); // todo:需要更换为FreeRTOS的延迟函数,以便可以进行任务切换 for (i = 0; i < 9; ++i) { Delay_us(50 * 1000); Delay_us(50 * 1000); } if ( !(DS18B20_Reset(id)) ) { return pdFALSE; } DS18B20_WriteByte(id, DS18B20_COMMAND_SKIPROM); DS18B20_WriteByte(id, DS18B20_COMMAND_READSCRATCHPAD); for (i = 0; i < sizeof(s_Scratchpad) / sizeof(s_Scratchpad[0]); ++i) { s_Scratchpad[i] = DS18B20_ReadByte(id); } // CRC校验 crc = crc8(s_Scratchpad, 9); if (crc) { return pdFALSE; } temp = s_Scratchpad[1] << 8; temp += s_Scratchpad[0]; // 转换为摄氏度,并放大100倍 temperature = (int16_t)temp; // 先进行符号位扩展 temperature = temperature * 625 / 100; // todo:看看是否需要进行四舍五入的处理? *pData = (int16_t)temperature; return pdTRUE; }
void main() { DS18B20_Reset(); //设备复位 DS18B20_WriteByte(0xCC); //跳过ROM命令 DS18B20_WriteByte(0x44); //开始转换命令 while (!DQ); //等待转换完成 DS18B20_Reset(); //设备复位 DS18B20_WriteByte(0xCC); //跳过ROM命令 DS18B20_WriteByte(0xBE); //读暂存存储器命令 TPL = DS18B20_ReadByte(); //读温度低字节 TPH = DS18B20_ReadByte(); //读温度高字节 while (1); }
/* ********************************************************************************************************* * 函 数 名: DS18B20_ReadID * 功能说明: 读DS18B20的ROM ID, 总线上必须只有1个芯片 * 形 参: _id 存储ID * 返 回 值: 0 表示失败, 1表示检测到正确ID ********************************************************************************************************* */ uint8_t DS18B20_ReadID(uint8_t *_id) { uint8_t i; /* 总线复位 */ if (DS18B20_Reset() == 0) { return 0; } DS18B20_WriteByte(0x33); /* 发命令 */ for (i = 0; i < 8; i++) { _id[i] = DS18B20_ReadByte(); } DS18B20_Reset(); /* 总线复位 */ return 1; }
/* ********************************************************************************************************* * 函 数 名: DS18B20_ReadTempReg * 功能说明: 读温度寄存器的值(原始数据) * 形 参: 无 * 返 回 值: 温度寄存器数据 (除以16得到 1摄氏度单位, 也就是小数点前面的数字) ********************************************************************************************************* */ int16_t DS18B20_ReadTempReg(void) { uint8_t temp1, temp2; /* 总线复位 */ if (DS18B20_Reset() == 0) { return 0; } DS18B20_WriteByte(0xcc); /* 发命令 */ DS18B20_WriteByte(0x44); /* 发转换命令 */ DS18B20_Reset(); /* 总线复位 */ DS18B20_WriteByte(0xcc); /* 发命令 */ DS18B20_WriteByte(0xbe); temp1 = DS18B20_ReadByte(); /* 读温度值低字节 */ temp2 = DS18B20_ReadByte(); /* 读温度值高字节 */ return ((temp2 << 8) | temp1); /* 返回16位寄存器值 */ }
s16 DS18B20_ReadTemper(void) { u8 th, tl; s16 data; if(DS18B20_Reset() == FALSE) { return 0xffff; //返回错误 } DS18B20_WriteData(0xcc); //跳过读序列号 DS18B20_WriteData(0x44); //启动温度转换 DS18B20_Reset(); DS18B20_WriteData(0xcc); //跳过读序列号 DS18B20_WriteData(0xbe); //读取温度 tl = DS18B20_ReadData(); //读取低八位 th = DS18B20_ReadData(); //读取高八位 data = th; data <<= 8; data |= tl; data *= 6.25; //温度值扩大100倍,精确到2位小数 return data; }
BaseType_t InitDS18B20() { GPIO_InitTypeDef GPIO_InitStructure; uint8_t i; // 初始化延时us用的定时器TIM5 initTIM5(); // 初始化所有的DS18B20 for (i = 0; i < (sizeof(s_DS18B20s) / sizeof(s_DS18B20s[0])); ++i) { // 初始化DS18B20使用的管脚 RCC_APB2PeriphClockCmd(s_DS18B20s[i].portclk, ENABLE); /*!< Configure DS18B20 DQ */ GPIO_InitStructure.GPIO_Pin = s_DS18B20s[i].pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(s_DS18B20s[i].port, &GPIO_InitStructure); // Reset DS18B20 if (DS18B20_Reset(i) != pdTRUE) { return pdFALSE; } // Init DS18B20 DS18B20_WriteByte(i, DS18B20_COMMAND_SKIPROM); DS18B20_WriteByte(i, DS18B20_COMMAND_WRITESCRATCHPAD); DS18B20_WriteByte(i, 0x64); DS18B20_WriteByte(i, 0x8A); DS18B20_WriteByte(i, 0x7F); // 12bit精度 } return pdTRUE; }
u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num) { unsigned char k,l,chongtuwei,m,n; unsigned char zhan[(MAXNUM-1)]; unsigned char ss[64]; unsigned char s=0; u8 num = 0; l=0; do { DS18B20_Reset(); DS18B20_WriteData(0xf0); for(m=0;m<8;m++) { s=0; for(n=0;n<8;n++) { k=DS18B20_Read2Bit();//读两位数据 k=k&0x03; s>>=1; if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应 { DS18B20_WriteBit (0); ss[(m*8+n)]=0; } else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应 { s=s|0x80; DS18B20_WriteBit (1); ss[(m*8+n)]=1; } else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位 { //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1 chongtuwei=m*8+n+1; if(chongtuwei>zhan[l]) { DS18B20_WriteBit (0); ss[(m*8+n)]=0; zhan[++l]=chongtuwei; } else if(chongtuwei<zhan[l]) { s=s|((ss[(m*8+n)]&0x01)<<7); DS18B20_WriteBit (ss[(m*8+n)]); } else if(chongtuwei==zhan[l]) { s=s|0x80; DS18B20_WriteBit (1); ss[(m*8+n)]=1; l=l-1; } } else { return num; //搜索完成,//返回搜索到的个数 } } pID[num][m]=s; } num=num+1; } while(zhan[l]!=0&&(num<MAXNUM)); return num; //返回搜索到的个数 }