⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 18b20.c

📁 我自己写的一个msp430和温度传感器ds18b20的C程序
💻 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 + -