⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w014.c

📁 W014-多功能数字温度表(DS18B20)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
* 实验名称: 多功能数字温度表(DS18B20)                                          *
********************************************************************************
* 实验描述: 多功能数字温度表具有测温、预设温度上下限、声光报警等功能           *                               *
* 实验说明: 各功能键如下:				                                       *
*			S1      温度上下限设置及确认键 						               *
*			S2 	    温度上(下)限加1键							               *
*           S3 	    温度上(下)限减1键                                          *
*           BELL    声音报警												   *
*           D04     光报警													   * 
*           																   *
*		    温度上下限设置过程:											   *
*		    (1)按S1进入温度上限设置界面,然后按S2或S3设置温度上限值,		   *
*		       最后按S1确认,自动进入温度下限设置界面。						   *
*			(2)按S2或S3设置温度下限值,按S1确认,自动进入温度测量状态		   *
*																			   *
*		       当温度超过上下限时,会发出声光报警,并显示相关信息			   *
*******************************************************************************/

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int


sbit DQ = P3^7 ;         //定义DS18B20端口DQ 
sbit BEEP = P1^4 ;       //定义蜂鸣器端口
sbit RED_Light = P1^3 ;	 //报警灯

sbit LCD_RS = P2^3;
sbit LCD_RW = P2^4;

sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;

#define SELECT_LCD()	HC138_A=0; HC138_B=1; HC138_C=0
#define NOSELECT_LCD()	HC138_A=1; HC138_B=1; HC138_C=1

sbit S1 = P1^5 ; 	//设置键和确认键
sbit S2 = P1^6 ; 	//加1键
sbit S3 = P1^7 ; 	//减1键

bit presence  ;

uchar TH=30;	//初始温度上限值
uchar TL=25;	//初始温度下限值

uchar Keyset_Flag = 0;	//S1键扫描标志位
uchar BEEP_Flag = 0;    //蜂鸣器报警标志位

uchar code  dis_code1[ ] = {"   DS18B20 OK   "} ;
uchar code  dis_code2[ ] = {"  TEMP:    .  C "} ;
uchar code  dis_code3[ ] = {" DS18B20  ERR0R "} ;
uchar code  dis_code4[ ] = {"  PLEASE CHECK  "} ;

uchar data  temp_data[2] = {0x00,0x00} ;   //温度数据缓存
uchar data  display_TH[2] = {0x00,0x00} ;  //温度上限值十位个位
uchar data  display_TL[2] = {0x00,0x00} ;  //温度下限值十位个位

uchar data  dis_data[5] =   {0x00,0x00,0x00,0x00,0x00} ;  //温度值百十个小数位及一个数据缓存

/*温度小数部分查表*/
uchar code  ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
                         0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} ;

/*自定义字符*/
uchar code  mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ; //度的符号



/*******************************************************************/
/*                                                                 */
/* us级延时函数                                                    */
/*                                                                 */
/*******************************************************************/
void Delay(unsigned int num) 
{
  while( --num ) ;
}

/*******************************************************************/
/*                                                                 */
/* ms级延时函数                                                    */
/*                                                                 */
/*******************************************************************/
void Delayms(unsigned char ms)
{						
	unsigned char i;
	while(ms--)
	{
		for(i = 0; i < 120; i++);
	}
}

/*******************************************************************/
/*                                                                 */
/* 检测LCD的忙碌状态                                               */
/*                                                                 */
/*******************************************************************/
bit LCD_Busy()		
{							
	bit result;
	LCD_RS = 0;			    
	LCD_RW = 1;
	SELECT_LCD();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	result = (bit)(P0 & 0x80);	//检查LCD的DB7的值 1为忙 0为空闲,可写指令与数据
	NOSELECT_LCD();
	return result;	
}

/*******************************************************************/
/*                                                                 */
/* 写指令数据到LCD                                                 */
/*                                                                 */
/*******************************************************************/
LCD_WriteCommand(uchar cmd)	 
{							   
	while(LCD_Busy());
	LCD_RS = 0;
	LCD_RW = 0;
	NOSELECT_LCD();
	_nop_();
	_nop_();	
	P0 = cmd;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SELECT_LCD();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	NOSELECT_LCD();		
}

/*******************************************************************/
/*                                                                 */
/* 写显示数据到LCD                                                 */
/*                                                                 */
/*******************************************************************/
LCD_WriteDate(uchar dat)
{							
	while(LCD_Busy());
	LCD_RS = 1;
	LCD_RW = 0;
	NOSELECT_LCD();
	P0 = dat;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SELECT_LCD();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	NOSELECT_LCD();	
}

/*******************************************************************/
/*                                                                 */
/* 设定字符在LCD上显示的位置                                       */
/*                                                                 */
/*******************************************************************/
LCD_DisplayPosit(uchar pos)	   
{							
	LCD_WriteCommand(pos | 0x80);
}

/*******************************************************************/
/*                                                                 */
/* LCD初始化                                                       */
/*                                                                 */
/*******************************************************************/
LCD_Init()			
{							
	LCD_WriteCommand(0x38);	   
	Delay(5);
	LCD_WriteCommand(0x0c);	  
	Delay(5);
	LCD_WriteCommand(0x06);	   
	Delay(5);
	LCD_WriteCommand(0x01);	   
	Delay(5);
}

/*******************************************************************/
/*                                                                 */
/* 自定义字符写入CGRAM函数                                         */
/*                                                                 */
/*******************************************************************/
void  LCD_WriteMytab()  
{  
    unsigned char i ;
    LCD_WriteCommand(0x40) ;      //写CGRAM
    for (i = 0 ; i< 8 ; i++)       
    LCD_WriteDate(mytab[ i ]) ;        
}

/*******************************************************************/
/*                                                                 */
/* LCD上显示两行字符函数                                           */
/*                                                                 */
/*******************************************************************/
void LCD_DisplayLine(uchar a[ ],uchar b[ ])	
{
    uchar  m ;
    LCD_Init() ;                
            
    LCD_DisplayPosit(0) ;      //设置显示位置为第一行的第1个字符
     m = 0 ;
    while(a[m] != '\0')
     {                         //显示第一行字符
       LCD_WriteDate(a[m]) ;
       m++ ;
     }

    LCD_DisplayPosit(0x40) ;   //设置显示位置为第二行第1个字符
     m = 0 ;
    while(b[m] != '\0')
     {
       LCD_WriteDate(b[m]) ;   //显示第二行字符
       m++ ;
     } 
}

/*******************************************************************/
/*                                                                 */
/* DS18B20初始化                                                   */
/*                                                                 */
/*******************************************************************/
DS18B20_Init(void)	 
{  
     DQ = 1 ;        //DQ复位
     Delay(8) ;      //延时

     DQ = 0 ;        //将DQ拉低
     Delay(90) ;     //精确延时 大于 480us

     DQ = 1 ;        //拉高总线
     Delay(8) ;

     presence = DQ ;    //如果 presence=0则初始化成功 presence=1则初始化失败
     Delay(100) ;
     DQ = 1 ; 
     
     return(presence) ; //返回presence
}

/*******************************************************************/
/*                                                                 */
/* 读一个字节数据                                                  */
/*                                                                 */
/*******************************************************************/
ReadOneChar(void)	 
{
  unsigned char i = 0 ;
  unsigned char dat = 0 ;

  for (i = 8 ; i > 0 ; i--)
    {
      DQ = 0 ;    
      dat >>= 1 ;
      DQ = 1 ;    

      if(DQ)
        dat |= 0x80 ;
        Delay(4) ;
    }

    return (dat) ;
}

/*******************************************************************/
/*                                                                 */
/* 写一个字节数据                                                  */
/*                                                                 */
/*******************************************************************/
WriteOneChar(unsigned char dat) 
{
  unsigned char i = 0 ;
  for (i = 8 ; i > 0 ; i--)
  {
    DQ = 0 ;
    DQ = dat&0x01 ;
    Delay(5) ;

    DQ = 1 ;
    dat>>=1 ;
  }
}

/*******************************************************************/
/*                                                                 */
/* 读取温度数据                                                    */
/*                                                                 */
/*******************************************************************/
ReadTemperature(void)	 
{
     DS18B20_Init() ;
  
     WriteOneChar(0xCC) ;  //跳过读序号列号的操作
     WriteOneChar(0x44) ;  //启动温度转换

     DS18B20_Init() ;
     WriteOneChar(0xCC) ;  //跳过读序号列号的操作
     WriteOneChar(0xBE) ;  //读取温度寄存器

     temp_data[0] = ReadOneChar() ;   //读温度低8位
     temp_data[1] = ReadOneChar() ;   //读温度高8位 
}

/*******************************************************************/
/*                                                                 */
/* 温度数据转换和显示                                              */
/*                                                                 */
/*******************************************************************/
TemperatureDisplay()	
{
  dis_data[4]=temp_data[0]&0x0f ;	       //temp_data[0]低4为有效
  dis_data[3]=ditab[dis_data[4]]+0x30;     //查表得小数位的值
  
  dis_data[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
  dis_data[2]=dis_data[4]%10+0x30;		   //个位
  dis_data[1]=(dis_data[4]/10)%10+0x30;	   //十位
  dis_data[0]=dis_data[4]/100+0x30;		   //百位

    if(dis_data[0]==0x30)        //百位为0,不显示
   { 
     dis_data[0]=0x20;
	               
     if(dis_data[1]==0x30)       //十位为0,不显示
       dis_data[1]=0x20 ;
   }

     LCD_DisplayPosit(0x48) ;             
     LCD_WriteDate(dis_data[0]) ;        //百位数显示 
     LCD_DisplayPosit(0x49) ;             
     LCD_WriteDate(dis_data[1]) ;        //十位数显示 
     LCD_DisplayPosit(0x4a) ;             
     LCD_WriteDate(dis_data[2]) ;        //个位数显示 
     LCD_DisplayPosit(0x4c) ;             
     LCD_WriteDate(dis_data[3]) ;        //小数位数显示
	 LCD_WriteMytab() ;                  //自定义字符(度的符号)写入CGRAM
     Delay(5) ;
     LCD_DisplayPosit(0x4d) ;
     LCD_WriteDate(0x00) ;               //显示自定义字符(度的符号)

}

/*******************************************************************/
/*                                                                 */
/* DS18B20 OK 界面显示                                             */
/*                                                                 */
/*******************************************************************/
void  DS18B20_OkMenu ()	  
{ 
     LCD_DisplayLine(dis_code1,dis_code2); 
}

/*******************************************************************/
/*                                                                 */
/* DS18B20 ERROR 界面显示                                          */
/*                                                                 */
/*******************************************************************/
void  DS18B20_ErrorMenu () 
{
     LCD_DisplayLine(dis_code3,dis_code4);
}


/*******************************************************************/
/*                                                                 */
/* 蜂鸣器响一声                                                    */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -