原创 DS18B20程序+proteus仿真

2010-3-21 16:07 1356 1 1 分类: MCU/ 嵌入式

/*====================================
这个程序是临时帮一个朋友写的
也是用以前的程序改的,注释了的句子就不必
细究了,用了几个全局变量,风格不是太好。


适合作单片机初学者和proteus入门参考
觉得好的话就顶一下。


作者:  emot
http://blog.ednchina.com/emot


 QQ : 908323461
淘宝:emotacer
邮件:emotacer@163.com
====================================*/



#include  #reg52.h#  //将#换为<>号
#include  #intrins.h#


#define uchar unsigned char
/*端口定义*/
#define LED P0     /*实际温度值输出端口定义*/ 


#define NOP _nop_()



sbit  tem_in=P3^0;    /*温度读取端口*/



uchar temp_h,temp_l;   /*温度值变量*/
uchar flag1;     /*正负标志位*/
uchar code ledcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};/*数码显示数据:0,1,2,3,4,5,6,7,8,9*/
uchar code ledbit[]={0xfe,0xfd,0xfb};//共阴led
uchar dispbuf[2]={0,0};


/*====================================
函数功能:延时 
入口参数:
 说  明 :送1迟202us
=====================================*/


void delay(unsigned int count)
{
 unsigned int i;
 while(count)
 {
  i=200;
  while(i>0)i--;
  count--;
 }
}


/*====================================
函数功能:延时 us
入口参数:
 说  明 :
=====================================*/


void Delay_us(uchar n)
{
 uchar i;
 i=0;
 while(i {i++;}
 return;
}


/*====================================
函数功能:DS18B20重设
入口参数:无
 说  明 :
=====================================*/


void dsreset(void)
{
 unsigned int i;
 tem_in=0;
 i=103;
 while(i>0)i--;
 tem_in=1;
 i=4;
 while(i>0)i--;
}


/*====================================
函数功能:直接读一字节程序
入口参数:无
 说  明 :返回结果
=====================================*/


uchar ReadByte(void){
 uchar i,k;
 i=8;
 k=0;
 while(i--)
 { 
  tem_in=1;
  Delay_us(1);
  tem_in=0;
  k=k>>1;
  tem_in=1;
  NOP;
  if(tem_in)k |= 0x80;
  Delay_us(4);
 }
 return(k);
}


/*====================================
函数功能:向B20写一字节
入口参数:待写数据
 说  明 :
=====================================*/


void tmpwrite(unsigned char dat)
{ unsigned int i;
 unsigned char j;
 bit testb;
 for(j=1;j<=8;j++)
 { testb=dat&0x01;
  dat=dat>>1;
  if(testb)
  { tem_in=0;i++;i++;
   tem_in=1;
   i=8;while(i>0)i--;
  }
  else
  {
   tem_in=0;
   i=8;while(i>0)i--;
   tem_in=1;i++;i++;
  }
 }
}


//////////////////////////////////////////////////////////////
void tmpchange(void)   
{
 dsreset();      /*复位*/
 delay(1);
 tmpwrite(0xcc);     //跳过序列号命令
 tmpwrite(0x44);     //转换命令
}


/////////////////////////////////////////////////////////


/*====================================
函数功能:将温度值读出来并转化为显示数组
入口参数:
 说  明 :调用 ReadByte();
=====================================*/


void tmp(void)

 float dis;
// uchar tempbuf;
 dsreset();
 delay(1);
 tmpwrite(0xcc);
 tmpwrite(0xbe);
 temp_l=ReadByte();    //低位在前
 temp_h=ReadByte();    //高位在后
 
 flag1=temp_h&0xf8;
 if(flag1)
 {
  temp_h=~temp_h;
  if(temp_l==0)temp_h++;  //若低8位全为0且温度为负,取补时就要向高位进1
  temp_l=~temp_l+1; 
 }
 dis=(temp_h*256+temp_l)/16;


// dis=25.34;      //调试用


 if(dis<10)
 {
  dispbuf[0]=0;
  dispbuf[1]=(uchar)dis;
 }
 else
 {
  dispbuf[0]=(uchar)dis/10;
  dispbuf[1]=(uchar)dis%10;
 }
// dispbuf[2]=(uchar)(dis*10)%10;
// dispbuf[3]=(uchar)dis*100%10;
}



/*====================================
函数功能:将显示数组里的数显示
入口参数:无
 说  明 :本例中只显示一片DS18B20中的温度
=====================================*/


void dis(void)
{
 uchar i;
  for(i=0;i<2;i++)                  /*输送显示数据*/    
  { 
   LED=0xff;        //去段码
   P2 = ledbit;       //LED位选能
   delay(3);


//   if((i==0)&&(dispbuf[0]==0))
//    LED=0x00;       /*去掉最前面的0,更符合阅读习惯*/
             /*保证有效数可靠显示,使其符合习惯*/ 
//
       LED=ledcode[dispbuf];    //送段码
  }  
  delay(5);
}


/*====================================
函数功能:主函数 将温度从DS18B20读出来并且显示
入口参数:
 说  明 :
=====================================*/


main()
{
 LED=0xff;
 P2=0x00;
 do{
  tmpchange();     /*启动温度转换*/
  delay(10);      /*等待转换结束,可不用,会对显示产生影响*/
  tmp();       /*读取温度转换结果*/
                 
  dis();       /*温度显示和报警*/ 
 }while(1);
}


//*******************程序完***********************************//


keil工程文件:


rar


Proteus仿真文件:


rar

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
1
关闭 站长推荐上一条 /3 下一条