新闻  |   论坛  |   博客  |   在线研讨会
温度控制器程序C语言
ysjabcd | 2011-03-02 21:33:44    阅读:93448   发布文章

这是我的程序,当时是为了做一个小冰箱的温控器做的,用的是51单片机,共阴数码管,P0口做段选,P1.4-1.7做位选。

#include<reg52.h>
#include<absacc.h>
#include<intrins.h>
#include<math.h>
#define uint unsigned int
#define uchar unsigned char

//相比以前的函数解决了显示不了百位,不能直接显示负号等

uchar code table[]={
 0x3f,0x06,0x5b,0x4f,
 // 0   1   2    3
 0x66,0x6d,0x7d,0x07,
 // 4   5   6    7
 0x7f,0x6f,0x40
 //8    9   -
 };
 
void display(uchar , uchar ,uchar ,uchar );
void delay_led(uint z);
void init_led();
uchar wei_3,v,wei_4,wei_5,wei_6,FWD,flag;

int shuju,a;           //得到的温度值
uchar temp[2]={0,0};  //存放DS18B20的温度寄存器值
uint value = 0;
sbit DQ=P1^0;       //数据线
sbit key=P1^1;     //被控开关
sbit key1=P3^4;    //温度加
sbit key2=P3^5;    //温度减
sbit d1=P1^2;      //设置指示灯
sbit we1=P1^4;
sbit we2=P1^5;
sbit we3=P1^6;
sbit we4=P1^7;
void ow_reset(void);
void tmstart (void);
void Read_Temperature(void);
void write_byte(char);
uint read_byte(void);
void delay_18B20(uint);

/*******主函数**********/
void main()
{
 init_led();//初始化子程序
 tmstart ();//18b20初始化
    delay_18B20(50);     /*等待转换结束*/
 while(1)
 {          
     Read_Temperature();
        delay_18B20(50);
        tmstart();
        delay_18B20(50);    /*等待转换结束*/
   if(FWD==0)   //当温度为正值时
 {
  if(shuju>a+5)//判断温度是否超过设定值若超过,则开始制冷,k=0时开始制冷
   key=0;
  if(shuju<a-5)
   key=1;   //shuju低于设定温度时,停止制冷,k=1停止制冷
 }
 if(FWD==1)    //当温度为负值时
 {
  if(abs(a)>a)
  {
   if(shuju>abs(a)+5)//数据大于设定温度,说明当前温度低,停止制冷,k=1停止制冷
    key=1;  
   if(shuju<abs(a)-5)//数据小于设定温度,说明当前温度高,开始制冷,k=0开始制冷
    key=0; 
  }
  else
      key=1; 
 }

  display(wei_3,wei_4,wei_5,wei_6);
  
 }
}
void exter0() interrupt 2
{

    flag=!flag;
// while(1);

}


/******延时函数*********/
void delay_led(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
/******led初始化函数******/
void init_led() 
{
 key=1;
    FWD=0;
    a=40;
   EA=1;//开总中断
 EX1=1;//开中断1
 IT1=1;//选择中断方式为下降沿触发

}
/********显示函数*********/
void display(uchar wei_3, uchar wei_4,uchar wei_5,uchar wei_6)
{
     wei_3=shuju/1000%100%10;
     wei_4=shuju/100%1000%100%10;
     wei_5=shuju/10%10000%1000%100%10;
     wei_6=shuju/1%100000%10000%1000%100%10;
  if (FWD==1)//此处用双等号!
  wei_3=10;
  P0=table[wei_3];
     we1=0;
  delay_led(5); 
 we1=1;
             
  P0=table[wei_4];
     we2=0;
  delay_led(5);
 we2=1;


  P0=table[wei_5]+0x80; //小数点显示+80H即可
    we3=0; 
  delay_led(5);
 we3=1;

  P0=table[wei_6];
     we4=0;
  delay_led(5);
 we4=1;
}

//========18b20程序=================*/

void delay_18B20(uint seconds)   //延时
{
     for(;seconds>0;seconds--);
}

/******************************************
          18b20程序
******************************************/
//===============复位 ===========
 void ow_reset(void)
{
    uchar presence;
    DQ = 0;          //pull DQ line low
    delay_18B20(44);       //至少480微秒, leave it low for 501us
    DQ = 1;          // allow line to return high?
    delay_18B20(3);        // wait for presence18b20 36us
    presence = DQ;   // get presence signal  // 0= DS18B20 ready, 1= busy
                     //if(!presence)P1_0=0;
    delay_18B20(12);       // wait for end of timeslot
}

//=========从总线上读取一个字节========
uint read_byte(void)
{
    uchar i;
    for (i=8;i>0;i--)
    {
        value>>=1;
        DQ = 0;                 // pull DQ low to start timeslot
        _nop_();_nop_();_nop_();_nop_();
        DQ = 1;               // then return high
        if(DQ)
        {
            value|=0x80;
        }
        delay_18B20(4);           // wait for rest of timeslot
     }
     return(value);
}

//===========向18B20写一个字节=================
void write_byte(char val)
{
    uchar i,j;
    for (i=8; i>0; i--)  // writes byte, one bit at a time
    {
        DQ = 0;         // pull DQ low to start timeslot
        j++;            /*延时4us*/
        DQ = val&0x01;
        delay_18B20(8);       // hold value for remainder of timeslot
        DQ = 1;
        j++;
        val>>=1;
     }

}
//============读取温度============
void Read_Temperature(void)
{
    uint k,i;
    int temple;            /*存放读取的温度值 将其除以16即为得到的值*/
    ow_reset();
    k++;              //延时4us
    write_byte(0xCC); //Sk_nop_();ip ROM
    k++;              //延时4us
    write_byte(0xBE); // read register
    k++;k++;          //延时8us
    temp[0]=read_byte();     //读取低字节
    temp[1]=read_byte();    //读取高字节
    i=temp[1];
    i<<=8;         /*把b放到高八位上去*/
                  /*将a放到底八位上去*/
    i=i|temp[0];
 if(flag==1)//如果按下设置键
 {
  d1=0;
  if(key1==0)//如果加温键被按下
  {
   delay_led(5);
   if(key1==0)//消抖,再次判断
   {
    a=a+10;//步长为1度
    while(!key1);//判断键盘松开
   }
  }
  if(key2==0)//如果减温键被按下
  {
   delay_led(5);
   if(key2==0)//再次判断,消抖
   {
    a=a-10;
    while(!key2);
   }
  }
  i=a*16/10;//显示当前设置的温度
 }
    else
  d1=1;
    if( i>6348)
    {
        temple=65536-i;   //如果为负温则去除其补码
        FWD=1;        /*表示温度为负数*/
    }
    else
    {
        temple=i;
  FWD=0;
              /*表示温度为正数*/
    }

    shuju=temple*10/16;
 

}

//=======初始化============
void tmstart (void)
{
    ow_reset();    //复位
    delay_18B20(1);      //延时
    write_byte(0xCC);    //跳过序列号命令,对所有器件有效
    write_byte(0x44);    //发转换命令 44H,
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
小太阳  2012-06-03 14:59:14 

ysjabcd你好 不错很好辛苦了 能把相关的电路图发给我学习一下 谢谢了 QQ邮箱:1161883661@qq.com

ysjabcd  2011-12-17 17:36:09 

呵呵,过奖了!

fellow  2011-03-03 15:42:14 

好例程,希望更多的网友看到,

推荐文章
最近访客