#include "temperature.H" #include #include UnSwSample UnSwSample_1 = {0}; #define Measure_Period 11000 //////////////////////////////////////////////////////////////////// // 计算字节序列的校验和 unsigned char CRC8MY(unsigned char *serial, unsigned char length) { unsigned char result = 0x00; unsigned char pDataBuf; unsigned char i; while (length--) { pDataBuf = *serial++; for (i = 0; i < 8; i++) { if ((result ^ pDataBuf) & 0x01) { result ^= 0x18; result >>= 1; result |= 0x80; } else { result >>= 1; } pDataBuf >>= 1; } } return result; //返回校验和 } //非精确延时10*X us,固定误差10us //@12.000MHz 12T模式 void Delay_us(uword x) { for (; x > 0; x--) { _nop_(); _nop_(); } } //////////////////////////////////////////////////////////////////// // 主机发送 复位脉冲( 大于 480 us 低电平) ,并检查 存在 脉冲 unsigned char ow_resetpresence(void) { unsigned char presence; int count=0; SFR_PAGE(_pp0, noSST); // switch to page 0 P3_DIR = P3_DIR | 0x20; // load direction register P3.5切换为输出 DQ = 0; // 主机拉低 DQ 总线 Delay_us(240); // 拉低 DQ 总线 持续 480us DQ = 1; // 主机释放总线,由上拉电阻拉高 SFR_PAGE(_pp0, noSST); // switch to page 0 P3_DIR = P3_DIR & 0xDF;// load direction register Delay_us(40); // 等待 80us 后检查 presence presence = DQ; // 检查存在 脉冲 while( presence && (count< 17) ) { Delay_us(2); presence = DQ; count++; } Delay_us(200); // 时序末尾 等待 return(presence); } // presence =0 时, M6 01 存在 , presence =1 时, M601 不存在 //////////////////////////////////////////////////////////////////// //// READ_BIT – 从 M601 读取 一位数 unsigned char read_bit(void) { unsigned char res; SFR_PAGE(_pp0, noSST); // switch to page 0 P3_DIR = P3_DIR | 0x20; // load direction register 切换为输出状态 DQ = 0; // 主机拉低 DQ 总线 Delay_us(2); // 拉低 DQ 总线 持续 3us DQ = 1; // 主机释放 DQ 总线,由上拉电阻拉高 Delay_us(5); // 等待 10us 确保总线上数据稳定 SFR_PAGE(_pp0, noSST); // switch to page 0 P3_DIR = P3_DIR & 0xDF;// load direction register res = DQ; Delay_us(28); // 时序末尾 等待 return(res); // 返回读取 数值 } //////////////////////////////////////////////////////////////////// //// WRITE_BIT – 主机 写一位数据 到 M601 void write_bit(char bitval) { SFR_PAGE(_pp0, noSST); // switch to page 0 P3_DIR = P3_DIR | 0x20; // load direction register 切换为输出状态 DQ = 0; // 主机拉低 DQ 总线 Delay_us(2); // 拉低 DQ 总线 持续 5us if(bitval == 1) DQ =1; // 如果 写 1,此时拉高 DQ 总线 Delay_us(25); // 如果 写 0,则持续拉低 DQ 总线 60 us DQ = 1; // 释放 DQ 总线 Delay_us(5); // (写 0)恢复 时间 10us } ///////////////////////////////////////////////////////////////////// //// READ_BYTE - 从 M601 读取 一字节 数据 unsigned char read_byte(void) { unsigned char i, j; unsigned char value = 0; for (i = 0;i < 8;i++) { j = read_bit(); value = (value) | (j<> i; temp &= 0x01; // 低位 先行 write_bit(temp); } } //读取测温数据 void Single_point_Read_Temperature(void) { unsigned char get[9]; unsigned char tpmsb, tplsb, i; int signedInt_f_tem; short s_tem; short wtem; float f_tem; UnSwSample_1.bit_data.reserve = 0; if (ow_resetpresence()) { // 建议保留该判断!可以有效排查硬件连接是否出现问题! // printf("\nPresence Error\n"); UnSwSample_1.bit_data.reserve = 0x01; } write_byte(0xCC); //Skip ROM ,或使用 匹配 ROM 序列号 (见后文) write_byte(0x44); // 转换 温度 Delay_us(Measure_Period / 2); // 温度 转换时间, 应根据配置寄存器的重复性设置选择 4ms ,5.5ms 或 10.5m if (ow_resetpresence()) { // 建议保留该判断!可以有效排查硬件连接是否出现问题! // printf("\nPresence Error\n"); UnSwSample_1.bit_data.reserve = 0x02; } write_byte(0xCC); // Skip ROM ,或使用 匹配 ROM 序列号 (见后文) write_byte(0xBE); // 读取 Scratch Pad 中数值 for (i = 0; i < 9; i++) get[i]=read_byte(); if(get[8] != CRC8MY(get,8)) { // 建议保留该判断!可以有效排查软件时序是否出现问题! // printf("\nCRC Error\n"); UnSwSample_1.bit_data.reserve = 0x03; } else { tpmsb = get[1]; // 温度高字节 tplsb = get[0]; // 温度 低字节 wtem= (tpmsb << 8 | tplsb); s_tem =(short) wtem; f_tem=(s_tem * 1.0)/256 + 40.0; // 将浮点数转换为有符号整型 signedInt_f_tem = (int)f_tem; // 温度 有符号整型转成无符号整形 UnSwSample_1.bit_data.temperature = (unsigned int)signedInt_f_tem; // printf( "\nTemp= %f degrees C\n", f_tem); // 打印摄氏温度 } }