MSP430F149的DS18B20C语言程序
来源:互联网 发布:手机闪存测试软件 编辑:程序博客网 时间:2024/06/06 01:13
#include "msp430x14x.h" // Standard Equations
//-------------------------I/O口定义------------------------------------
#define DS_DIR P6DIR
#define DS_OUT P6OUT
#define DS_IN P6IN
#define DS18B20 BIT4
#define W18BUS_1 {DS_DIR |= DS18B20;DS_OUT |= DS18B20;_NOP();DS_DIR &= ~DS18B20;}
//DS18B20总线写"1"
#define W18BUS_0 {DS_DIR |= DS18B20;DS_OUT &= ~DS18B20;_NOP();}
//DS18B20总线写"0"
#define SF18BUS (DS_DIR &= ~DS18B20) //释放DS18B20总线
#define R18BUS (DS_IN & DS18B20)
#define FLAG_TEMP_RET 0x01 //DS18B20复位OK
#define FLAG_TEMP_OK 0x02 //DS18B20 传感器OK
#define FLAG_TEMP_OVER 0x04 //搜索DS18B20结束
#define WDT_CLR (WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + WDTIS0) //看门狗清零
//----------------------------------------------------------------------
void Delay(unsigned int x); //延时程序
void Temp(void);
//-----------------------全局变量定义------------------------------
unsigned char ID[5][8]; //ID[5][8]为检索到的地址
unsigned char TEMP_NUMBER; //温度传感器数量
unsigned int TEMP[5]; //温度值
float fT[5];
//-----------------------软件标志定义------------------------------
unsigned int FLAG; //软件标志
//FLAG.0--DS18B20复位OK FLAG.1--温度传感器OK FLAG.2--搜索温度结束
//****************************************************************************
//模块名:Init_DS18B20
//描述: 初试化DS18B20子程序。
//****************************************************************************
void Init_DS18B20(void)
{
DS_DIR = DS18B20;
DS_OUT = 0;
}
void main(void)
{
unsigned int iq0;
WDTCTL = WDTPW +WDTHOLD; //停看门狗
//---------------------------系统时钟定义---------------------
BCSCTL1&=~XT2OFF; //打开XT2振荡器
do
{
IFG1 &= ~OFIFG; // 清除振荡器失效标志
for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振
}
while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
BCSCTL2 =SELM_2+DIVS_0+SELS; //选择MCLK、SMCLK为XT2
Init_DS18B20();
_EINT();
while (1)
{
Temp();
for (iq0 = 5; iq0 != 0; iq0--)
{
fT[iq0-1] = 0.0625 * TEMP[iq0-1];
}
_NOP();
}
}
//****************************************************************************
//模块名:Rst_DS18B20
//描述: 复位温度传感器DS18B20子程序。
//****************************************************************************
void Rst_DS18B20(void)
{
unsigned int I;
FLAG |= FLAG_TEMP_RET; //预设ds18b20复位OK
W18BUS_0; //拉低总线
Delay(960); //延时480uS
SF18BUS; //释放总线
Delay(50); //延时15-60uS
I = 890;
while (/*(R18BUS) && */(I != 0)) I--; //循环条件:ds18b20总线不为“0”
//并且延时总时间不够4mS
if (I != 0)
{
_NOP();
while(!(R18BUS));
}
else
{
FLAG &= ~FLAG_TEMP_RET;
}
}
//****************************************************************************
//模块名:Read_BUS_bit
//描述: 从单总线读一位数据子程序。
//功能: DATA右移一位,从单总线读一位数据到DATA的最高位,
//****************************************************************************
unsigned char Read_BUS_bit (unsigned char DATA)
{
unsigned char I;
DATA >>= 1;
SF18BUS; //释放总线
I = 30;
while (I != 0) I--;
_DINT();
W18BUS_0; //拉低总线2uS
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
W18BUS_1; //拉高总线
I = 20;
while (I != 0) I--;
if (R18BUS != 0)
DATA |= 0X80;
_NOP();
_EINT();
I = 25; //延时45uS
while (I != 0) I--;
return (DATA);
}
//****************************************************************************
//模块名:Write_BUS_bit
//描述: 向单总线写一位数据子程序。
//功能: 把DATA的最低一位数据写到单总线上,DATA右移一位
//****************************************************************************
unsigned char Write_BUS_bit (unsigned char DATA)
{
unsigned char I;
_DINT();
W18BUS_1;
if (DATA&0X01)
{
DS_DIR |= DS18B20;
DS_OUT &= ~DS18B20;
_NOP();
_NOP();
DS_OUT |= DS18B20;
}
else
{
W18BUS_0;
}
_EINT();
I = 16; //延时15uS
while (I != 0) I--;
DATA >>= 1;
I = 80;
while (I != 0) I--;
W18BUS_1;
_NOP();
_NOP();
return (DATA);
}
//****************************************************************************
//模块名:Read_BUS_Byte
//描述: 从单总线读一个字节数据子程序。
//功能: 返回从单总线读出的一个字节数据,调用了Read_BUS_bit
//****************************************************************************
unsigned char Read_BUS_Byte (void)
{
unsigned char I;
unsigned char DATA;
for (I = 8;I != 0;I--)
{
DATA = Read_BUS_bit(DATA);
}
return (DATA);
}
//****************************************************************************
//模块名:Write_BUS_Byte
//描述: 向单总线写一个字节数据子程序。
//功能: 调用Write_BUS_bit,把DATA数据写到单总线上
//****************************************************************************
void Write_BUS_Byte (unsigned char DATA)
{
unsigned char I;
for (I = 8;I != 0;I--)
{
DATA = Write_BUS_bit(DATA);
}
}
//****************************************************************************
//模块名:Read_BUS_2bit
//描述: 从单总线读2位数据子程序。
//功能: 调用Read_BUS_bit,从单总线读2位数据到DATA高位,并返回DATA
//****************************************************************************
unsigned char Read_BUS_2bit (void)
{
unsigned char DATA;
DATA = 0;
DATA = Read_BUS_bit(DATA);
DATA = Read_BUS_bit(DATA);
return(DATA);
}
//****************************************************************************
//模块名:Right_Move_Temp
//描述: 循环右移子程序。
//****************************************************************************
void Right_Move_Temp(unsigned char *PA,unsigned char *PB)
{
unsigned char DATA,I;
DATA = 0;
if (*PA & 0X01) DATA = 0X80;
PB = PB+7;
if (*PB & 0X01) DATA |= 0X01;
for (I=0; I<7; I++)
{
*PA >>= 1;
*PB >>= 1;
if (*(PA+1) & 0X01) *PA |= 0X80;
else *PA &= 0X7F;
if (*(PB-1) & 0X01) *PB |= 0X80;
else *PB &= 0X7F;
PA++;
PB--;
}
*PA >>= 1;
*PB >>= 1;
if (DATA & 0X80) *PA |= 0X80;
else *PA &= 0X7F;
if (DATA & 0X01) *PB |= 0X80;
else *PB &= 0X7F;
}
//****************************************************************************
//模块名:CRC_Verify
//描述: CRC校验子程序。
//****************************************************************************
const unsigned char CRC_H[16] =
{0x00,0x9d,0x23,0xbe,0x46,0xdb,0x65,0xf8,0x8c,0x11,0xaf,0x32,0xca,0x57,0xe9,0x74};
const unsigned char CRC_L[16] =
{0x00,0x5e,0xbc,0xe2,0x61,0x3f,0xdd,0x83,0xc2,0x9c,0x7e,0x20,0xa3,0xfd,0x1f,0x41};
unsigned char CRC_Verify(unsigned char * buf,unsigned char length)
{
unsigned char crc = 0x00;
do
{
crc ^= *buf;
crc = CRC_H[crc >> 4] ^ CRC_L[crc & 0x0f];
buf++;
}
while(--length);
return(crc);
}
//****************************************************************************
//模块名:Search_ROM
//描述: 搜索ds18b20的地址子程序。
//****************************************************************************
void Search_ROM (void)
{
unsigned char A[8],B[8]; //A[8]为已知ID中最大的ID值,B[8]节点表
unsigned char POINT0,POINT; //POINT0指向上次检索的最后一个节点位置;
//POINT指向当前节点位置;
unsigned char I,J,K; //I,J为循环计数器;K为检索失败次数
unsigned char DATA,CRC;
unsigned char *PA,*PB;
PA = &A[0];
PB = &B[0];
J = 0xFF;
FLAG |= FLAG_TEMP_OK; //预设传感器正常
I = 5; //
while ((I != 0) && ~(FLAG & FLAG_TEMP_RET))
{
Rst_DS18B20(); //传感器复位,复位成功或5次复位失败跳出循环
I--;
}
if (FLAG && FLAG_TEMP_RET)
{ //复位成功,开始搜索ds18b20的地址
for (I = 0 ; I <8 ; I++)
{
A[I] = 0; //已知ID中最大的ID值"0"
B[I] = 0; //所有节点都未处理
}
POINT0 = 63;
POINT = 0XFF;
K = 0;
for (J = 0 ; (J<5 && K<5 && POINT != 0) ; J++)
{
Rst_DS18B20(); //传感器复位
Write_BUS_Byte (0XF0); //写搜索ID命令
POINT = 0;
FLAG &= ~FLAG_TEMP_OVER;
for (I = 0 ; ((I 64) && ~(FLAG & FLAG_TEMP_OVER)) ; I++)
{
Right_Move_Temp(PA,PB); //循环右移
DATA = Read_BUS_2bit(); //读ds18b20两位
switch (DATA &= 0XC0)
{
case 0: //读数为“0”,此位为一节点
{
if (B[0] & 0X80)
{ //本节点已处理
DATA = 0XFF;
A[7] |= 0X80; //地址表写"1"
}
else
{ //本节点未处理
if (I == POINT0)
{ //当前节点是最后的未处理节点
DATA = 0XFF;
A[7] |= 0X80; //地址表写"1"
B[0] |= 0X80; //节点表写"1"
}
else
{
A[7] &= ~0X80; //地址表写"0"
POINT = I; //设置节点指针
}
}
DATA = Write_BUS_bit (DATA); //选择方向
}
break;
case 0X80:
{
DATA = 0X00;
DATA = Write_BUS_bit (DATA); //写"0"
A[7] &= ~0X80;
}
break;
case 0X40:
{
DATA = 0X0F;
DATA = Write_BUS_bit (DATA); //写"1"
A[7] |= 0X80;
}
break;
case 0XC0:
{
FLAG |= FLAG_TEMP_OVER;
}
break;
default:
break;
}
} //I循环结束
if(!(FLAG & FLAG_TEMP_OVER))
{
CRC = CRC_Verify(PA,7);
if (CRC == A[7])
{
for (I=0; I<8; I++) ID[J][I] = A[I];
POINT0 = POINT;
K = 0;
}
else
{
J--;
K++;
}
}
} //J循环结束
TEMP_NUMBER = J;
}
else
{ //复位失败,置失败标志
FLAG &= FLAG_TEMP_OK;
}
}
//****************************************************************************
//模块名:Read_Temp
//描述: 读温度子程序。
//****************************************************************************
void Read_Temp (void)
{
unsigned char I,J,DATA,CRC;
unsigned char ROM[9];
unsigned char *PA;
Rst_DS18B20(); //温度传感器复位
if ((TEMP_NUMBER > 0) && (FLAG && FLAG_TEMP_RET))
{ //温度传感器数量>0并且复位正常
Write_BUS_Byte (0xcc); //写"跳过"命令
Write_BUS_Byte (0x44); //写"读温度"命令
DATA = 0;
I = 0XFF;
while ((DATA != 0XFF) && (I>0))
{ //循环等待温度转换结束
DATA = Read_BUS_Byte();
I--;
}
for (I=0; I<TEMP_NUMBER; I++)
{
PA = ROM;
Rst_DS18B20();
Write_BUS_Byte (0x55); //写"匹配温度传感器"命令
for (J=0; J<8; J++) //写温度传感器地址
{
Write_BUS_Byte (ID[I][J]);
}
Write_BUS_Byte (0xbe); //写"读存储器"命令
for (J=0; J<9; J++)
{
ROM[J] = Read_BUS_Byte();
}
CRC = CRC_Verify(PA,8);
if (CRC == ROM[8])
{
PA =(unsigned char*)&TEMP[I];
*PA = ROM[0];
*(PA+1) = ROM[1];
}
} //I循环结束
}
}
//****************************************************************************
//模块名:Temp
//描述: 温度子程序。
//****************************************************************************
void Temp (void)
{
Rst_DS18B20 ();
Search_ROM ();
Read_Temp();
_NOP();
}
//****************************************************************************
//模块名:Delay
//描述: 延时子程序。
//****************************************************************************
void Delay(unsigned int x)
{
while(x !=0)x--;
}
本程序是以MSP430F149单片机的DS18B20C语言程序,DS18B20的DQ脚连接MSP430单片机的P6.4,把读取到温度值,存放在float类型数组fT[]里面,如果你需要移值此文件显示在液晶或其它显示设备上,只要调用 fT[]数组即可。
- MSP430F149的DS18B20C语言程序
- MSP430f149上LCD显示的程序【转载】
- msp430f149单片机控制步进电机C语言程序
- MSP430F149按键检测程序
- MSP430F149的ADC12模块
- msp430f149单片机串口C程序
- MSP430F149串口收发程序详解
- msp430f149相关的一些描述
- 关于MSP430F149的ADC转换过程详解
- 基于MSP430f149单片机的简单秒表
- MSP430F149流水灯闪烁以及数码管的显示
- MSP430F149嵌入式系统中FLASH K9F1G08U0M的应用
- MSP430F149嵌入式系统中FLASH K9F1G08U0M的应用
- c语言的程序
- msp430F149串口UART结合舵机控制板来控制机器人动作的模版
- 跪求msp430f149资料???????????????
- MSP430F149时钟源选择
- MSP430F149 FLASH 操作
- HTTP协议详解
- (挑战编程_3_2)Where's Waldorf?
- 学习android这些天,学会反编译后顿时伤心了
- 初涉数据库之使用数据
- A*算法学习笔记
- MSP430F149的DS18B20C语言程序
- VC++深入详解--掌握c++
- (挑战编程_3_3)Common Permutation
- CodeIgniter 核心代码阅读-入口文件index.php
- 常用Linux系统信息查看命令
- 2013-5-30
- POJ 3261 Milk Patterns(后缀数组)
- The Eclipse Color Theme Plugin http://eclipsecolorthemes.org/
- 五、 作业