51单片机温度传感器ds18b20、lcd1602液晶C程序

51单片机温度传感器ds18b20、lcd1602液晶C程序,第1张

/*

必要 *** 作:连接传感器DS18B20到U6

*/

#pragma db code

#include<AT89X52.H>

#include "INTRINS.H"

#define BUSY1(DQ1==0) //定义busy信号

sbit LED_0=P1^0 //定义数码管控制脚为P1口的0-3脚

sbit LED_1=P1^1

sbit LED_2=P1^2

sbit LED_3=P1^3

sbit DQ1=P3^5 //定义18B20单总线引脚

void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)//声明显示函数

void ds_reset_1(void) //声明18B20复位函数

void wr_ds18_1(char dat) //声明18B20写入函数

void time_delay(unsigned char time)//声明延时函数

int get_temp_1(void) //声明18B20读入温度函数

void delay(unsigned int x) //声明延时函数

void read_ROM(void) //声明18B20读ROM函数

int get_temp_d(void) //声明获取温度函数

void ds_init(void) //声明18B20初始化函数

void ds_getT(void) //声明18B20获得温度显示值函数

/*定义数码管段码=====0-9=====A-G=====*/

unsigned char a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}

//共阳极数码管的段码0 1 2 3 4 5 6 7 8 9 A B C D E F

/****************以下定义各种变量********************/

unsigned char ResultSignal

int ResultTemperatureLH,ResultTemperatureLL,ResultTemperatureH

unsigned char ROM[8]

unsigned char idata TMP

unsigned char idata TMP_d

unsigned char f

unsigned char rd_ds18_1()

unsigned int TemH,TemL //温度的整数部分和小数部分

unsigned int count //定义小数计算部分

void main()

{

ds_init() //18B20初始化

while(1)

{

ds_getT() //使用该函数获得温度,整数部分存储到TemH,小数部分存储到count的低8位

display((TemH/10)%10,TemH%10,((count/10)%10),(count%10))

//温度发送到数码管显示

}

}

/***************18B20初始化函数***********************/

void ds_init(void)

{

unsigned int k=0

ds_reset_1()

ds_reset_1() //reset

wr_ds18_1(0xcc) //skip rom

_nop_()

wr_ds18_1(0x7f)

ds_reset_1()

wr_ds18_1(0xcc)

_nop_()

wr_ds18_1(0x44)

for(k=0k<11000k++)

time_delay(255)

ds_reset_1()

}

void ds_getT(void)

{

wr_ds18_1(0xcc)

wr_ds18_1(0xbe)

TemH=get_temp_1()

TemL=get_temp_d()

TemH&=0x00ff

TemL&=0x00ff

count=(TemH*256+TemL)*6.25

}

/***************延时程序,单位us,大于10us*************/

void time_delay(unsigned char time)

{

time=time-10

time=time/6

while(time!=0)time--

}

/*****************************************************/

/*reset ds18b20 */

/*****************************************************/

void ds_reset_1(void)

{

unsigned char idata count=0

DQ1=0

time_delay(240)

time_delay(240)

DQ1=1

return

}

void check_pre_1(void)

{

while(DQ1)

while(~DQ1)

time_delay(30)

}

void read_ROM(void)

{

int n

ds_reset_1()

check_pre_1()

wr_ds18_1(0x33)

for(n=0n<8n++){ROM[n]=rd_ds18_1()}

}

/*****************************************************/

/* Read a bit from 1820 位读取 */

/*****************************************************/

bit tmrbit_1(void)

{

idata char i=0

bit dat

DQ1=0_nop_()

DQ1=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

dat = DQ1

time_delay(50)

return dat

}

/*****************************************************/

/*read a bety from ds18b20 字节读取 */

/*****************************************************/

unsigned char rd_ds18_1()

{

unsigned char idata i,j,dat=0

for(i=1i<=8i++)

{

j=tmrbit_1()

dat=(j<<(i-1))|dat

}

return dat

}

/*****************************************************/

/* write a bety from ds18b20 写字节*/

/****************************************************/

void wr_ds18_1(char dat)

{

signed char idata i=0

unsigned char idata j

bit testb

for(j=1j<=8j++)

{

testb=dat &0x01

dat = dat>>1

if(testb)

{

DQ1=0

_nop_()

_nop_()

DQ1=1

time_delay(60)

}

else

{

DQ1=0

time_delay(50)

DQ1=1

_nop_()

_nop_()

}

}

}

int get_temp_1(void)

{

unsigned char idata a=0,b=0

unsigned char idata i

EA=0

ds_reset_1()

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0x44)

while(BUSY1)

ds_reset_1()

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0xbe)

a=rd_ds18_1()

b=rd_ds18_1()

i=b /*若b为1则为负温 */

i=(i>>4)

if(i==0)

{

f=0

TMP=((a>>4)|(b<<4))

a=(a&0x0f)

if (a>8)

{

TMP=(TMP+1)

}

}

else

{

f=1

a=a>>4

b=b<<4

TMP=(a|b)

TMP=~TMP

TMP=(TMP+1)

}

EA=1

return(TMP)

}

int get_temp_d(void)

{

unsigned char idata a=0,b=0

unsigned char idata i,m

EA=0

ds_reset_1()//复位

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0x44)

while(BUSY1)

ds_reset_1()

check_pre_1()

wr_ds18_1(0xcc)

wr_ds18_1(0xbe)

a=rd_ds18_1()

b=rd_ds18_1()

i=b /*若b为1则为负温 */

i=(i>>4)

if(i==0)

{

f=0

TMP=((a>>4)|(b<<4))

a=(a&0x0f)

TMP_d=a

}

else

{

f=1

a=~a

a=(a+1)

b=~b

b=(b+1)

m=a

a=a>>4

b=b<<4

TMP=(a|b)

m=(m&0x0f)

TMP_d=m

}

EA=1

return(TMP_d)

}void delay(unsigned int x)

{

unsigned int i

for(i=0i<xi++)

}

void display(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)

{

P0=a[d1]

LED_0=0

delay(100)

LED_0=1

P0=a[d2] &0x7f

LED_1=0

delay(100)

LED_1=1

P0=a[d3]

LED_2=0

delay(100)

LED_2=1

P0=a[d4]

LED_3=0

delay(100)

LED_3=1

}

比如

while(t--)

{

_nop_()

}

t在delayus(10)中已经赋值,即t=10,_nop_()是一个空 *** 作NOP(汇编语言中),即一个机器周期,主频12Mhz中就是1um.

//这是我曾经做的一个温度控制系统,可以调节上下限温度,低于下限温度启动加热,高于上限停止加热。

//温控系统控制程序

//版本号:V1.0;2015.6.19

//温度传感器:DS18B20

//显示方式:LED

#include <reg51.h>

#define uchar unsigned char

sbit keyup=P1^0

sbit keydn=P1^1

sbit keymd=P1^2

sbit out=P3^7 //接控制继电器

sbit DQ = P3^4   //接温度传感器18B20

uchar t[2],number=0,*pt    //温度值

uchar  TempBuffer1[4]={0,0,0,0}

uchar Tmax=18,Tmin=8

uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7}

uchar dismod=0,xiaodou1=0,xiaodou2=0,currtemp

bit flag

void t0isr() interrupt 1

{

 TH0=(65536-5000)/256

 TL0=(65536-5000)%256

 switch(number)

 {

  case 0:

       P2=0x08

        P0=distab[TempBuffer1[0]]

        break

  case 1:

       P2=0x04

        P0=distab[TempBuffer1[1]]

        break

  case 2:

       P2=0x02

        P0=distab[TempBuffer1[2]]&0x7f

        break

  case 3:

       P2=0x01

        P0=distab[TempBuffer1[3]]

        break

  default:

       break

 }

 number++

 if(number>3)number=0

}

void delay_18B20(unsigned int i)

{

 while(i--)

}

/**********ds18b20初始化函数**********************/

void Init_DS18B20(void)

{

  bit x=0

 do{

  DQ=1

  delay_18B20(8)

  DQ = 0          //单片机将DQ拉低

  delay_18B20(90)//精确延时 大于 480us

  DQ = 1          //拉高总线

  delay_18B20(14)

  x=DQ            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败,继续初始化

 }while(x)

  delay_18B20(20)

}

/***********ds18b20读一个字节**************/

unsigned char ReadOneChar(void)

{

 unsigned char i=0

 unsigned char dat = 0

 for (i=8i>0i--)

  {

    DQ = 0// 给脉冲信号

    dat>>=1

    DQ = 1// 给脉冲信号

    if(DQ)

    dat|=0x80

    delay_18B20(4)

  }

  return(dat)

}

/*************ds18b20写一个字节****************/

void WriteOneChar(unsigned char dat)

{

  unsigned char i=0

  for (i=8i>0i--)

  {

   DQ = 0

   DQ = dat&0x01

    delay_18B20(5)

   DQ = 1

    dat>>=1

 }

}

/**************读取ds18b20当前温度************/

unsigned char *ReadTemperature(unsigned char rs)

{

 unsigned char tt[2]

  delay_18B20(80) 

 Init_DS18B20()

 WriteOneChar(0xCC)   //跳过读序号列号的 *** 作

 WriteOneChar(0x44) //启动温度转换

  delay_18B20(80) 

 Init_DS18B20()

 WriteOneChar(0xCC) //跳过读序号列号的 *** 作

 WriteOneChar(0xBE) //读取温度寄存器等(共可读9个寄存器)前两个就是温度

 tt[0]=ReadOneChar()  //读取温度值低位

 tt[1]=ReadOneChar()  //读取温度值高位

 return(tt)

}

void covert1(void) //将温度转换为LED显示的数据

{

   uchar x=0x00,y=0x00

   t[0]=*pt

   pt++

   t[1]=*pt

   if(t[1]&0x080)      //判断正负温度

   {

    TempBuffer1[0]=0x0c      //c代表负

  t[1]=~t[1]    /*下面几句把负数的补码*/

  t[0]=~t[0]   /*换算成绝对值*********/

  x=t[0]+1

  t[0]=x

  if(x==0x00)t[1]++

   }

  else TempBuffer1[0]=0x0a //A代表正

  t[1]<<=4  //将高字节左移4位

  t[1]=t[1]&0xf0

  x=t[0]     //将t[0]暂存到X,因为取小数部分还要用到它

  x>>=4     //右移4位

  x=x&0x0f     //和前面两句就是取出t[0]的高四位 

  y=t[1]|x   //将高低字节的有效值的整数部分拼成一个字节

  TempBuffer1[1]=(y%100)/10

  TempBuffer1[2]=(y%100)%10

  t[0]=t[0]&0x0f //小数部分

  TempBuffer1[3]=t[0]*10/16

  //以下程序段消去随机误检查造成的误判,只有连续12次检测到温度超出限制才切换加热装置

 if(currtemp>Tmin)xiaodou1=0

 if(y<Tmin)

  {

   xiaodou1++

   currtemp=y

   xiaodou2=0

  }

 if(xiaodou1>12)

  {

   out=0

   flag=1

   xiaodou1=0

  }

 if(currtemp<Tmax)xiaodou2=0

 if(y>Tmax)

  {

   xiaodou2++

   currtemp=y

   xiaodou1=0

  }

 if(xiaodou2>12)

  {

   out=1

   flag=0

   xiaodou2=0

  }

 out=flag

}

void convert(char tmp)

{

 uchar a

 if(tmp<0)

 {

  TempBuffer1[0]=0x0c

  a=~tmp+1

 }

 else

 {

  TempBuffer1[0]=0x0a

  a=tmp

 }

  TempBuffer1[1]=(a%100)/10

  TempBuffer1[2]=(a%100)%10

}

void keyscan( )

{

uchar keyin

 keyin=P1&0x07

 if(keyin==0x07)return

 else if(keymd==0)

  {

   dismod++

   dismod%=3

   while(keymd==0)

   switch(dismod)

   {

    case 1:

         convert(Tmax)

          TempBuffer1[3]=0x11

          break

    case 2:

         convert(Tmin)

          TempBuffer1[3]=0x12

          break

    default:

         break

   }

  }

 else if((keyup==0)&&(dismod==1))

  {

   Tmax++

   convert(Tmax)

   while(keyup==0)

  }

 else if((keydn==0)&&(dismod==1))

  {

   Tmax--

   convert(Tmax)

   while(keydn==0)

  }

 else if((keyup==0)&&(dismod==2))

  {

   Tmin++

   convert(Tmin)

   while(keyup==0)

  }

 else if((keydn==0)&&(dismod==2))

  {

   Tmin--

   convert(Tmin)

   while(keydn==0)

  }

 xiaodou1=0

 xiaodou2=0

}

main()

{

 TMOD=0x01

 TH0=(65536-5000)/256

 TL0=(65536-5000)%256

 TR0=1

 ET0=1

 EA=1

 out=1

 flag=0

 ReadTemperature(0x3f)

  delay_18B20(50000) //延时等待18B20数据稳定 

 while(1)

 {

  pt=ReadTemperature(0x7f)//读取温度,温度值存放在一个两个字节的数组中

  if(dismod==0)covert1()

  keyscan()

  delay_18B20(30000)

 }

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11126128.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-13
下一篇2023-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存