温度传感器cc2530源码.docx
《温度传感器cc2530源码.docx》由会员分享,可在线阅读,更多相关《温度传感器cc2530源码.docx(15页珍藏版)》请在冰豆网上搜索。
温度传感器cc2530源码
/*
温度传感器头文件(.h文件);
*/
ds18b20程序。
本程序使用说明:
在使用之前必须在相应的代码文件里全局位置加入一
段代码:
//#defineFLOAT_MODE1
#ifFLOAT_MODE
unsignedcharTemperature[8];//小数模式需要8个
字节;
#defineTemp_Len_7//温度值字符串有效长度;
#else
unsignedcharTemperature[5];//整数模式需要5个
#defineTemp_Len_4//温度值字符串有效长度;
#endif
加入此段代码后可以通过是否注释#define
FLOAT_MODE1
这句代码来选择是获取整数温度还是获取小数温度,注释后
为获
取整数温度。
获取温度的函数如下:
TemperatureConver();
不需要参数,结果以字符串的形式保存在
Temperature[x]中,
通过字符串操作方式操作该数组变量;
该程序在cc2530采用外部晶振32MHZ时使用,如果频率
不是
32MHZ,会因为延时不正确导致时序问题,故在其他频率下
使用
需自行调试延时函数的函数体。
voidds18b20_delay_us(unsignedintx)
#ifndef__DS18B20_H__
#define__DS18B20_H__
#include
//引脚定义,即ds18b20的数据线;
#defineDs18b20_DataP0_7//根据实际更改;
/*//////////////////////////////////////
开启下列定义表示读取的温度精确
到小数,注释后精度为整数;
*///////////////////////////////////////
//默认注释//#defineFLOAT_MODE1//默认下不开启;<<<<<<-----------//自行更改;
////////////////////////////////////////
externunsignedcharTemperature[8];//小数模式需要8个字节;
externunsignedcharTemperature[5];//整数模式需要5个字节;
//端口配置;
#defineINPUT_MODEP0DIR&=0x7f
#defineOUTPUT_MODEP0DIR|=0x80
//32MHZ下,供温度传感器使用的us延时函数;
voidds18b20_delay_us(unsignedintx);
//ds18b20初始化函数;
unsignedcharDS18B20_Init(void);
//读一个字节函数:
unsignedcharReadByte(void);
//写一个字节函数;
voidWriteByte(unsignedcharByte);
//读取温度函数;
unsignedintReadTemperature(void);
//温度转换函数;
voidTemperatureConver(void);
温度传感器源文件;
#include"ds18b20.h"
//#include"OnBoard.h"
{
unsignedinti,j;
for(i=0;i{for(j=0;j<2;j++);}/*while(x--){asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");}*/}unsignedcharDS18B20_Init(void){unsignedcharIS_FINISH=0;//若ds18b20复位成功,置1,默认为0;unsignedintCount=0;//获取ds18b20复位成功与否时防止超时的变量;OUTPUT_MODE;//温度传感器IO口为输出模式;Ds18b20_Data=1;//初始时确保ds18b20数据线为高;ds18b20_delay_us(100);//稍作延时;Ds18b20_Data=0;//复位ds18b20;ds18b20_delay_us(600);//精确延时,必须满足480us~960us;Ds18b20_Data=1;//在480us~960us后拉高数据线,ds18b20会在在15~60us产生脉冲;ds18b20_delay_us(40);//精确延时,15~60us后接收数据线上60~240us的存在脉冲;INPUT_MODE;//温度传感器IO口为输入模式;do{Count++;IS_FINISH=Ds18b20_Data;//读IO口状态;}while((IS_FINISH!=0)&&(Count<400));//大约3ms,这段时间等待响应;OUTPUT_MODE;//温度传感器IO口为输出模式;Ds18b20_Data=1;//归还数据线;ds18b20_delay_us(100);//稍作延时;//如果读取的脉冲为0,说明初始化成功,否则失败;returnIS_FINISH;}unsignedcharReadByte(void){unsignedchari,Byte=0;//Byte为读取的字节;OUTPUT_MODE;//温度传感器IO口为输出模式;Ds18b20_Data=1;//初始时确保ds18b20数据线为高;ds18b20_delay_us(100);//稍作延时;for(i=0;i<8;i++)//8位,读8次;{Byte>>=1;//腾出一位用于存入下次的读取位值;Ds18b20_Data=0;//ds18b20在拉低4us后沿拉高产生10us的读间隙;ds18b20_delay_us(4);//精确延时;Ds18b20_Data=1;//拉高;ds18b20_delay_us(2);//稍作延时;if(Ds18b20_Data==1)//判断数据位是否为高,若高,做运算,低则保留;{Byte|=0x80;}//最高位置1;ds18b20_delay_us(20);//稍作延时;}returnByte;}voidWriteByte(unsignedcharByte){unsignedchari;OUTPUT_MODE;//温度传感器IO口为输出模式;Ds18b20_Data=1;//初始时确保ds18b20数据线为高;ds18b20_delay_us(100);//稍作延时;for(i=0;i<8;i++){Ds18b20_Data=0;//拉低数据线后的15us为写入位时间间隙;Ds18b20_Data=Byte&0x01;//数据位写入,写入后的45us内ds18b20采样,完成写//入位工作;ds18b20_delay_us(40);//40us延时后保证采样成功;Ds18b20_Data=1;//数据线重新置高;Byte>>=1;//移出已经写入的位;}ds18b20_delay_us(10);//稍作延时;}/*读取温度的步骤:1.启动温度转换;(1.复位2.发SkipROM命令,即0xcc3.发ConvertT命令,即0x44);2.复位;3.发SkipROM命令,即0xcc;4.读ds18b20寄存器命令,即0xbe;5.读两字节温度;(低字节高字节)6.温度格式转换;*/unsignedintReadTemperature(void){unsignedintTemperature=0,//最终的返回值,同时也用来存放高字节;low=0;//低字节;DS18B20_Init();//复位;WriteByte(0xcc);//skipROM命令;WriteByte(0x44);//ConverT命令;ds18b20_delay_us(5);//稍作延时;DS18B20_Init();//复位;WriteByte(0xcc);//skipROM命令;WriteByte(0xbe);//读寄存器命令,前两个寄存器存放温度值;low=ReadByte();//读取第一个寄存器,即低位温度值;Temperature=ReadByte();//读取第二个寄存器,即高位温度值;Temperature<<=8;//高字节移动到高8位,低8位用来放低字节;Temperature+=low;//存入低字节;returnTemperature;//返回读取值;} voidTemperatureConver(void){#ifFLOAT_MODEunsignedcharTempH,TempL;unsignedintTemp;Temp=ReadTemperature();//读取当前温度;if(Temp&0x80000)//最高位为1时表示温度为负数;{Temperature[0]='-';//负号标志,表示温度为负数;Temp=~Temp;//取反Temp+=1;//加1;//当读出数为负的时,必须做取反加1操作;}//ifelse{Temperature[0]='';}//温度为正时,第一位置空;//整数部分;TempH=Temp>>4;//将温度整数部分存放在TempH中,整数部分包括高字节的低4位//和低字节的高4位;//小数部分;TempL=(unsignedchar)(Temp&0x000f);//将温度小数部分存放在TempL中,小数部分由//低字节的低4位决定;//小数近似处理,处理原理见下表://------------------------------------------------------------------------------///*二进制:1111十进制:8421小数:0.50.250.1250.0625存在一个整数6,使得十进制数与小数点后的值的转换关系近似相等:8*6=48偏差24*6=2412*60=120忽略1*600=600于是,若我们只需要小数点后两位,则只需要*6即可,需要后一位的话*6/10;若还想提高精度,可加一个修正值,该值建议为:1或者2;*///--------------------------------------------------------------------------------//TempL=TempL*6;//近似处理转换,两位小数;TempL+=1;//修正值;//百位温度值;if(TempH/100==0){Temperature[1]='';}else{Temperature[1]=TempH/100+'0';}//十位温度值;if((TempH/100==0)&&((TempH%100)/10==0)){Temperature[2]='';}else{Temperature[2]=(TempH%100)/10+'0';}//个位温度;Temperature[3]=(TempH%100)%10+'0';//小数点;Temperature[4]='.';//小数部分;Temperature[5]=TempL/10+'0';Temperature[6]=TempL%10+'0';//字符串结束符;Temperature[7]='\0';//_1ms();//稍作延时;ds18b20_delay_us(5);#elseunsignedintTemp;Temp=ReadTemperature();//读取当前温度;if(Temp&0x80000)//最高位为1时表示温度为负数;{Temperature[0]='-';//负号标志,表示温度为负数;Temp=~Temp;//取反Temp+=1;//加1;//当读出数为负的时,必须做取反加1操作;}//ifelse{Temperature[0]='';}//温度为正时,第一位置空;//整数部分;Temp>>=4;//将低4位移除,因为这4位为小数部分;//百位温度值;if(Temp/100==0){Temperature[1]='';}else{Temperature[1]=Temp/100+'0';}//十位温度值;if((Temp/100==0)&&((Temp%100)/10==0)){Temperature[2]='';}else{Temperature[2]=(Temp%100)/10+'0';}//个位温度;Temperature[3]=(Temp%100)%10+'0';//字符串结束符;Temperature[4]='\0';//_1ms();//稍作延时;ds18b20_delay_us(5);#endif} /*主函数所在文件,用做测试;*//*USART0发送温度程序测试。*/ #include#include#include"ds18b20.h" /*使用ds18b20需引用的一段代码*///#defineFLOAT_MODE1#ifFLOAT_MODEunsignedcharTemperature[8];//小数模式需要8个字节;#defineTemp_Len_7//温度值字符串有效长度;#elseunsignedcharTemperature[5];//整数模式需要5个字节;#defineTemp_Len_4//温度值字符串有效长度;#endifvoiddelay(unsignedintx){unsignedinti,j;for(i=0;i{for(j=0;j<1000;j++);}}voidCLOCK_Init(){CLKCONCMD&=~0x40;while(CLKCONSTA&0x40);CLKCONCMD&=~0x47;}voidUART0_Init(){PERCFG=0x00;P0SEL=0x0c;P2DIR&=~0xc0;U0CSR|=0x80;U0GCR|=11;U0BAUD|=216;U0CSR|=0x40;UTX0IF=0;}voidSendString(char*String,unsignedcharLen){unsignedchari;for(i=0;i{U0DBUF=*String++;while(UTX0IF==0);UTX0IF=0;}}voidmain(){P0SEL&=0x7f;CLOCK_Init();UART0_Init();while(1){TemperatureConver();delay(5);SendString(Temperature,Temp_Len_);delay(1000);}}
for(j=0;j<2;j++);
}
while(x--)
asm("NOP");
unsignedcharDS18B20_Init(void)
unsignedcharIS_FINISH=0;//若ds18b20复位成功,置1,默认为0;
unsignedintCount=0;//获取ds18b20复位成功与否时防止超时的变量;
OUTPUT_MODE;//温度传感器IO口为输出模式;
Ds18b20_Data=1;//初始时确保ds18b20数据线为高;
ds18b20_delay_us(100);//稍作延时;
Ds18b20_Data=0;//复位ds18b20;
ds18b20_delay_us(600);//精确延时,必须满足480us~960us;
Ds18b20_Data=1;//在480us~960us后拉高数据线,ds18b20会在在15~60us产生脉冲;
ds18b20_delay_us(40);//精确延时,15~60us后接收数据线上60~240us的存在脉冲;
INPUT_MODE;//温度传感器IO口为输入模式;
do
Count++;
IS_FINISH=Ds18b20_Data;//读IO口状态;
while((IS_FINISH!
=0)&&(Count<400));//大约3ms,这段时间等待响应;
Ds18b20_Data=1;//归还数据线;
//如果读取的脉冲为0,说明初始化成功,否则失败;
returnIS_FINISH;
unsignedcharReadByte(void)
unsignedchari,Byte=0;//Byte为读取的字节;
for(i=0;i<8;i++)//8位,读8次;
Byte>>=1;//腾出一位用于存入下次的读取位值;
Ds18b20_Data=0;//ds18b20在拉低4us后沿拉高产生10us的读间隙;
ds18b20_delay_us(4);//精确延时;
Ds18b20_Data=1;//拉高;
ds18b20_delay_us
(2);//稍作延时;
if(Ds18b20_Data==1)//判断数据位是否为高,若高,做运算,低则保留;
{Byte|=0x80;}//最高位置1;
ds18b20_delay_us(20);//稍作延时;
returnByte;
voidWriteByte(unsignedcharByte)
unsignedchari;
for(i=0;i<8;i++)
Ds18b20_Data=0;//拉低数据线后的15us为写入位时间间隙;
Ds18b20_Data=Byte&0x01;//数据位写入,写入后的45us内ds18b20采样,完成写//入位工作;
ds18b20_delay_us(40);//40us延时后保证采样成功;
Ds18b20_Data=1;//数据线重新置高;
Byte>>=1;//移出已经写入的位;
ds18b20_delay_us(10);//稍作延时;
读取温度的步骤:
1.启动温度转换;(1.复位2.发SkipROM命令,即0xcc3.发ConvertT命令,即0x44);
2.复位;
3.发SkipROM命令,即0xcc;
4.读ds18b20寄存器命令,即0xbe;
5.读两字节温度;(低字节高字节)
6.温度格式转换;
unsignedintReadTemperature(void)
unsignedintTemperature=0,//最终的返回值,同时也用来存放高字节;
low=0;//低字节;
DS18B20_Init();//复位;
WriteByte(0xcc);//skipROM命令;
WriteByte(0x44);//ConverT命令;
ds18b20_delay_us(5);//稍作延时;
WriteByte(0xbe);//读寄存器命令,前两个寄存器存放温度值;
low=ReadByte();//读取第一个寄存器,即低位温度值;
Temperature=ReadByte();//读取第二个寄存器,即高位温度值;
Temperature<<=8;//高字节移动到高8位,低8位用来放低字节;
Temperature+=low;//存入低字节;
returnTemperature;//返回读取值;
voidTemperatureConver(void)
unsignedcharTempH,TempL;
unsignedintTemp;
Temp=ReadTemperature();//读取当前温度;
if(Temp&0x80000)//最高位为1时表示温度为负数;
Temperature[0]='-';//负号标志,表示温度为负数;
Temp=~Temp;//取反
Temp+=1;//加1;
//当读出数为负的时,必须做取反加1操作;
}//if
else{Temperature[0]='';}//温度为正时,第一位置空;
//整数部分;
TempH=Temp>>4;//将温度整数部分存放在TempH中,整数部分包括高字节的低4位//和低字节的高4位;
//小数部分;
TempL=(unsignedchar)(Temp&0x000f);//将温度小数部分存放在TempL中,小数部分由//低字节的低4位决定;
//小数近似处理,处理原理见下表:
//------------------------------------------------------------------------------//
二进制:
1111
十进制:
8421
小数:
0.50.250.1250.0625
存在一个整数6,使得十进制数与小数点后的值的转换关系近似相等:
8*6=48偏差2
4*6=241
2*60=120忽略
1*600=600
于是,若我们只需要小数点后两位,则只需要*6即可,需要后一位的话*6/10;
若还想提高精度,可加一个修正值,该值建议为:
1或者2;
//--------------------------------------------------------------------------------//
TempL=TempL*6;//近似处理转换,两位小数;
TempL+=1;//修正值;
//百位温度值;
if(TempH/100==0){Temperature[1]='';}
else{Temperature[1]=TempH/100+'0';}
//十位温度值;
if((TempH/100==0)&&((TempH%100)/10==0))
{Temperature[2]='';}
else{Temperature[2]=(TempH%100)/10+'0';}
//个位温度;
Temperature[3]=(TempH%100)%10+'0';
//小数点;
Temperature[4]='.';
Temperature[5]=TempL/10+'0';
Temperature[6]=TempL%10+'0';
//字符串结束符;
Temperature[7]='\0';
//_1ms();//稍作延时;
ds18b20_delay_us(5);
Temp>>=4;//将低4位移除,因为这4位为小数部分;
if(Temp/100==0){Temperature[1]='';}
else{Temperature[1]=Temp/100+'0';}
if((Temp/100==0)&&((Temp%100)/10==0))
else{Temperature[2]=(Temp%100)/10+'0';}
Temperature[3]=(Temp%100)%10+'0';
Temperature[4]='\0';
主函数所在文件,用做测试;
USART0发送温度程序测试。
/*使用ds18b20需引用的一段代码*/
unsignedcharTemperature[8];//小数模式需要8个字节;
unsignedcharTemperature[5];//整数模式需要5个字节;
voiddelay(unsignedintx)
for(i=0;i{for(j=0;j<1000;j++);}}voidCLOCK_Init(){CLKCONCMD&=~0x40;while(CLKCONSTA&0x40);CLKCONCMD&=~0x47;}voidUART0_Init(){PERCFG=0x00;P0SEL=0x0c;P2DIR&=~0xc0;U0CSR|=0x80;U0GCR|=11;U0BAUD|=216;U0CSR|=0x40;UTX0IF=0;}voidSendString(char*String,unsignedcharLen){unsignedchari;for(i=0;i{U0DBUF=*String++;while(UTX0IF==0);UTX0IF=0;}}voidmain(){P0SEL&=0x7f;CLOCK_Init();UART0_Init();while(1){TemperatureConver();delay(5);SendString(Temperature,Temp_Len_);delay(1000);}}
for(j=0;j<1000;j++);
voidCLOCK_Init()
CLKCONCMD&=~0x40;
while(CLKCONSTA&0x40);
CLKCONCMD&=~0x47;
voidUART0_Init()
PERCFG=0x00;
P0SEL=0x0c;
P2DIR&=~0xc0;
U0CSR|=0x80;
U0GCR|=11;
U0BAUD|=216;
U0CSR|=0x40;
UTX0IF=0;
voidSendString(char*String,unsignedcharLen)
for(i=0;i{U0DBUF=*String++;while(UTX0IF==0);UTX0IF=0;}}voidmain(){P0SEL&=0x7f;CLOCK_Init();UART0_Init();while(1){TemperatureConver();delay(5);SendString(Temperature,Temp_Len_);delay(1000);}}
U0DBUF=*String++;
while(UTX0IF==0);
voidmain()
P0SEL&=0x7f;
CLOCK_Init();
UART0_Init();
while
(1)
delay(5);
SendString(Temperature,Temp_Len_);
delay(1000);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1