/*************** writer:shopping.w ******************/
#include reg51.h
#include intrins.h
#define uint unsigned int
#define uchar unsigned char
sbit DQ = P3^6;
uchar code DSY_CODE[] =
{ 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X00};
uchar code df_Table[] = {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchar CurrentT = 0;
uchar Temp_Value[]={0x11,0x22};
uchar Display_Digit[]={0,0,0,0};
bit DS18B20_IS_OK = 1;
void Delay(uint x)
{
while(--x);
}
uchar Init_DS18B20()
{
uchar status;
DQ = 1;
Delay(8);
DQ = 0;
Delay(90);
DQ = 1;
Delay(8);
DQ = 1;
return status;
}
uchar ReadOneByte()
{
uchar i,dat=0;
DQ = 1;
_nop_();
for(i=0;i8;i++)
{
DQ = 0;
dat = 1;
DQ = 1;
_nop_();
_nop_();
if(DQ)
dat |= 0X80;
Delay(30);
DQ = 1;
}
return dat;
}
void WriteOneByte(uchar dat)
{
uchar i;
for(i=0;i8;i++)
{
DQ = 0;
DQ = dat 0x01;
Delay(5);
DQ = 1;
dat = 1;
}
}
void Read_Temperature()
{
if(Init_DS18B20() ==1 )
DS18B20_IS_OK = 0;
else
{
WriteOneByte(0xcc);
WriteOneByte(0x44);
Init_DS18B20();
WriteOneByte(0xcc);
WriteOneByte(0xbe);
Temp_Value[0] = ReadOneByte();
Temp_Value[1] = ReadOneByte();
DS18B20_IS_OK=1;
}
}
void Display_Temperature()
{
uchar i;
uchar t=150;
uchar ng=0, np=0;
if ( (Temp_Value[1] 0xf8) == 0xf8)
{
Temp_Value[1] = ~Temp_Value[1];
Temp_Value[0] = ~Temp_Value[0]+1;
if (Temp_Value[0] == 0x00) Temp_Value[1]++;
ng=1;np=0xfd;
}
Display_Digit[0] = df_Table[ Temp_Value[0] 0x0f ];
CurrentT = ((Temp_Value[0] 0xf0)4) | ((Temp_Value[1] 0x07)4);
Display_Digit[3] = CurrentT / 100;
Display_Digit[2] = CurrentT % 100 / 10;
Display_Digit[1] = CurrentT % 10;
if (Display_Digit[3] == 0)
{
Display_Digit[3] = 10;
np = 0xfb;
if (Display_Digit[2] == 0)
{
Display_Digit[2] = 10;
np = 0xf7;
}
}
for (i=0;i30;i++)
{
P0=0x39;P2=0x7f;Delay(t);P2=0xFF;
P0=0x63;P2=0xbf;Delay(t);P2=0xff;
P0=DSY_CODE[Display_Digit[0]];
P2=0xDF;Delay(t);P2=0xff;
P0=(DSY_CODE[Display_Digit[1]]) | 0x80;
P2=0xef;Delay(t);P2=0xff;
P0=DSY_CODE[Display_Digit[2]];
P2=0xf7;Delay(t);P2=0xff;
P0=DSY_CODE[Display_Digit[3]];
P2=0xfb; Delay(t); P2=0xff;
if (ng)
{
P0 = 0x40; P2 = np; Delay(t); P2=0xff;
}
}
}
void main()
{
Read_Temperature();
Delay(50000);
Delay(50000);
while(1)
{
Read_Temperature();
if(DS18B20_IS_OK)
Display_Temperature();
}
}
一、DS18B20.c文件(用LCD1602显示的 I_N为DS18B20数据IO)
/*
模块名称:温度模块(DS18B20)
模块功能:DS18B20的功能子函数
*/
/********************************************预处理命令*******************************************/
#include"ds18b20.h"
/*
函数名:DS_WriBteAndRead(bit x,unit8 val)
函数功能:向DS18B20内部寄存器写入或读取数据
输入: x,val
输出:DS_WriteAndRead
*/
unit8 DS_WriteAndRead(bit x,unit8 val)
{
unit8 i=0,Red=0;
for(i=8;i0;i--)
{
if(x) //读数据
{
I_N=0;
I_N=1;
Red=1;
if(I_N)Red|=0x80;
}
else //写数据
{
I_N=1;
I_N=0;
I_N=val0x01;
val=1;
}
delay_us(4);
}
if(x)
return(Red);//返回数据
else
return 0;
}
/*
函数名:DS_Reset()
函数功能:DS18B20初始化设置
输入:无
输出:无
*/
void DS_Reset()
{
I_N=1;
I_N=0;
delay_us(50);
I_N=1;
delay_us(30);
DS_WriteAndRead(0,0xcc);//跳过搜索
}
/*
函数名: DS_Data_Handle()
函数功能:数据处理
输入:无
输出:无
*/
void DS_Data_Handle()
{
unit_16 Ra=0,Rb=0,Temp=0;
DS_Reset(); //复位
DS_WriteAndRead(0,0x44); //启动温度转换
DS_Reset(); //复位
delay_us(100);
DS_WriteAndRead(0,0xbe);//读暂存器中的数据
Ra=DS_WriteAndRead(1,0xbe);
Rb=DS_WriteAndRead(1,0xbe);
Temp=Rb;
Temp=8;
Temp|=Ra;
Temp=Temp*0.625+0.5;//数值转换
LCD_Write_Data(0,0xc5);
LCD_Write_Data(1,(Temp/100)+48);
LCD_Write_Data(1,(Temp/10%10)+48);
LCD_Write_Data(1,46);
LCD_Write_Data(1,(Temp%10)+48);
}
方法:
第一:搭建单片机最小系统及供电电源系统;
第二:选择温度传感器及设计温度测试电路,比如DS18B20还是NTC还是PT100,无论哪种,网络上关于这些传感器的帖子及程序不少!
第三:设计速度检测办法,是选择旋转编码器还是什么方式来实现,但是无论哪种,基本输出的都是PWM波形进入单片机外部中断口(INT0或者INT1),然后通过定时1秒范围内,检测到了多少脉冲,这样每一圈发送多少个脉冲,这样就可以知道具体一秒转了多少圈,也就可以计算出来速度了。
第四:关于串口,通过单片机+MAX232通信芯片+DB9接口(也可以使用串口转USB的方式,现在电脑基本没有物理串口了。通过USB来转成串口);设置好通信波特率、数据位、通信格式及停止位后,借助电脑的《串口助手软件》配合来实现即可。
用DS18B20做的电子温度计,非常简单。
#include reg51.h
#include\"AscLed.h\"
#include intrins.h
#include stdio.h
//********************************************************
#define Seck (500/TK) //1秒中的主程序的系数
#define OffLed (Seck*5*60) //自动关机的时间5分钟!
//********************************************************
#if (FHz==0)
#define NOP_2uS_nop_()
#else
#define NOP_2uS_nop_();_nop_()
#endif
//**************************************
#define SkipK 0xcc //跳过命令
#define ConvertK 0x44 //转化命令
#define RdDs18b20K 0xbe //读温度命令
//*******************************************
extern LedOut(void);
//*************************************************
sbit PNP1=P3^4;
sbit PNP2=P3^5;
sbit BEEP=P3^2;
//***********************************
#defineDQ PNP2 //原来的PNP2 BEEP
//***********************************
static unsigned char Power=0;
//************************************
union{
unsigned char Temp[2]; //单字节温度
unsigned int Tt; //2字节温度
}T;
//***********************************************
typedef struct{
unsigned char Flag; //正数标志 0;1==》负数
unsigned char WenDu; //温度整数
unsigned int WenDuDot; //温度小数放大了10000
}WENDU;
//***********************************************
WENDU WenDu;
unsigned char LedBuf[3];
//----------------------------------
//功能:10us 级别延时
// n=1=== 6Mhz=14uS 12MHz=7uS
//----------------------------------
void Delay10us(unsigned char n){
do{
#if (FHz==1)
NOP_2uS;NOP_2uS;
#endif
}while(--n);
}
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n){
unsigned char i;
for(i=0;i8;i++){
DQ=0;
Delay10us(1);//延时13us 左右
DQ=n 0x01;
n=n1;
Delay10us(5);//延时50us 以上
DQ=1;
}
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void){
unsigned char i;
unsigned char temp;
for(i=0;i8;i++){
temp=temp1;
DQ=0;
NOP_2uS;//延时1us
DQ=1;
NOP_2uS;NOP_2uS;//延时5us
if(DQ==0){
temp=temp0x7F;
}else{
temp=temp|0x80;
}
Delay10us(5);//延时40us
DQ=1;
}
return temp;
}
//-----------------------------------
void Init (void){
DQ=0;
Delay10us(45);//延时500us
DQ=1;
Delay10us(9);//延时90us
if(DQ){ //0001 1111b=1f
Power =0; //失败0
}else{
Power++;
DQ=1;
}
}
//----------------------------------
void Skip(void){
Write_18B20(SkipK);
Power++;
}
//----------------------------------
void Convert (void){
Write_18B20(ConvertK);
Power++;
}
//______________________________________
void Get_Ds18b20L (void){
T.Temp[1]=Read_18B20(); //读低位
Power++;
}
//______________________________________
void Get_Ds18b20H (void){
T.Temp[0]=Read_18B20(); //读高位
Power++;
}
//------------------------------------
//规范化成浮点数
// sssss111;11110000
// sssss111;1111(0.5,0.25,0.125,0.0625)
//------------------------------------
void ReadTemp (void){
unsigned char i;
unsigned intF1=0;
char j=1;
code int Code_F[]={6250,1250,2500,5000};
WenDu.Flag=0;
if (T.Temp[0] 0x80){ //负温度
T.Tt =~T.Tt+1; //取反+1=源吗 +符号S
WenDu.Flag=-1;
}
T.Tt = 4; //左移4位
WenDu.WenDu=T.Temp[0]; // 温度整数
//**************************************************
T.Temp[1]=4;
//---------------------------
for (i=0;i4;i++){ //计算小数位
F1 +=(T.Temp[1] 0x01)*Code_F;
T.Temp[1]=1;
}
WenDu.WenDuDot=F1; //温度的小数
Power=0;
}
//----------------------------------
void Delay1S (void){
static unsigned int i=0;
if (++i==Seck) {i=0ower++;}
}
//----------------------------------
void ReadDo (void){
Write_18B20(RdDs18b20K);
Power++;
}
/**********************************
函数指针定义
***********************************/
code void (code *SubTemp[])()={
Init,Skip,Convert,Delay1S,Init,Skip,ReadDo,Get_Ds18b20L,
Get_Ds18b20H,ReadTemp
};
//**************************************
void GetTemp(void){
(*SubTemp[Power])();
}
//---------------------------------------------------
//将温度显示,小数点放大了10000.
void GetBcd(void){
LedBuf[0]=WenDu.WenDu / 10;
LedBuf[1]=WenDu.WenDu % 10 +DotK;
LedBuf[2]=(WenDu.WenDuDot/1000)%10;
if(LedBuf[0]==0)LedBuf[0]=Black;
if(WenDu.Flag==0) return;
if(LedBuf[0] !=Black){
LedBuf[2]=LedBuf[1];
LedBuf[1]=LedBuf[0];
LedBuf[0]=Led_Pol; //'-'
}else{
LedBuf[0]=Led_Pol; //'-'
}
}
/*
//---------------------------------------------------
void JbDelay (void){
static long i;
if (++i=OffLed){
P1=0xff;
P2=0xff;
PCON=0x02;
}
}
*/
/*****************************************************
主程序开始
1:2002_10_1 设计,采用DS18B20测量
2:采用函数数组读取DS18B20.LED数码管显示正常!
3:改变FHz可以用6,12MHz工作!
******************************************************/
code unsigned char Stop[3] _at_ 0x3b;
void main (void){
P1=0xff;
WenDu.WenDu=0;
while (1){
GetTemp();
GetBcd();
// JbDelay();
LedOut();
}
}
复制代码
20091012_8b1ef92155560c13b5807ZmoDVSacjwD[1].jpg (12 KB)
2009-10-21 23:21 上传
下载次数:0
这需要温度感应头与单片机配合的,感应头把温度信号转换成电信号在转换成二进制数,输入单片机,单片机与储存的温度记录相比较,得出当前温度,输出。总得来说就是需要有外部原件把温度换成二进制信号(有的单片机可以直接识别电压信号,内部自动转换二进制信号),单片机识别与存储的数据进行比较得出温度。
单片机温度监测的介绍到此就结束了,感谢您耐心阅读,谢谢。
本文标签:单片机温度监测