190 lines
5.7 KiB
C
190 lines
5.7 KiB
C
#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); // 打印摄氏温度
|
||
}
|
||
}
|
||
|
||
|