Files
RC/temperature.C
2025-10-21 20:34:06 +08:00

190 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "temperature.H"
#include <stdio.h>
#include <math.h>
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); // 每次读进 1 位(低位 先行 ), 然后 左移
}
return(value);
}
/////////////////////////////////////////////////////////////////////
//// WRITE_BYTE - 主机 写一字节数据 到 M601
void write_byte(char val)
{
unsigned char i;
unsigned char temp;
for (i = 0; i < 8; i++) { // 写字节 ,每次 一位
temp = val >> 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); // 打印摄氏温度
}
}