[资料分享] 电冰箱(制冷器)的设计

用心思考   2012-9-1 12:56 楼主
#include
#include
#include
#include "lcd.h"

#define uchar unsigned char
#define  uint   unsigned int
sfr DQ = 0x80;                                     //DS18B20连接在单片机的P0口
sbit LIGHT = P2^7;                                 //灯报警标志P2^7口
sbit P3_6=P3^6;                                    //引脚定义,继电器控制端         
uchar PLUS = 0x01;
uchar MINUS = 0xFE;
uchar temp1;
unsigned char xx;
bit mode=0,work=0;
int ALARM_TH = 0x32;                              //报警温度上限值,50摄氏度
int ALARM_TL = 0x00;                               //报警温度下限值,0摄氏度
int temp_minus,temp_plus,temp,xiaoshu,xiaoshu1,xiaoshu2;
int temp_value = 0;                                   //DS18B20 读出的温度值
void Temp_write(uchar wbyte);                         //写DS18B20 一个字节
void Temp_bcd(void);               
void Temp_convert(void);                              //温度转换开始命令
void delay15us(uchar n);                               //延时15us倍数的程序
int  Temp_read(void);                                //读DS18B20 一个字节
void read_temp(void);                                 //读出温度值子程序
void Temp_reset(void);                              
extern int abs(int val);                                 //温度值为零下时取绝对值
void display_temperature(void);
void send_temperature(void);
void date_time(void);
void com_initialize(void);
void delay1ms(unsigned int x);                           //函数声明
void set_adj(void);                                     //函数声明
void inc_key(void);                                    //函数声明
void dec_key(void);                                    //函数声明                             
//****************************************************************************
void delay1ms(unsigned int x)                           //delay x*1ms
{            
unsigned char j;
while((x--)!=0)
      {for(j=0;j<125;j--)
       {;}
      }
}
//*****************************************************************************按键操作子程序
//****************************************************************************
void key(void)
{
     P2=0xff;
     if(P2!=0xff)
  {delay1ms(10);
     if(P2!=0xff)
  {   
       xx=P2;
       switch(xx)
     {
      case 0xfe:{set_adj();break;}         //"MS"键按下,调用set_adj()子函数
               case 0xfd:{inc_key();break;}        //"+"键按下,调用inc_key()子函数
               case 0xfb:{dec_key();break;}        //"-"键按下,调用dec_key()子函数
               case 0xf7:{//ON_OFF=!ON_OFF;/
                 work=0;
                 temp1=10;
                          init_LCD();
                 //clear_LCD();
                 gotoxy(1,1);                   //设置显示位置
                          display_LCD_string("Init_T:  ");  //显示初使温度
                          display_LCD_number(10);               
                 write_LCD_data(223);
                          display_LCD_string("C");
                 break;
                        }
      default:break;
     }
   }  
       }
}
//*****************************************************************************void set_adj(void)                                          //模式设置子函数
{  mode=!mode;
   delay1ms(5000);
   if(mode==0)
      {P3_6=0; //启动制冷
       init_LCD();
    gotoxy(1,1);
       display_LCD_string("Pre_temp:");   
    display_LCD_number(temp1);
       write_LCD_data(223);
       display_LCD_string("C");
       delay1ms(5000);
   }
  if(mode==1)
   {init_LCD();
       gotoxy(1,1);
       display_LCD_string("Please Set:");
       delay1ms(5000);      
   }
}
//****************************************************************************
void inc_key(void)                                          //按键加法子函数
{
   if(mode==1)
   {temp1++;
    init_LCD();
    gotoxy(1,1);
    display_LCD_string("Set_T:   ");   
display_LCD_number(temp1);
    write_LCD_data(223);
    display_LCD_string("C");
   delay1ms(9000);
   }
}
//****************************************************************************
void dec_key(void)                                          //按键减法子函数
{
    if(mode==1)
      {temp1--;
    init_LCD();
    //clear_LCD();
       gotoxy(1,1);
       display_LCD_string("Set_T:   ");   
    display_LCD_number(temp1);
       write_LCD_data(223);
       display_LCD_string("C");
    delay1ms(9000);
      }
  
}
//****************************************************************************
void delay15us(uchar n)            
{
  do
  { _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    --n;
  }while(n);
  return;
}
//****************************************************************************
*温度检测子程序
//****************************************************************************
void Temp_reset(void)
{
    uchar i;
bit flag = 0;                                      //flag为初始化完成(1)标志
  while(~flag)
  {
    DQ = MINUS;                                   //主机拉低单线480us
    delay15us(40);                                   //产生复位脉冲
    DQ = PLUS;                                     //上拉电阻拉高单线60us
    delay15us(4);                                     //延时60us
    while(DQ & PLUS)                               //等待DS18B20应答,拉低总线
    ;
    while(~(DQ | MINUS))                            //DQ线被拉低以产生应答信号
    {
      flag = 1;                                      //初始化完成
   for(i = 0; i < 25; ++i)                            //延时200us
         {;}
      break;                                       //完成复位操作
}
  }
  DQ = PLUS;   
  return;
}
//****************************************************************************                                                                        
*完成二进制到BCD码的转换                                                                 
//****************************************************************************
void Temp_bcd(void)            
{
  temp_plus = temp_value;
  if(temp_plus & 0xf800)                               //温度值为负,求其补码
    { gotoxy(2,7);     //温度为负时,因最大可测量零下55摄氏度即百位可用来显示负号  
      display_LCD_string('-');
      temp_minus = abs((int) temp_plus);                  //温度的绝对值
                                                  //求出小数位的值
   xiaoshu1 = (temp_minus & 0x000f)*10/16;            //小数第一位
   xiaoshu2 = (temp_minus & 0x000f)*100/16%10;        //小数第二位
      xiaoshu=xiaoshu1*10+xiaoshu2;
      temp_minus >>= 4;                                //余下整数值
      temp_value=temp_minus;
      if(temp_minus >= ALARM_TH || temp_minus < ALARM_TL )  
//温度高于ALARM_TH,或者低于ALARM_TL即报警
             { LIGHT = 1; }                              //报警,正常显示温度
      else   { LIGHT = 0; }                               //不报警,正常显示温度
    }
  else                 //温度为正时,百位可用来显示百位的数值
    {                                                  //求出小数位的值
      xiaoshu1 = (temp_plus & 0x000f)*10/16;                //小数第一位
   xiaoshu2 = (temp_plus & 0x000f)*100/16%10;           //小数第二位
      xiaoshu=xiaoshu1*10+xiaoshu2;
      temp_plus >>= 4;                                  //余下整数值
      temp_value=temp_plus;
      if(temp_plus >= ALARM_TH || temp_plus < ALARM_TL )   
//温度高于ALARM_TH,或者低于ALARM_TL即报警
             {LIGHT = 1;   }                           //报警,正常显示温度   
      else   {LIGHT = 0;   }                           //不报警,正常显示温度
    }
  temp=temp_value;
  return;
}
//****************************************************************************
void Temp_convert(void)
{
  Temp_reset();                                        //复位DS18B20
  Temp_write(0xcc); //跳过读64位ROM序列号命令,用于单线接系统 [Skip ROM] [CCH]
  Temp_write(0x44);     //启动DS18B20进行温度转换 [Convert T] [44H]
  return;
}
//*****************************************************************************int Temp_read(void)
{
  uchar i,j,rbyte;
  rbyte = 0;
  for(i = 0; i < 8; ++i)
  { DQ = MINUS;                                     //DQ保持低电平2us
_nop_();_nop_();
DQ = PLUS;  
//将DQ拉高15us以上。P1口在作为输入时必须先写"1",截止场效应管
delay15us(1);
j = (DQ & PLUS);
    delay15us(4);                                      //读时隙不低于60us
rbyte = (j << 7) | (rbyte >> 1);     //每读一位,即右移一位,将新读的位放入最高位
  }
    _nop_();                                          //读时隙间隔至少1us
    return(rbyte);
}
/*****************************************************************************
void read_temp(void)
{
  uchar temp_lsb,temp_msb;
  Temp_reset();                                        //复位DS18B20
  Temp_write(0xcc); //跳过读64位ROM序列号命令,用于单线接系统 [Skip ROM] [CCH]
  Temp_write(0xbe);                            //读暂存器 [Read Scratchpad] [BEH]
  temp_lsb = Temp_read();                              //读出低字节
  temp_msb = Temp_read();                             //读出高字节
  temp_value = (((uint)temp_msb) << 8) + temp_lsb;     //计算(256*高字节+低字节)
  return;
}
//****************************************************************************
void Temp_write(uchar wbyte)
{
    uchar i;
  for(i = 0; i < 8; ++i)
    {
      DQ = MINUS;
      DQ = wbyte & 0x01;
    delay15us(6);                          //写时隙延时90us [Write Time Slots]
      DQ = PLUS;                                 //拉高总线
     wbyte >>= 1;         //取下一位(由低位到高位),每写入一位,把字节右移一位
  _nop_();                                     //每写一位最少间隔1us
    }
  return;
}
//****************************************************************************
*温度显示子函数
//****************************************************************************
void display_temperature()
   { gotoxy(2,0);
     display_LCD_string("Temper:");  
     gotoxy(2,7);
     display_LCD_number(temp_value);                  //LCD显示温度
     display_LCD_string(".");
     display_LCD_number(xiaoshu);                     //LCD显示温度
     write_LCD_data(223);
     display_LCD_string("C");
   }
//****************************************************************************
*主函数
//****************************************************************************
void main(void)
{ P3=0x0FF;
  LIGHT = 0;                                          //默认不报警,不亮  
  PLUS = 0x01;
  MINUS = 0xFE;
  init_LCD();
  //clear_LCD();
  gotoxy(1,2);
  display_LCD_string("**Hello**");                    //欢迎信息显示
  while(1)
  {
     Temp_convert();                                  //发转换命令
     read_temp();                                     //读温度
     Temp_bcd();                                     //温度值转换
   display_temperature();
  key();
     if(temp_value<=temp1)
     {P3_6=1;//关闭制冷
   init_LCD();
      gotoxy(1,1);
         display_LCD_string("Pre_temp OK!!");
         work=1;
  }
  if(work==1)
    {if(temp_value>temp1)
        {P3_6=0;                                      //开启制冷
         init_LCD();
         gotoxy(1,1);
            display_LCD_string("Pre_temp:");   
         display_LCD_number(temp1);
            write_LCD_data(223);
            display_LCD_string("C");
            delay1ms(5000);   
         work=0;}
    }
  }
}
(3)显示子程序
#include
#include
char code int2charLCD[]="0123456789";
void write_LCD_command(unsigned command)       //将命令写入LCM模块
{
rw=WRITE;
rs=COMMAND;
enable=ENABLE;
P1=command;
delay1ms(2);
enable=DISABLE;
rw=1;
}
void write_LCD_data(unsigned LCDdata)           //将数据写入LCM模块
{
rw=WRITE;
rs=DATA;
enable=ENABLE;
P1=LCDdata;
delay1ms(2);
enable=DISABLE;
rw=1;
}
void init_LCD(void)                          //对LCM模块进行初始化
{
write_LCD_command(TwoLine_8bit);          // 0x38   
write_LCD_command(CURSOR_OFF);           // 0x0C
write_LCD_command(CURSOR_RIGHT);          // 0x06
}
void clear_LCD()                             //清除LCM的显示屏
{
write_LCD_command(CLEAR);               // Ox01,清屏
write_LCD_command(CURSOR_HOME);           // ox02,光标返回原点
}
void display_LCD_string(char *p)             //对LCM模块显示字符串
{
while(*p)
{
  write_LCD_data(*p);
  p++;
}
}
void display_LCD_number(char number)         //对LCM模块显示数字
{
unsigned char x,y;
x=number/10;
y=number%10;
write_LCD_data(int2charLCD[x]);
write_LCD_data(int2charLCD[y]);
}
void gotoxy(unsigned x,unsigned y)        //设置光标位置
{
if(x==1)  
  write_LCD_command(GOTO_LINE_1+y);
else
     write_LCD_command(GOTO_LINE_2+y);
}

回复评论 (1)

shop33392572.taobao.com
点赞  2012-10-16 13:16
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复