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

📄 温控开关.c

📁 这些是自己大学里认为非常宝贵的AVR程序
💻 C
字号:
/*****************************************************************************
程 序 名:51AVR实验板配套程序 - 18B20温控开关
开发环境:Keil
编 写 者:www.01mcu.net
功能简述:读取DS18B20测得的温度,转换并显示到数码管上,
          同时根据设定值来控制继电器的吸合与释放
硬件说明:将选购的 DS18B20 装到实验板的 U4 插座上,方向是平面朝向自己:G O V
          晶体为12MHz
其它说明:本实验牵扯到 18B20 的相关知识,请参阅本目录下18B20的器件手册
完成日期:2008.06.22
******************************************************************************/

#include <reg51.h>
 
//定义位操作
sbit DQ=P3^7;      //18B20数据端
sbit ls1=P0^2;     //个位公共极 
sbit ls2=P0^3;     //十位公共极
sbit ls3=P0^4;     //百位公共极
sbit ls4=P0^5;     //千位公共极

sbit J=P2^6;       //继电器 ,

#define Out P1     //数据输出端
unsigned char ALLTEMP;           //温度
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //共阳
               //显示 0    1    2    3    4    5    6    7    8    9    空   -   
               //序号 0    1    2    3    4    5    6    7    8    9    a    b 
unsigned char Disbuf[]={0,0,0,0};  //显示缓存               
//------------------------------------------------------------------------
//延时
delay(unsigned int t)
{
 while(t--);
}
//显示----------------------------
void Display() 
{
 unsigned char j;
 for(j=0;j<30;j++)
  {
     Out=tab[Disbuf[0]];      //要显示的数据第一位
     ls4=0;
     delay(300);
     ls4=1;
     Out=tab[Disbuf[1]];    //要显示的数据第二位
     ls3=0;
     delay(300);
     ls3=1;
         
     Out=tab[Disbuf[2]];    //要显示的数据第三位
     ls2=0;
     delay(300);
     ls2=1;
     
     Out=tab[Disbuf[3]];    //要显示的数据第四位
     ls1=0;
     delay(300);
     ls1=1;
  }
}
//---将 DS18B20 采集到的温度转换显示到数码管上 -----------
void conv(void)  
{
  unsigned char bdata p;
  unsigned char tem1,tem2,tem3;
  p=ALLTEMP;
  p=p&0x80;
  p>>=7;
  if(p==1)   //判断+-温度
      {
       Disbuf[0]=0x0b;  //显示“-”号
       ALLTEMP=~ALLTEMP;      //取补码
       ALLTEMP++;
       tem2=ALLTEMP/10;
       tem3=ALLTEMP%10;
       Disbuf[1]=0x0a;  //负温度本位不显示
       Disbuf[2]=tem2;
         if (Disbuf[2]==0) Disbuf[2]=0x0a;    //高位0不显示
       Disbuf[3]=tem3;
        
      }
  else{
       tem1=ALLTEMP/100;
       tem2=(ALLTEMP-tem1*100)/10;
       tem3=ALLTEMP-tem1*100-tem2*10;
       Disbuf[0]=0x0a;  //不显示
       Disbuf[1]=tem1; 
       Disbuf[2]=tem2; 
       Disbuf[3]=tem3;
         if(Disbuf[1]==0)
           {Disbuf[1]=0x0a;                    //高位0不显示
            if(Disbuf[2]==0) Disbuf[2]=0x0a;   //高位0不显示
           }
      }
}
//*************************************************
//复位 
unsigned char ow_reset(void)
{
  unsigned char p;
  DQ=0;          // 拉DQ线为低
  delay(29);     // 等待480nS
  DQ=1;          // DQ返回高
  delay(3);      // 等待
  p=DQ;          // 获得信号
  delay(25);     // 等待结束时间片
  return(p); 
}  // 0=找到器件, 1 = 无器件
//从 1-wire 总线上读取一个字节
unsigned char read_byte(void)
{
  unsigned char i;
  unsigned char value = 0;
  for (i=8;i>0;i--)
  {
    value>>=1;
    DQ = 0;       //拉低 DQ 
    DQ = 1;       //返回高
    DQ = 1;  
    if(DQ)value|=0x80;
    delay(6);     // 等待读时间片
  }
  return(value);
}
//向 1-WIRE 总线上写一个字节
void write_byte(char val)
{
  unsigned char i;
  for (i=8;i>0;i--) // 写1字节
  {
    DQ = 0;         // 拉低 DQ
    DQ = val&0x01;
    delay(2);       // 等待
    DQ = 1;
    val=val/2;
  }
  delay(5);
}
//读取温度
char Read_Temperature(void)
{
  union{
    unsigned char c[2];
    unsigned int x;
       }temp;            //定义一个联合数据类型,便于数据处理
  ow_reset();
  write_byte(0xCC);      // 此命令执行后的存储器操作将针对在线的所有DS1820
  write_byte(0xBE);      // 从高速暂存器读9bits温度值和CRC值
  temp.c[1]=read_byte();
  temp.c[0]=read_byte();
  ow_reset();
  write_byte(0xCC);      //跳过 ROM
  write_byte(0x44);      //转换温度
  return temp.x/16;      //保留整度,显示前要转换其特殊格式!
}
main()
{
 unsigned char i;
 unsigned char T=32;     //比较温度,你可以自行修改到你认为合适的温度控制点
 J=0;       //先关闭继电器
 conv();
 while(1)
  {
    Display();
    if(i>2)    //由于18B20转换速度限制读取温度不能太快,一般要隔2秒读取一次
      {        //这里采用显示2次后读一次数据
       ALLTEMP=Read_Temperature();  //读温度
       conv();                      //转换
       i=0;
      }
    i++;
    //判断控制继电器
    if(ALLTEMP<127)   //不处理负温度
      {
       if(ALLTEMP>T) J=1; // 高于设定,吸合继电器,温控时可作为加热开
       if(ALLTEMP<T) J=0; // 低于设定,释放继电器,温控时可作为加热关
      }
  }
}

⌨️ 快捷键说明

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