📄 18b20.c
字号:
#include <msp430x14x.h>
unsigned char err_flag = 0;
unsigned char result[9];
float temperature[6] = {0.0};
const unsigned char ROMserial[6][8]
void Init_CLK(void);
void Reset(void);
void Write_command(unsigned char command);
unsigned int Read_data(void);
unsigned char CRC8(unsigned char *ptr, unsigned char len);
float Temperature(void);
void Delay_5dd_5us(unsigned int dd);
void main(void)
{
unsigned int i;
unsigned int j;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
Init_CLK(); // Set CLK
P3OUT |= BIT4; //
P3DIR |= BIT4;
Delay_5dd_5us(60000);
Reset(); // Reset DS18B20
Write_command(0xCC); // Skip ROM
Write_command(0x44); // Start conversion
for (i=0; i<3; i++) // Delay 0.9sec for convert
{
Delay_5dd_5us(60000);
}
for (i=0; i<6; i++)
{
Reset(); // Reset DS18B20
Write_command(0x55); // Match ROM
for (j=0; j<8; j++)
{
Write_command(ROMserial[i][j]);
}
do
{
Write_command(0xBE); // Read Scrathpad, 9 byte
for (j=0; j<9; j++)
{
result[j] = Read_data();
}
}
while(result[8] != CRC8(result, 8));
temperature[i] = Temperature(); // if CRC error, reread scratchp
}
for (; ;);
}
// 初始化时钟
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0x00; // XT2振荡器开启, LFXT1选择低频模式
do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 等待时钟源转换完成
BCSCTL1 &= ~(XT2OFF + XTS); // 启动XT2, ACLK为LFTX1
BCSCTL2 |= SELM1 + SELS + DIVM1+DIVM0; // MCLK的时钟源为XT2CLK, SMCLK的时钟源为XT2CLK
}
// 初始化
void Reset(void)
{
// 初始化的时序是计算机先发出 480-960us 的复位脉冲
P3OUT &= ~BIT4;
P3DIR |= BIT4;
Delay_5dd_5us(120);
// 释放总线, 进入接收状态
P3DIR &= ~BIT4;
// 在15-60us后一个或多个单总线器件发出应答脉冲
{
for (; ;);
}
}
// 读数据
unsigned int Read_data(void)
{
unsigned int data = 0;
unsigned int i;
// 主机总线t0(0)时刻从高拉至低电平时总线, 只须保持低电平ls,
// 之后在t1时刻(约5us)将总线拉高, 产生读时间隙, 读时间隙在t1时刻后t2(15us)时刻前有效,
// t2距t0为15us, 也就是说t2(15us)时刻前主机必须完成读位, 并在t0后的60us-120us内释放总线.
for(i=0; i<8; i++)
{
P3OUT &= ~BIT4;
P3DIR |= BIT4;
_NOP();
_NOP();
P3DIR &= ~BIT4; // 主机释放总线, 在t0后的15us内读取数据
// DS18B20释放总线后, 上拉电阻自动拉高电平
_NOP();
_NOP();
data = data >> 1; // 先读取低字节低位, 故向右移位
if (P3IN & BIT4)
{
data |= 0x80;
}
Delay_5dd_5us(13);
}
return data;
}
unsigned char CRC8(unsigned char *ptr, unsigned char len)
{
unsigned char i; // ptr: data ptr, len: data len.
unsigned char crc = 0;
unsigned char cbyte = 0x01;
while(len--) // X8 + X5 + X4 + 1
{
for(i=0; i<8; i++)
{
if ((*ptr) & cbyte)
{
crc = crc ^ 0x01;
}
if ((crc & 0x01) == 1)
{
crc = crc >> 1;
crc = crc ^ 0x0C;
crc |= BIT7;
}
else
{
crc = crc >> 1;
}
cbyte <<= 1;
}
ptr++;
cbyte = 0x01;
}
return crc;
}
float Temperature(void)
{
float temperature = 0.0;
float temp_dot = 0.0;
unsigned int i;
for (i=0; i<4; i++)
{
if (result[0] & 0x01)
{
switch(i)
{
case 0: temp_dot += 0.0625;
break;
case 1: temp_dot += 0.125;
break;
case 2: temp_dot += 0.25;
break;
case 3: temp_dot += 0.5;
break;
}
}
result[0] >>= 1;
}
temperature = (float)(result[1] * 16 + result[0]) + temp_dot;
return temperature;
}
void Delay_5dd_5us(unsigned int dd) // Delay (5+5i) us
{
while(dd--);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -