专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

51单片机18B20温度与串口实验

作者:佚名   来源:本站原创   点击数:  更新时间:2013年10月25日   【字体:

有图有真相





温度显示在串口调速器上,此软件可到 http://www.51hei.com/mcudown/ 单片机开发实用工具软件这一栏下载
下面单片机部分的源代码:
 

//11.0592晶振
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
code uchar seg[]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60};   //数码管码表
code uchar tab[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};   //数码管位选

//sbit k8=P1^7;   //按键发送温度值
sbit dec=P0^5;   //小数点显示位
static uint count;     //延时发送温度值变量
void delay(uint k)
{
 while(k--);
}
void show_temp(uint k)    //显示温度值函数
{
 P0=seg[k/100];
 P2=tab[2];
 delay(30);
 P0=0xff;
 P2=0xff;
 P0=seg[k%100/10];
 dec=0;       //显示小数点
 P2=tab[1];
 delay(30);
 P0=0xff;
 P2=0xff;
 P0=seg[k%10];
 P2=tab[0];
 delay(30);
 P0=0xff;
 P2=0xff;
}
#include "18B20.h"        //18B20库函数
 
uchar suf;      //存放串口收到的数据
uint temp;    //输出温度值
 
void serial_init()   //串口初始化
{
   TMOD|=0x20;   //定时器设定自动重撞在模式
   TH1=TL1=0xfd;  //9600波特率
   SM2=0;       //无多机处理位
   SM1=1;     // 8位可变波特率模式
   SM0=0;
   TR1=1;         //  定时器1打开
   REN=1;         //串口接收使能
}
void send_byte(uchar u)   //发送一个字节函数
{
   bit es;    //保存先前ES状态变量,这样可以不干扰其他用户用它是现在的状态
   es=ES;
   ES=0;     //暂时关闭串口中断
   SBUF=u;    //数据放入SBUF缓冲器等待发送完成
   while(TI==0);   //等待发送完成
   TI=0;
   ES=es;     //恢复先前状态
}
void send_str(uchar *p) //发送一串字符函数
{
   while(*p)
   {
 send_byte(*p);
 p++;
   }
}
void str_init()   //串口中断初始化
{
 EA=1;
 ES=1;
}
void serial_event() interrupt 4   //串口中断函数
{
   if(RI==1)   //在中断里尽量只做需要的事情
   {
    suf=SBUF;
 RI=0;
   }
   else
   {
 ;
 }
}
void send_number(uchar *p,uint k)    //通过串口发送温度值函数
{
 while(*p)
 {
  send_byte(*p);
  p++;
 }
 send_byte(' ');
 send_byte(' ');
 send_byte(k/100+48);
 send_byte(k%100/10+48);
 send_byte('.');
 send_byte(k%10+48);
 send_byte('\r');
 send_byte('\n');
}
/*
void key8()             //按键发送函数
{
  static uchar i,j;
  if(k8==0)
  {
 if(i==0)
 {
  j++;
  if(j>3)
  {
   i=1;j=0;
   send_number("the temperature is  ",temp);
  }
 }
  }
  else
  {
   i=0;
   j=0;
  }
}
*/
void main()
{
   serial_init();       //串口初始化
   send_byte(12);  //超级终端清屏
   send_str("serial_init is ok \r\n");    //初始化好坏标示字符串
   str_init();           //串口中断初始化
   send_str("str_init is ok \r\n");
 while(1)               
 {
   count++;  
   temp=read_18b20();
   show_temp(temp);
   if(count>500)     //约没3秒发送一次温度值给串口
   {
   send_number("The temperature is ",temp);
   count=0;
   }
   else
   {
   }
 }
}
 
//-----------------------18B20----库函数----------------
sbit dq=P3^4;   //18B20数据口
void send_1()  //发送1位1函数
{
  dq=0;
  dq=0;
  dq=0;
  dq=1;
  delay(2);
}
void send_0() //发送1位0函数
{
  dq=0; 
  delay(2);
  dq=1;
}
void Tsend_byte(uchar dat)
{
 uchar i;
 for(i=0;i<8;i++)
 {
  if(dat&0x01)send_1();
  else send_0();
  dat>>=1;
 }
}
uchar read_byte()   //18B20读取数据函数
{
  uchar i,byte;
  for(i=0;i<8;i++)
  {
    dq=0;
 dq=0;
 dq=1;
 dq=1;
 byte>>=1;
 if(dq==1)
 {
  byte=byte+0x80;  //如果采样为1则最高位为1
 }
 delay(3);
  }
  return byte;
}
uchar start_18b20() //启动18b20实质上判断有误应答信号
{
  static uint cnt;
  dq=0;
  delay(62);
  dq=1;
  while(dq==1)  //等待拉低
  {
 cnt++;
 if(cnt>50000)
 {
 cnt=0;
 return 1;  //等待超时判断说明器件坏了
 }
  }
   while(dq==0)             
   {
 cnt++;
 if(cnt>50000)
 {
  cnt=0;
  return 1;
 }
   }
   return 0;       //正常启动返回0值
}
uint read_18b20()  //读取温度值函数
{
  uchar TH,TL;
  uint temp;
  start_18b20();
  Tsend_byte(0xcc);
  Tsend_byte(0x44);
  ;;
  start_18b20();
  Tsend_byte(0xcc);
  Tsend_byte(0xbe);
   TL=read_byte();
   TH=read_byte();
   temp=TH;
   temp<<=8;
   temp=temp+TL;
   /*if(temp&0xf800)   //如果最高位为1则是温度为负值   .可以设置温度负值符号
   {
 temp=~temp+1;
   }
   */
   temp=temp*0.0625*10;   //显示小数部分
   return temp;
}
关闭窗口

相关文章