单片机实时温度采集并通过串口通信上传电脑显示

首先说下我所用到的主要器件器件:STC89C52,AT24C08,DS18B20,MAX232

实验源代码:

 

//接上18B20温度传感器(另购)后数码管显示出当前温度
#include <reg52.h>
#include <intrins.h>
#include <AT24C08.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P1^0;           //define interface
uint temp;             // variable of temperature
uchar flag,dat1;            // sign of the result positive or negative
uchar code table[]={
0xC0,0xF9,0xA4,0xB0,
0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8E};
/*uchar code table1[]={
0x40,0x79,0x24,0x30,
0x19,0x12,0x02,0xF8,
0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8E};*/
sbit wela1 = P1^4;
sbit wela2 = P1^5;
sbit wela3 = P1^6;
/*unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
                        0x87,0xff,0xef};
 */
/*********************************************
                 串口通信部分
*********************************************/
void RS232_Init()
{      
	TMOD=0x20;//设置定时器1为工作方式2
	TH1=0xfd;
	TL1=0xfd;
	TR1=1;
	REN=1;
	SM0=0;
	SM1=1;
	EA=1;
	ES=1;
}
/*-----------------------发送数据函数----------------------------*/
void USART_Transmit(unsigned char buf)
{    
       SBUF=buf;                  //发送数据
       while(TI==0);                //等待发送结束
       TI=0;                           //清除发送结束标志
}
/*********************************************
					AT24C08读写部分
********************************************/
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Delay1ms(uint x)
 函数功能: 延时1ms
 入口参数: x
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Delay1ms(uint x)
{
 uint i;
 while(x--)
 for(i=0;i<165;i++);
}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Start()
 函数功能: 起始函数
 入口参数: 无
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Start()
{AT24C08_SDA_1();AT24C08_SCL_1();NOP();AT24C08_SDA_0();NOP();AT24C08_SCL_0();}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Stop()
 函数功能: 停止函数
 入口参数: 无
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Stop()
{AT24C08_SDA_0();AT24C08_SCL_1();NOP();AT24C08_SDA_1();NOP();AT24C08_SCL_0();}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Ack()
 函数功能: 应答函数
 入口参数: 无
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Ack()
{AT24C08_SDA_0();NOP();AT24C08_SCL_1();NOP();AT24C08_SCL_0();}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_NO_Ack()
 函数功能: 无应答函数
 入口参数: 无
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_NO_Ack()
{AT24C08_SDA_1();AT24C08_SCL_1();NOP();AT24C08_SCL_0();}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Writ_Byte(uchar dat)
 函数功能: 写函数
 入口参数: dat
 返回参数:t
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
uchar AT24C08_Writ_Byte(uchar dat)
{
 uchar i;
 uchar t;
 AT24C08_SDA_1();AT24C08_SCL_0();
 for(i=0;i<8;i++)
 {
  if(dat&0x80)AT24C08_SDA_1();
  else AT24C08_SDA_0();
  AT24C08_SCL_1();NOP();
  AT24C08_SCL_0();
  dat<<=1; 
 }
 NOP();
 AT24C08_SDA_1();NOP();
 AT24C08_SCL_1();NOP();
 t=(AT24C08_CONT & (1<<AT24C08_SDA));
 AT24C08_SCL_0();
 return t;
}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Read_Byte()
 函数功能: 读函数
 入口参数: 无
 返回参数:dat
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
uchar AT24C08_Read_Byte()
{
   uchar i,dat;
   AT24C08_SDA_1();AT24C08_SCL_1();
   for(i=0;i<8;i++)
   {
     dat<<=1;
     AT24C08_SCL_1();
  if((AT24C08_CONT & (1<<AT24C08_SDA)))dat|= 0x01;
  AT24C08_SCL_0();
   }
   AT24C08_Ack();
   return dat;
}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Write_One_Dat(uchar add,uchar dat)
 函数功能: 写一字节函数
 入口参数: add,dat
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
int AT24C08_Write_One_Dat(uchar add,uchar dat)
{
 EA=0;
 AT24C08_Start();
 if(AT24C08_Writ_Byte(sla))return 0;
 if(AT24C08_Writ_Byte(add))return 0;
 if(AT24C08_Writ_Byte(dat))return 0;
 AT24C08_Stop();
 AT24C08_Delay1ms(10);
 EA=1;
 return 1;
} 
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Write_Mul_Dat(uchar add,uchar dat)
 函数功能: 写多字节函数
 入口参数: add,dat
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Write_Mul_Dat(uchar add,uchar *s,uchar n)
{
 uchar i;
 EA=0;
 for(i=0;i<n;i++)
 {while(!AT24C08_Write_One_Dat(add+i,s[i]));
 }
  EA=1;
}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Read_One_Dat(uchar add)
 函数功能: 读一字节函数
 入口参数: add,dat
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
int AT24C08_Read_One_Dat(uchar add)
{ 
 EA=0;
 AT24C08_Start();
 if(AT24C08_Writ_Byte(sla))return 0;
 if(AT24C08_Writ_Byte(add))return 0;
 AT24C08_Start();
 if(AT24C08_Writ_Byte(sla|0x01))return 0;
 dat1=AT24C08_Read_Byte();AT24C08_NO_Ack();
 AT24C08_Stop();
 EA=1;
 return 1; 
} 
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Read_Mul_Dat(uchar add)
 函数功能: 读多字节函数
 入口参数: add,s,n
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Read_Mul_Dat(uchar add,uchar *s,uchar n)
{
 uchar i;
 EA=0;
 for(i=0;i<n;i++)
 {
  while(!AT24C08_Read_One_Dat(add+i));
  s[i]=dat1;
 }
 EA=1;
}
/**************************************************************
 隶属模块:AT24C08存储模块
 函数名称:AT24C08_Clear()
 函数功能: 清空
 入口参数: 无
 返回参数:无
 修改时间: 2011-7-10
 修改者:  彭瑞
***************************************************************/
void AT24C08_Clear()
{
 uchar i;
 EA=0;
 for(i=0;i<256;i++)
 {
  AT24C08_Write_One_Dat(i,0xff);
 }
 EA=1;
}
/*********************************************
                    温度采集部分
*********************************************/
void delay(uint count)      //delay
{
  uint i;
  while(count)
  {
    i=200;
    while(i>0)
    i--;
    count--;
  }
}
void dsreset(void)       //send reset and initialization command
{
  uint i;
  DS=0;
  i=103;
  while(i>0)i--;
  DS=1;
  i=4;
  while(i>0)i--;
}

bit tmpreadbit(void)       //read a bit
{
   uint i;
   bit dat;
   DS=0;i++;          //i++ for delay
   DS=1;i++;i++;
   dat=DS;
   i=8;while(i>0)i--;
   return (dat);
}

uchar tmpread(void)   //read a byte date
{
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tmpreadbit();
    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  }
  return(dat);
}

void tmpwritebyte(uchar dat)   //write a byte to ds18b20
{
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)     //write 1
    {
      DS=0;
      i++;i++;
      DS=1;
      i=8;while(i>0)i--;
    }
    else
    {
      DS=0;       //write 0
      i=8;while(i>0)i--;
      DS=1;
      i++;i++;
    }

  }
}

void tmpchange(void)  //DS18B20 begin change
{
  dsreset();
  delay(1);
  tmpwritebyte(0xcc);  // address all drivers on bus
  tmpwritebyte(0x44);  //  initiates a single temperature conversion
}

uint tmp()               //get the temperature
{
  float tt;
  uchar a,b;
  dsreset();
  delay(1);
  tmpwritebyte(0xcc);//访问总线上的器件
  tmpwritebyte(0xbe);//从器件上读取值
  a=tmpread();
  b=tmpread();
  temp=b;
  temp<<=8;             //two byte  compose a int variable
  temp=temp|a;
  tt=temp*0.0625;
  temp=tt*10+0.5;//四舍五入
  return temp;
}

void readrom()          //read the serial
{
  uchar sn1,sn2;
  dsreset();
  delay(1);
  tmpwritebyte(0x33);
  sn1=tmpread();
  sn2=tmpread();
}


void delay10ms()            //delay
  {
    uchar a,b;
    for(a=10;a>0;a--)
      for(b=60;b>0;b--);
   }

void display(uint temp)			//显示程序
{
   uchar A1,A2,A2t,A3;
   A1=temp/100;
   A2t=temp%100;
   A2=A2t/10;
   A3=A2t%10;

   wela3=1;
   P2=table[A1];		//显示百位
   delay(1);
   wela3=0;

   wela2=1;
   P2=table[A2]-0x80;		//显示十位
   delay(1);
   wela2=0;

   wela1=1;
   P2=table[A3];		//显示个位
   delay(1);
   wela1=0;
}


void main()
{
	uint i;
	uchar a,dat;
	RS232_Init();	
	tmpchange();
	// delay(200);
	//for(a=10;a>0;a--)
	//{   		
		//display(tmp());
	//}	
	for(i=0;i<1024;i++){
		tmpchange();
		dat=400-tmp();
		AT24C08_Write_One_Dat(i,dat);
		for(a=20;a>0;a--)
			display(400-dat);
	}
	do{
		display(888);
		if(flag==1)
		{
			ES=0;
			flag=0;
			for(i=0;i<1024;i++){
				AT24C08_Read_One_Dat(i);
				USART_Transmit(dat1);
			}
			ES=1;
		}
	}while(1);
}
/*---------------------发送字符串函数--------------------------*/
void USART_Transmit_str() interrupt 4
{
	uchar a;
	RI=0;
//	P1=SBUF;
	a=SBUF;
	flag=1;
}


AT24C08.h源代码:

 

 

#ifndef _short_type_H_
#define _short_type_H_
#define uchar unsigned char
#define uint  unsigned int
#endif

#define sla 0xa0
#define NOP()  _nop_();_nop_();_nop_();_nop_();_nop_()

#define AT24C08_CONT P1

#define AT24C08_SDA 2
#define AT24C08_SCL 1


#define AT24C08_SDA_1() AT24C08_CONT |= (1<<AT24C08_SDA)
#define AT24C08_SDA_0() AT24C08_CONT &=~(1<<AT24C08_SDA)
#define AT24C08_SCL_1() AT24C08_CONT |= (1<<AT24C08_SCL)
#define AT24C08_SCL_0() AT24C08_CONT &=~(1<<AT24C08_SCL)

/*unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
                        0x87,0xff,0xef};
*/
void AT24C08_Start();//开始
void AT24C08_Stop();//结束
void AT24C08_Ack();//应答
void AT24C08_NO_Ack();//无应答

uchar AT24C08_Writ_Byte(uchar dat);//写数据
uchar AT24C08_Read_Byte();//读数据

int AT24C08_Write_One_Dat(uchar add,uchar dat);//写一字节数据
void AT24C08_Write_Mul_Dat(uchar add,uchar *s,uchar n);//写多字节数据
int AT24C08_Read_One_Dat(uchar add);//读一字节数据
void AT24C08_Read_Mul_Dat(uchar add,uchar *s,uchar n);//读多字节数据

void AT24C08_Clear();//清存储空间数据
void AT24C08_Delay1ms(uint x);//延时1ms
/****************串口通信*********************/
void RS232_Init();
void USART_Transmit(unsigned char buf);
void delay(uint count);
void display(uint temp);//数码管先显示
#endif

由于最近时间比较忙,这里过多的话就不说了。

  • 15
    点赞
  • 119
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
DS18B20是单总线数字传感器,共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。 这几个信号的时序如下: 1)复位脉冲和应答脉冲 单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲,若为低电平,再延时480us。 2)写时序 写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。 3)读时序 单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。 DS18B20的温度读取过程一般为:复位->发SKIPROM命令(0XCC)->发开始转换命令(0X44)->延时->复位->发送SKIPROM命令(0XCC)->发读存储器命令(0XBE)->连续读出两个字节数据(即温度)->结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值