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

📄 main.c

📁 基于单片机89C51的程序温控系统
💻 C
字号:
#include <AT89X52.H>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define uchar unsigned char
#define uint unsigned int

sfr  p3=0xb0;
sbit p3_5=p3^5;
sbit p3_4=p3^4;

sbit DQ=P1^5;//ds18b20与单片机连接口
sbit RS=P1^2;
sbit RW=P1^1;
sbit EN=P1^0;

/****继电器部分控制***********************************/
sbit LED_RED=P2^6;
sbit LED_BLUE=P2^7;
sbit Relay_add=P2^0;


//// /////////////////////////////////////////////////////
bit K1,K2,K3,k4,k5;
bit KT;
bit flash;
unsigned char set=0,xiaoshi=0,fenzhong=0,wendu=0;//定时与调温变量   
uchar ms50,second,minite,hour=12; 
uchar temp;

void Init_T0(void);
void FlashKey(void);
void Add(void);
void Init_Clock(void);
void Refresh(void);


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

unsigned char code str1[]={"M:  :   T:   . "};
unsigned char code str2[]={"S:  :   st:  . "};

unsigned char code str3[]={"I love you HJ!"};
unsigned char code str4[]={"Made by hu jiao"};

uchar data disdata[8];
uint tvalue;//温度值
uchar tflag;//温度正负标志
 
/////////////////////////////////
uchar data inputdata[8];
///////////////////////////////////////

/*************************lcd1602程序**************************/
void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
{unsigned int i,j;
   for(i=0;i<ms;i++)
    for(j=0;j<120;j++);
}

void wr_com(unsigned char com)//写指令//
{ delay1ms(1);
   RS=0;
   RW=0;
   EN=0;
   P0=com;                                                         //////////////////////******************DAT
   delay1ms(1);
   EN=1;
   delay1ms(1);     	 	
   EN=0;
}

void wr_dat(unsigned char dat)//写数据//
{ delay1ms(1);;
   RS=1;
   RW=0;
   EN=0;
   P0=dat;                                                        /////////////////////////******************DAT
   delay1ms(1);
   EN=1;
   delay1ms(1);
   EN=0;
}

void lcd_init()//初始化设置//
{delay1ms(15);
  wr_com(0x38);delay1ms(5);
   wr_com(0x08);delay1ms(5);
    wr_com(0x01);delay1ms(5);
     wr_com(0x06);delay1ms(5);
      wr_com(0x0c);delay1ms(5);
}




void display(unsigned char *p)//显示//
{
while(*p!='\0')
{
 wr_dat(*p);
 p++;
 delay1ms(1);
}
}

init_play()//初始化显示
{   lcd_init();
    wr_com(0x80);
    display(str1);
    wr_com(0xc0);
    display(str2);
   }

/******************************ds1820程序***************************************/
void delay_18B20(unsigned int i)//延时1微秒
{
   while(i--);
}


void ds1820rst()/*ds1820复位*/
{ unsigned char x=0;
DQ = 1;          //DQ复位
delay_18B20(4); //延时
DQ = 0;          //DQ拉低
delay_18B20(100); //精确延时大于480us
DQ = 1;          //拉高
delay_18B20(40); 
 } 


uchar ds1820rd()/*读数据*/
{ 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_18B20(10);
  }
   return(dat);
}


void ds1820wr(uchar wdata)/*写数据*/
{
  unsigned char i=0;
    for (i=8; i>0; i--)
    { DQ = 0;
      DQ = wdata&0x01;
      delay_18B20(10);
      DQ = 1;
      wdata>>=1;
    }
}



read_temp()/*读取温度值并转换*/
{
   uchar a,b;
   ds1820rst();    
   ds1820wr(0xcc);//*跳过读序列号*/
   ds1820wr(0x44);//*启动温度转换*/
   ds1820rst();    
   ds1820wr(0xcc);//*跳过读序列号*/ 
   ds1820wr(0xbe);//*读取温度*/ 
   a=ds1820rd();
   b=ds1820rd();
   tvalue=b;
   tvalue<<=8;
   tvalue=tvalue|a;
   if(tvalue<0x0fff)
      tflag=0;
   else
     {tvalue=~tvalue+1;
      tflag=1;}

   tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
   return(tvalue);
}


/*******************************************************************/
void ds1820disp1()          //温度值显示
{ 
     uchar flagdat;

	 disdata[0]=tvalue/1000  +0x30;//百位数
     disdata[1]=tvalue%1000/100  +0x30;//十位数
     disdata[2]=tvalue%100/10  +0x30;//个位数
     disdata[3]=tvalue%10  +0x30;//小数位
     
	 disdata[4]=hour/10+0x30;//小时高位
     disdata[5]=hour%10+0x30;//小时低位
     disdata[6]=minite/10+0x30;//分钟高位
     disdata[7]=minite%10+0x30;//分钟低位

  
     if(tflag==0)
       flagdat=0x20;//正温度不显示符号
     else
       flagdat=0x2d;//负温度显示负号:-

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

/*    wr_com(0x80|9);                                //第一行 第 0x80|x   列    
    wr_dat(flagdat);//显示符号位

    wr_com(0x80|10);
    wr_dat(disdata[0]);//显示  百位

    wr_com(0x80|11);
    wr_dat(disdata[1]);//显示  十位 

    wr_com(0x80|12);
    wr_dat(disdata[2]);//显示  个位 

    wr_com(0x80|13);
    wr_dat(0x2e);//显示小数点 

    wr_com(0x80|14);
    wr_dat(disdata[3]);//显示小数位 
    
    wr_com(0x80|15);
    wr_dat(0xdf);          //  du */
    wr_com(0x80|2);                //第一行 第 0x80|x   列    
    wr_dat(disdata[4]); //小时高位

    wr_com(0x80|3);
    wr_dat(disdata[5]); //小时低位

    wr_com(0x80|5);
    wr_dat(disdata[6]); //分高位

    wr_com(0x80|6);
    wr_dat(disdata[7]); //分低位

//    wr_com(0x80|9);
//    wr_dat(flagdat);//正负标志位 

    wr_com(0x80|10);
    wr_dat(disdata[0]); //百位
    
    wr_com(0x80|11);
    wr_dat(disdata[1]);  //十位 
    wr_com(0x80|12);
    wr_dat(disdata[2]);  //个位
//    wr_com(0x80|13);  
//   wr_dat(0x2e);     //小数点
    wr_com(0x80|14);
    wr_dat(disdata[3]);//显示小数位
    wr_com(0x80|15);
    wr_dat(0xdf);       //  du */
}

/////////////////////////////////////////////////////////// 
void ds1820disp2()               //温度值显示      
{    
	/****************时间设定值**************/

	 inputdata[4]=xiaoshi/10+0x30;
     inputdata[5]=xiaoshi%10+0x30;
     inputdata[6]=fenzhong/10+0x30;
     inputdata[7]=fenzhong%10+0x30;

     /**************温度设定值***************/

     inputdata[0]=0  +0x30;
     inputdata[1]=wendu/10 +0x30;
     inputdata[2]=wendu%10 +0x30;
     inputdata[3]=0 +0x30;    //小数位
     

      if(inputdata[0]==0x30)
      {
       inputdata[0]=0x20;//如果百位为0,不显示
       if(disdata[1]==0x30)
        {disdata[1]=0x20;//如果百位为0,十位为0也不显示
         }
      }

    wr_com(0x80|(2-0x40));                       //第二行 第  0x80|(x-0x40)    列                
    wr_dat(inputdata[4]);
 
    wr_com(0x80|(3-0x40));                       //第二行 第  0x80|(x-0x40)    列                
    wr_dat(inputdata[5]);

    wr_com(0x80|(5-0x40));                                      
    wr_dat(inputdata[6]);

    wr_com(0x80|(6-0x40));                                    
    wr_dat(inputdata[7]);



    /*******************************/
    wr_com(0x80|(11-0x40));                       //第二行 第  0x80|(x-0x40)    列                
    wr_dat(inputdata[1]);
 
    wr_com(0x80|(12-0x40));                       //第二行 第  0x80|(x-0x40)    列                
    wr_dat(inputdata[2]);

    wr_com(0x80|(14-0x40));                                      
    wr_dat(inputdata[3]);

//    wr_com(0x80|(13-0x40));                   //  dian                    
//    wr_dat(0x2e);

//    wr_com(0x80|(14-0x40));                                    
//    wr_dat(inputdata[3]);

    wr_com(0x80|(15-0x40));                  //du                              
    wr_dat(0xdf);
}

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






////////////////////////////////////////////////////
////////////////////////////////////////////////////
///// 函数名:   时间闪烁子函数               //////
///// 函数功能: 选择确定闪烁位等待调整       //////
///// 调用:     Add();                       //////
///// 函数参数: 无                           //////
///// 返回值:   无                           //////
//////////////////////////////////////////////////// 
/************************************************************/
void FlashKey(void)             //闪烁子函数//
{
 if(P3_5==0)
  {
    delay1ms(10);
    if(p3_5==0)
   {
    {
	 Refresh();
     set++;
	}
   } 
	while(!P3_5);                       
  }           
                 
 if(set==6)  set=0;                      
 if(set!=1)  K1=1;
 if(set!=2)  K2=1;
 if(set!=3)  K3=1;                      
 if(set!=4)  k4=1;
 if(set!=5)  k5=1;

 switch(set)
  {
   case 0:KT=0;break;
   case 1:K1=flash;KT=1;break;        //hms为调时临时变量,需要调整某位时则先把其初始值放到hms中//
   case 2:K2=flash;KT=1;break;
   case 3:K3=flash;KT=1;break;
   case 4:k4=flash;KT=1;break;
   case 5:k5=flash;KT=1;break;
  }
 Add();
} 

void Add(void)           
 {
  if(P3_4==0)             
   {
    delay1ms(10);
	if(p3_4==0)
   {
    Refresh();
    if(KT==1)             //检验可调标志位KT//
     {
      switch(set)
       {
        case 1:hour++;if(hour>=24)hour=0;break;           
        case 2:minite++;if(minite>=60)minite=0;break;          
        case 3:xiaoshi++;if(xiaoshi>=24)xiaoshi=0;break;          
        case 4:fenzhong++;if(fenzhong>=60)fenzhong=0;break;
        case 5:wendu++;if(wendu>=100)wendu=0;break;
         }
	   
	 disdata[4]=hour/10+0x30;//小时高位
     disdata[5]=hour%10+0x30;//小时低位
     disdata[6]=minite/10+0x30;//分钟高位
     disdata[7]=minite%10+0x30;//分钟低位

       inputdata[4] = xiaoshi/10+0x30;
       inputdata[5] = xiaoshi%10+0x30;
       inputdata[6] = fenzhong/10+0x30;
       inputdata[7] = fenzhong%10+0x30;
       inputdata[1] = wendu/10+0x30;
       inputdata[2] = wendu%10+0x30;
       inputdata[3] = 0+0x30;
     }
	} 
	 while(!P3_4);
   }
 }

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

void Refresh(void)
{
  ds1820disp1();   //显示1
  ds1820disp2();      //温度值显示 
 
}


/*-----------------------------状态判断于提示------------------------*/
void State(void)
 {
  if(KT==1)
   {
    wr_com(0x80|(7-0x40));                                              
    wr_dat(0xef); 
    
   }             
  
   else
   {wr_com(0x80|(7-0x40));                                              
    wr_dat(0x00); 
   }

}

///////////////////////////////***************************************////////kaiji hua mian
intstart()//初始化显示
{   lcd_init();
    wr_com(0x80);
    display(str3);
    wr_com(0xc0);
    display(str4);
}


///////////////////////***************************************************
/************************比较判断函数***********************/
/////////////////////////////////////
 void b_j()   
{    
   Relay_add=1;  LED_RED=1; LED_BLUE=0;      ////条件加热,降热
   temp=wendu*10;

if(((xiaoshi==hour)&&(fenzhong==minite))||temp>(tvalue+15))
 {
  Relay_add=0;   LED_RED=0;   LED_BLUE=1;
 }
 else
 {
  Relay_add=1;   LED_RED=1;   LED_BLUE=0;
 }
}
/***********************************************************/

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/********************主程序***********************************/
void main()
{  
   TMOD=0X01;
   TH0=0X3C;TL0=0XB0;
   ET0=1;TR0=1;
   EA=1;

   intstart();   //开机画面 *************************************
   delay1ms(2500);

   init_play();//初始化显示
   while(1)
    {
     read_temp();//读取温度

     ds1820disp1();   //显示1
     ds1820disp2();      //温度值显示
     
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////// 
     FlashKey();
     State();
     delay1ms(400);
     b_j();
    }  ///while


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


 
}

/****************定时中断服务子函数******************/
void TIME_INT() interrupt 1 using 1
{
 TH0=0X3C;TL0=0XB0;
 ms50++;
 if(ms50==20)
 {
  ms50=0;second++;
  if(second==60)
   {
     second=0;minite++;
     if(minite==60)
      {
        minite=0;hour++;
        if(hour==24)
        hour=0;
       }
    }
  }
}

⌨️ 快捷键说明

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