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

📄 ds18b20_pwm.c

📁 数字温度PWM控制仪
💻 C
字号:
#include<reg51.h>
#include "intrins.h"


#define uchar unsigned char
#define uint unsigned int
void keyscan();
void delay20ms(void);


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

unsigned char code str1[]={"D/C:  % T:  3S  "};
unsigned char code str2[]={"t      C Set:50C"}; 


uchar data disdata[5];
uint tvalue;//温度值
uchar tflag;//温度正负标志
//uint  Tset=60; //设置周期

sbit  Light = P2^3;   //控制LED显示
sbit  key  = P1^0;      //调整设置温度加
sbit  key2 = P1^1;      //调整设置温度减
sbit  key3 = P1^2;      //调整周期加,步进20
sbit  key4 = P1^3;      //调整周期减,步进20
int SetTemp=50;      //温度初始值
unsigned long int Tset=60; //设置周期 
int temp=0;                           //温度中间变量
uint count1=0;                    

unsigned long int count=0;  //计数器




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

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

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

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


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

  init_play()//初始化显示
  { lcd_init();
    Write_Com(0x80);
	 display(str1);
	 Write_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位小数
  temp=tvalue/10;
	return(tvalue);
  }

/*******************************************************************/
   void ds1820disp()//温度值显示
	{ uchar flagdat;
	  
	  disdata[0]=tvalue/1000+0x30;//百位数
     disdata[1]=tvalue%1000/100+0x30;//十位数
     disdata[2]=tvalue%100/10+0x30;//个位数
     disdata[3]=tvalue%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也不显示
		  }
		}
       
	   Write_Com(0x8a);
	   Write_Dat(Tset/2000+0x30);//显示周期百位 Tset/20/100+0x30 
     
       Write_Com(0x8b);
	   Write_Dat(Tset/200%10+0x30);//显示周期十位  Tset/20/10%10+0x30

	   Write_Com(0x8c);
	   Write_Dat(Tset/20%10+0x30);//显示周期个位   Tset/20%10+0x30
        
       Write_Com(0xc1);
	   Write_Dat(flagdat);//显示符号位
	   Write_Com(0xc2);
	   Write_Dat(disdata[0]);//显示百位
	   Write_Com(0xc3);
	   Write_Dat(disdata[1]);//显示十位 	
	   Write_Com(0xc4);
	   Write_Dat(disdata[2]);//显示个位 	
	   Write_Com(0xc5);
	   Write_Dat(0x2e);//显示小数点 	
	   Write_Com(0xc6);
	   Write_Dat(disdata[3]);//显示小数位
      
    
       Write_Com(0xcd);
       Write_Dat(SetTemp/10+0x30);  //显示设置温度十位
       Write_Com(0xce);  
       Write_Dat(SetTemp%10+0x30);  //显示设置温度各位
	   Write_Com(0xcf);  
       Write_Dat('C');

       
   }


void TO_Service (void) interrupt 1 using 3
	{ 	
		 TH0 = 0x3C;
         TL0 = 0x0B0;
		if(count==Tset) {count = 0;}
		count++;
		if(count<=Tset/20*(SetTemp-temp)) Light=1;
		else Light=0;


    }
void initTO(void)
    {
	   TMOD=0X11;
	   EA=1;
	   ET0=0;
	   TH0 = 0x3C;
       TL0 = 0x0B0;
       TH1 = 0x3C;
       TL1 = 0x0B0;
       ET1 = 1;
       TR1 = 1;
       TR0=0;
		
	}



void Timer1Interrupt(void) interrupt 3
{
    TH1 = 0x3C;
    TL1 = 0x0B0;
    if(count1==10) {count1=0;read_temp();}  //0.5S读一次温度
    count1++;  
  // keyscan();
    
    
}

void delay20ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=215;b>0;b--)
        for(a=45;a>0;a--);
    _nop_;  //if Keil,require use intrins.h
    _nop_;  //if Keil,require use intrins.h
}
void keyscan()
	{
 		if(key==0||key2==0||key3==0) 
			delay20ms();
               {
    			if(key==0)
					{SetTemp++; 
						ds1820disp();
                           if(SetTemp==100)  SetTemp=0;
                     }
                 if(key2==0)
    				 {SetTemp--;
   						ds1820disp();	
  							if(SetTemp==-1)   SetTemp=99;

                     }
				  if(key3==0)
					 {
                       Tset+=20;count=0;//count必须清零,否则中断里的count不知道加到多少,造成紊乱
						ds1820disp();
								if(Tset==20000) Tset=20;                      
					  }	
				   if(key4==0)
					 { 
					  if(Tset==20) Tset=20000;	
                       Tset-=20;count=0;//count必须清零,否则中断里的count不知道加到多少,造成紊乱
						ds1820disp();
 						
								                      
					  }		
                }
 }

/********************主程序***********************************/
 void main()
 { init_play();//初始化显示
   
   initTO();   //TO初始化
   while(1)
	{ keyscan();
      ds1820disp();//显示
     if((SetTemp-20)>0){
						 if(temp>=SetTemp) {ET0=0;Light=0;
											Write_Com(0x84);Write_Dat('0');
											Write_Com(0x85);Write_Dat('0');
											Write_Com(0x86);Write_Dat('*');
											} //如果温度值大于等于50度,灯灭
						 if(temp>=(SetTemp-20)&&temp<SetTemp) {TR0=1;ET0=1;
																Write_Com(0x84);Write_Dat(((SetTemp-temp)*100/20)/10+0x30);
																Write_Com(0x85);Write_Dat(((SetTemp-temp)*100/20)%10+0x30);
																Write_Com(0x86);Write_Dat('%');} //如果温度值在30和50度之间,开中断,输出PWM波,显示占空比
						 if(temp<SetTemp-20) {ET0=0;Light=1;
											  Write_Com(0x84);Write_Dat('0');
											  Write_Com(0x85);Write_Dat('1');
											  Write_Com(0x86);Write_Dat('*');}// 如果温度值小于30度,关中断,灯亮
	                   }
     if ((SetTemp-20)<=0){ET0=0;Light=0;
						  Write_Com(0x84);Write_Dat('0');
						  Write_Com(0x85);Write_Dat('0');
                          Write_Com(0x86);Write_Dat('*');}//如果设置温度小于当前温度,占空比显示00*
	}
  }




⌨️ 快捷键说明

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