一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 4170|回复: 14
收起左侧

请教 单片机 抗干扰

  [复制链接]
发表于 2011-9-6 20:09 | 显示全部楼层 |阅读模式
一个客户的三星大冰 原机电控板坏了   售后没有(开始报价1300,等了一个月又报1600,又等了3个月告诉没有配件
了修不好了,后边是很客气的扯淡,我还是边学边做,硬件不是问题,呵呵早年学习很好的) 我做了一块 有点问题如下
只给程序加电  一切正常  今日安装上后 开关门时 显示的显示屏死机  大约等待20多秒自己还可以恢复
由于怕显示屏和板子之间连接线长受到干扰用了两个芯片  一个用于显示万年历以及温度等 另一个用于输出检测传感器温度
等  公用5V和地线 一片at89s52负责显示   一片stc89c52负责温度采集以及负载输出 DS18B20做温度传感器铜管704封装的
现在传感器温度检测正常 开关机正常 显示正常 稳定性暂时不知道;现在死机的是at89s52 另一个没见异常
现在问题是开门后在关门   显示屏死机 万年历时间停止 或者停留在门已打开的画面上    大约等待20多秒自己还可以恢复(另一个单片机压缩机等控制正常)。
在压缩机启动瞬间也会出现这个现象 但是at89s52没见异常  最担心的19264的屏也没问题
这个冰箱的门开关检测很特别 后面的电路图上可以看到,强弱电在一个开关上 和控制灯的是一个开关 ;图片在最后面,不知道是属于什么问题  ,麻烦各位老师了 先谢谢了
如果只上弱电 开关门一切正常 在1秒内都可以响应
这是用于负载输出和发送传感器数据的
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit cl=P0^0;
sbit e=P0^1;//   串行数据传输此端口上接显示单片机的外部中断0
sbit io=P0^2;//   串行数据传输接口定义
sbit lcsd=P0^3; //按键定义冷藏设定
sbit ldsd=P0^4; //按键定义冷冻设定
sbit sdsd=P0^5; //按键定义速冻设定实际为调整时间
sbit gblc=P0^6; //按键定义关闭冷藏实际为调整时间
sbit ds18_0=P2^0;
sbit ds18_1=P2^1;
sbit ds18_2=P2^2;
sbit ds18_3=P2^3; //传感器接口定义
sbit lc_dr=P1^0;
sbit ld_dr=P1^1;
sbit ysj=P1^2;
sbit lc_fj=P1^3;
sbit ld_fj=P1^4; //输出接口定义
uchar lc_hw_h;//储存冷藏环境温度高八位数值
uchar lc_hw_l;//储存冷藏环境温度低八位数值
uchar lc_gw_h;//储存冷藏管温温度高八位数值
uchar lc_gw_l;//储存冷藏管温温度低八位数值
uchar ld_hw_h;//储存冷冻环境温度高八位数值
uchar ld_hw_l;//储存冷冻环境温度低八位数值
uchar ld_gw_h;//储存冷冻管温温度高八位数值
uchar ld_gw_l;//储存冷冻环境温度低八位数值
signed char lc_sd;   //储存冷藏温度上电初始值
signed char ld_sd;   //储存冷冻温度上电初始值
signed char lc_hw;  //储存冷藏实际温度值
signed char ld_hw;  //储存冷冻实际温度值
signed char lc_gw;  //储存冷藏盘管实际温度值
signed char ld_gw;  //储存冷冻盘管实际温度值

uchar mode,time;       //用于调节屏幕时间
uchar mode_temp;      //暂时无效变量 在程序中未使用 但有占位不能删除
uint num;                     //全局精准延时变量  暂时确定用于压缩机开停机延时以及化霜时间调节
uchar ysj_yanshi,dr_time; //储存压缩机延时运转时间以及化霜时间
uint ysj_yunzhuan;
uchar fhw_lcgw,fhw_ldgw,fhw_lchw,fhw_ldhw; //保存读出的高位数据来判断正负值
bit ysj_ys;                   //此位保存压缩机状态用于压缩机延时保护
uchar wd_lcdr,wd_lddr,wd_ysj,wd_lcfj,wd_ldfj;//此值可以认为对温度值进行平均取值防止
            //传感器偶然异常引起电路误动作,修改动作阀值
uchar dr_num_1;         //可以改变动作延时时间以及抗误码率


void delay_us(uchar i) //精准延时
{
while(--i);
}
void delay_ms(uchar tt)//约1ms延时
{
uchar aa,bb;
for(aa=tt;aa>0;aa--)   for(bb=100;bb>0;bb--);
}
void exter0() interrupt 1  //精确中断定时器
{
TH0=0x4c;
TL0=0x00;    //中断后重装定时器初值
num--;
if(num<5) //定时器时间到时执行命令
{
  num=1205;//1分钟时间归零
  if(ysj_yanshi>1)
   ysj_yanshi--;  //压缩机延时运转倒计时 暂时时间为2分钟多   
  if(lc_dr|ld_dr)  
   dr_time++;   //电加热计时条件
  if(ysj)   
   ysj_yunzhuan++;  //压缩机运转时间计时条件
}
if(ysj_yunzhuan>690)
  {
   ysj_yunzhuan=0;//正常情况下此值最大为480+120为防止意外当此值超出时
   lc_dr=0;   //关闭一切负载 对此语句好像用途不大 暂时保留
   ld_dr=0;
   ysj=0;
   lc_fj=0;
   ld_fj=0;
  }
}
void fasong(uchar date1,date2,date3,date4,date5,date6,date7,date8,lc_sd,ld_sd,mode,time) //发送数据
{

uchar a,temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9,tempa,tempb,tempc;
temp1=date1;temp2=date2;temp3=date3;temp4=date4;temp5=date5;temp6=date6;temp7=date7;temp8=date8;
temp9=lc_sd;tempa=ld_sd;tempb=mode;tempc=time;
fhw_lcgw=lc_gw_h;
fhw_lchw=lc_hw_h;
fhw_ldgw=ld_gw_h;
fhw_ldhw=ld_hw_h;   //发送前保存温度高8位初始值用来判断正负温度
cl=1;io=0;e=1;e=0;delay_us(2);e=1;delay_us(200);
for(a=8;a>0;a--)
  {  cl=0;io=temp1&0x01;delay_us(200);cl=1;delay_us(200);temp1>>=1;}
delay_us(200);  
for(a=8;a>0;a--)
  { cl=0;io=temp2&0x01;delay_us(200);cl=1;delay_us(200);temp2>>=1; }
delay_us(200);
for(a=8;a>0;a--)
  { cl=0;io=temp3&0x01;delay_us(200);cl=1;delay_us(200);temp3>>=1; }
delay_us(200);         
for(a=8;a>0;a--)
  { cl=0;io=temp4&0x01;delay_us(200);cl=1;delay_us(200);temp4>>=1;}
delay_us(200);  
for(a=8;a>0;a--)
  { cl=0;io=temp5&0x01;delay_us(200);cl=1;delay_us(200);temp5>>=1;}
delay_us(200);  
for(a=8;a>0;a--)
  { cl=0;io=temp6&0x01;delay_us(200);cl=1;delay_us(200);temp6>>=1;}
delay_us(200);
for(a=8;a>0;a--)
  { cl=0;io=temp7&0x01;delay_us(200);cl=1;delay_us(200);temp7>>=1;}
delay_us(200);  
for(a=8;a>0;a--)
  { cl=0;io=temp8&0x01;delay_us(200);cl=1;delay_us(200);temp8>>=1;}
delay_us(200);
for(a=8;a>0;a--)
  {  cl=0;io=temp9&0x01;delay_us(200);cl=1;delay_us(200);temp9>>=1;}
delay_us(200);
for(a=8;a>0;a--)
  {  cl=0;io=tempa&0x01;delay_us(200);cl=1;delay_us(200);tempa>>=1;}
delay_us(200);
for(a=8;a>0;a--)
  {  cl=0;io=tempb&0x01;delay_us(200);cl=1;delay_us(200);tempb>>=1;}
delay_us(200);
for(a=8;a>0;a--)
  {  cl=0;io=tempc&0x01;delay_us(200);cl=1;delay_us(200);tempc>>=1;}
delay_us(200);


}
void ds18b20_init(void)//4个传感器全部初始化
{
  ds18_0=1;delay_us(1);ds18_0=0;delay_us(250);ds18_0=1;delay_us(30);delay_us(250);
  ds18_1=1;delay_us(1);ds18_1=0;delay_us(250);ds18_1=1;delay_us(30);delay_us(250);   
  ds18_2=1;delay_us(1);ds18_2=0;delay_us(250);ds18_2=1;delay_us(30);delay_us(250);
  ds18_3=1;delay_us(1);ds18_3=0;delay_us(250);ds18_3=1;delay_us(30);delay_us(250);
}
void write_0(uchar com)//传感器0写数据
{ uchar x;
for(x=8;x>0;x--)
{ ds18_0=0;_nop_();ds18_0=com&0x01;delay_us(15);ds18_0=1;com>>=1;delay_us(1);}
}
uchar read_0()//传感器0读数据
{ uchar x;
uchar dat;
for(x=8;x>0;x--)
{ ds18_0=0;_nop_(); dat>>=1;ds18_0=1;delay_us(1);if(ds18_0==1) dat=dat|0x80;delay_us(10);}
return (dat);
}  
void wendu_0() //读传感器0温度数据
{ ds18b20_init();write_0(0xcc);write_0(0x44);delay_ms(200);delay_ms(200);  
ds18b20_init();write_0(0xcc);write_0(0xbe);  
lc_hw_l=read_0();
lc_hw_h=read_0();  
}
void write_1(uchar com)//传感器1写数据
{ uchar x;
for(x=8;x>0;x--)
{ ds18_1=0;_nop_();ds18_1=com&0x01;delay_us(15);ds18_1=1;com>>=1;delay_us(1);}
}
uchar read_1()//传感器1读数据
{ uchar x;
uchar dat;
for(x=8;x>0;x--)
{ ds18_1=0;_nop_(); dat>>=1;ds18_1=1;delay_us(1);if(ds18_1==1) dat=dat|0x80;delay_us(10);}
return (dat);
}  
void wendu_1() //读传感器1温度数据
{ ds18b20_init();write_1(0xcc);write_1(0x44);delay_ms(200);delay_ms(200);  
ds18b20_init();write_1(0xcc);write_1(0xbe);  
ld_hw_l=read_1();
ld_hw_h=read_1();  
}
void write_2(uchar com)//传感器2写数据
{ uchar x;
for(x=8;x>0;x--)
{ ds18_2=0;_nop_();ds18_2=com&0x01;delay_us(15);ds18_2=1;com>>=1;delay_us(1);}
}
uchar read_2()  //传感器2读数据
{ uchar x;
uchar dat;
for(x=8;x>0;x--)
{ ds18_2=0;_nop_(); dat>>=1;ds18_2=1;delay_us(1);if(ds18_2==1) dat=dat|0x80;delay_us(10);}
return (dat);
}  
void wendu_2()    //读传感器2温度数据
{ ds18b20_init();write_2(0xcc);write_2(0x44);delay_ms(200);delay_ms(200);  
ds18b20_init();write_2(0xcc);write_2(0xbe);  
lc_gw_l=read_2();
lc_gw_h=read_2();
}
void write_3(uchar com)  //传感器3写数据
{ uchar x;
for(x=8;x>0;x--)
{ ds18_3=0;_nop_();ds18_3=com&0x01;delay_us(15);ds18_3=1;com>>=1;delay_us(1);}
}
uchar read_3()     //传感器3读数据
{ uchar x;
uchar dat;
for(x=8;x>0;x--)
{ ds18_3=0;_nop_(); dat>>=1;ds18_3=1;delay_us(1);if(ds18_3==1) dat=dat|0x80;delay_us(10);}
return (dat);
}  
void wendu_3()   //读传感器3温度数据
{ ds18b20_init();write_3(0xcc);write_3(0x44);delay_ms(200);delay_ms(200);  
ds18b20_init();write_3(0xcc);write_3(0xbe);  
ld_gw_l=read_3();
ld_gw_h=read_3();  
}
void quganrao(void)
{
ds18b20_init();
wendu_0();  //读传感器0温度数据
wendu_1();  //读传感器1温度数据
wendu_2();  //读传感器2温度数据
wendu_3();  //读传感器3温度数据
wendu_0();  //读传感器0温度数据
wendu_1();  //读传感器1温度数据
wendu_2();  //读传感器2温度数据
wendu_3();  //读传感器3温度数据
}
void wendu_zhuanhuan(void)
{
uchar ds_ds;
if(lc_hw_h&0x80)
{
  lc_hw_l=~lc_hw_l;
  lc_hw_h=~lc_hw_h;
  ds_ds=lc_hw_l+1;
  lc_hw_l=ds_ds;
  if(ds_ds>255)
   lc_hw_h=lc_hw_h+1;
  lc_hw=(lc_hw_h*16)+(lc_hw_l/16);
  }
  lc_hw=(lc_hw_h*16)+(lc_hw_l/16);
[url=]////@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/////[/url]
  if(lc_gw_h&0x80)
{
  lc_gw_l=~lc_gw_l;
  lc_gw_h=~lc_gw_h;
  ds_ds=lc_gw_l+1;
  lc_gw_l=ds_ds;
  if(ds_ds>255)
   lc_gw_h=lc_gw_h+1;
  lc_gw=(lc_gw_h*16)+(lc_gw_l/16);
  }
  lc_gw=(lc_gw_h*16)+(lc_gw_l/16);
[url=]/////@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@////////[/url]
if(ld_hw_h&0x80)
{
  ld_hw_l=~ld_hw_l;
  ld_hw_h=~ld_hw_h;
  ds_ds=ld_hw_l+1;
  ld_hw_l=ds_ds;
  if(ds_ds>255)
   ld_hw_h=ld_hw_h+1;
  ld_hw=(ld_hw_h*16)+(ld_hw_l/16);
  }
  ld_hw=(ld_hw_h*16)+(ld_hw_l/16);
[url=]////////@@@@@@@@@@@@@@@@@@@@@/////////////////[/url]
  if(ld_gw_h&0x80)
{
  ld_gw_l=~ld_gw_l;
  ld_gw_h=~ld_gw_h;
  ds_ds=ld_gw_l+1;
  ld_gw_l=ds_ds;
  if(ds_ds>255)
   ld_gw_h=ld_gw_h+1;
  ld_gw=(ld_gw_h*16)+(ld_gw_l/16);
  }
  ld_gw=(ld_gw_h*16)+(ld_gw_l/16);
if(fhw_lchw&0x80)
  lc_hw=0-lc_hw;
if(fhw_lcgw&0x80)
  lc_gw=0-lc_gw;
if(fhw_ldhw&0x80)
  ld_hw=0-ld_hw;
if(fhw_ldgw&0x80)
  ld_gw=0-ld_gw;

}
void fuzaishuchu(void) //!!!!!!!!!!关键子程序输出
{
  if(ysj_yunzhuan>480) //判断压缩机实际运转时间是否大于8小时此值标准应为480
  {
   
   ysj=0;   //关闭压缩机
   if(ysj_ys!=ysj)
   {
    ysj_yanshi=4;     //置位压缩机延时时间  
    ysj_ys=ysj;        //置位压缩机延时状态 保存压缩机状态   
   }
   if(dr_num_1==10)  //用于电加热只会开启一次 防止二次开启
    {
     lc_dr=1;   //
     ld_dr=1;   // 开启电热
     dr_num_1=15; //将dr_num_1的值改变使值不为10 防止冷藏冷冻电加热二次开启
     }
   if(dr_time<=120)     //判断电热时间如果小于2小时那么检测管温是否达到7度
    {        //如果达到7度关闭电热,否则累计计时
     if(lc_gw>0x07)
      {
       wd_lcdr=wd_lcdr+1;   //当检测到温度高于限值 将wd_lcdr加1;否则
       if(wd_lcdr>=100)   //对wd_lcdr的值减1 传感器毕竟错误率还是很
         wd_lcdr=90;   //低的,累计监测。然后判断wd_lcdr的值来确定
      }        //是否执行动作 防止误动作
     else
      {
       wd_lcdr=wd_lcdr-1;
       if(wd_lcdr<=10)
        wd_lcdr=20;
      }
     if(wd_lcdr>=70)
      {
       lc_dr=0;      //关闭电热
       wd_lcdr=40;   //复位此值
      }
     if(ld_gw>0x07)
      {
       wd_lddr=wd_lddr+1;   //当检测到温度高于限值 将wd_lcdr加1;否则
       if(wd_lddr>=100)   //对wd_lcdr的值减1 传感器毕竟错误率还是很
         wd_lddr=90;   //低的,累计监测。然后判断wd_lcdr的值来确定
      }        //是否执行动作 防止误动作当前值为累计60次再执行
     else
      {
       wd_lddr=wd_lddr-1;
       if(wd_lddr<=10)
        wd_lddr=20;
      }
     if(wd_lddr>=70)
      {
       ld_dr=0;      //关闭电热
       wd_lddr=40;   //复位此值
      }
     if((lc_dr|ld_dr)==0)   //如果冷藏冷冻电加热都关闭了
      {
       ysj_yunzhuan=0;    //将计时清零 退出化霜循环
       dr_num_1=10;    //将dr_num_1值复位 为下次开启电热准备
      }
    }
   else         //如果加热时间大于2小时仍然未达到7度强制关闭电热
    {          //后期加上报警暂时不加   
     lc_dr=0;
     ld_dr=0;
     ysj_yunzhuan=0;       //将计时清零 退出化霜循环
     dr_num_1=10;    //将dr_num_1值复位 为下次开启电热准备
    }
   
  }
else                //压缩机开启时间未达到化霜限制条件电加热工作时间保持清零
  {
   if((lc_hw>(lc_sd+1))|(ld_hw>(ld_sd+1)))  //压缩机工作条件实际温度大于设定温度1度
    {          //将wd_ysj值加1
     wd_ysj++;
     if(wd_ysj>=90)
      wd_ysj=80;
    }
   
   if((lc_hw<(lc_sd-1))&(ld_hw<(ld_sd-1)))  //压缩机工作条件实际温度小于设定温度1度
    {          //将wd_ysj值减1
     wd_ysj--;
     if(wd_ysj<=20)
      wd_ysj=20;
    }
   if(wd_ysj>=70)//如果wd_ysj值高于70说明温度值的却为高 执行压缩机运转条件
    {
     if(ysj_yanshi<=1)
      {
       ysj=1;
       ysj_ys=ysj;
      }
    }
   if(wd_ysj<=30)//如果wd_ysj值低于30说明温度值的却为低 执行压缩机关闭条件
    {    //如果wd_ysj值在30-70中间程序忽略
     ysj=0;
     if(ysj_ys!=ysj)
      {
       ysj_yanshi=4;     //置位压缩机延时时间
       ysj_ys=ysj;        //置位压缩机延时状态
      }
    }
   dr_time=0;     //在非化霜期间一直对化霜计时清零
         
  }
  if((ysj&(ld_hw>(ld_sd-1))))
  {
   wd_ldfj=wd_ldfj+1;
    if(wd_ldfj>=90)
     wd_ldfj=80;
  }
  else
  {
    wd_ldfj=wd_ldfj-1;
    if(wd_ldfj<=10)
     wd_ldfj=10;
  }
  if(wd_ldfj>=70)      //冷冻风机运转条件
    ld_fj=1;
  if(wd_ldfj<=30)      //冷冻风机关闭条件
    ld_fj=0;  
  if((ysj&(lc_hw>(lc_sd-1))))
  {
   wd_lcfj=wd_lcfj+1;
    if(wd_lcfj>=90)
     wd_lcfj=80;
  }
  else
  {
   wd_lcfj=wd_lcfj-1;
   if(wd_lcfj<=10)
     wd_lcfj=10;
  }
  if(wd_lcfj>=70)   //冷藏风机运转条件
    lc_fj=1;
  if(wd_lcfj<=30)   //冷藏风机关闭条件
    lc_fj=0;
}
void sheding(void)
{

if(~lcsd)
{
  delay_ms(200);
  if(~lcsd)
  {
   lc_sd--;
   if(lc_sd<2)
    lc_sd=9;
  }
  while(~lcsd);    //按键松手检测
   
}
if(~ldsd)
{
  delay_ms(200);
  if(~ldsd)
  {
   ld_sd-=2;
   if(ld_sd<-26)
    ld_sd=-16;
  }
  while(~ldsd);   //按键松手检测
        //
}

}
void ceshi(void)
{
if(~sdsd)
{   delay_ms(20);
   if(~sdsd)
   {
    mode=(0x83|mode_temp);
    while(~sdsd);
   }
}
if(~gblc)
{   delay_ms(20);
   if(~gblc)
   {
    mode_temp>>=1;
    if(mode_temp&0x02)
      mode_temp<<=5;
    mode=((0x83|mode_temp)&0xfd);
    while(~gblc);
   }
}
}
/****************************************
从机的时间调整应该在数据传输之前进行,,在按键动作时应该包含发送数据这个子程序
关于压缩机工作时间延时部分 定时器已经验证  大约每5分钟快4秒  关系不大显示部分几乎完工
程序封装时去掉管温显示 阳历节日已经加入 阴历未加入
温度传感器有一个温差错误  比其他值小4度左右 有极低几率出现乱码温度  此传感器需要更换  
关于时间设定方面 暂时不打算加入防止误操作状
  
试机发现问题  在不接传感器时  相当于稳定温度为0度   程序运转稳定   接入传感器后 好像有不正常的
化霜行为和风机误动作  初步判断在程序中每次判断温度值  当有一次温度值错误
就导致异常停机  在程序中温度已经求平局值   在做实验   
程序固化0831 试机
***************************************/
void main(void)
{
wd_lcdr=40;
wd_lddr=40;
wd_ysj=40;
wd_lcfj=40;
wd_ldfj=40;     //上面几个变量相当于对温度求平均值防止传感器偶然错误导致电路动作
dr_num_1=10;    //此值用于任何时候电加热只会被开启一次
P1=0x00;P1=0x00;      //上电关闭压缩机
lc_sd=5;        //上电初始设定温度
ld_sd=-16;     //上电初始设定温度
num=1;         //上电基准 时间关系到压缩机计时以及化霜
TMOD=0x01;       //
TH0=0x4c;       //
TL0=0x00;         //上电定时状态
ysj_yanshi=4;    //压缩机上电延时  
EA=1;       //开总中断
ET0=1;       //
    TR0=1;            //上电定时器初值
lcsd=1;
ldsd=1;      //按键键位上拉
mode=0x00;       //赋予功能调整变量
time=0x00;       //初值那个位置1时对应报警
mode_temp=0x40;      //
quganrao();          //去除读取温度值时的第一个温度参数
while(1)          //主循环
{  
  wendu_0();      //读传感器0温度数据
  wendu_1();      //读传感器1温度数据
  wendu_2();      //读传感器2温度数据
  wendu_3();      //读传感器3温度数据
  sheding();
  delay_ms(2);
  ceshi();
  fasong(lc_hw_l,lc_hw_h,lc_gw_l,lc_gw_h,ld_hw_l,ld_hw_h,ld_gw_l,ld_gw_h,lc_sd,0-ld_sd,mode,time);
  mode=0x00;                   //发送后将值清 0防止连续调整
  wendu_zhuanhuan();    //time作为故障报警位
  fuzaishuchu();
  delay_ms(200);
}
}
这是显示屏上的
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define WRITE_sec 0x80 //  寄存器宏定义 时间 秒
#define WRITE_min 0x82 //  寄存器宏定义 时间 分
#define WRITE_hou 0x84 //  寄存器宏定义 时间 时
#define WRITE_jap 0x86 //  寄存器宏定义 时间 日
#define WRITE_mon 0x88 //  寄存器宏定义 时间 月
#define WRITE_wee 0x8a //  寄存器宏定义 时间 周
#define WRITE_yea 0x8c //  寄存器宏定义 时间 年
#define WRITE_pro 0x8e //  寄存器宏定义 时间 寄存器写保护位
sbit lcd_rs=P0^3;
sbit lcd_rw=P0^2;
sbit lcd_e1=P0^1;
sbit lcd_e2=P0^0;  //屏接口定义
sbit cl=P2^2;
sbit io=P2^4;      //主从机通讯接口定义
sbit k_c=P2^0;
sbit k_d=P2^1;   //暂时确定端口 后期需要更改 检测为门开关端口
sbit ds18b20=P2^6;   //室温传感器接口后期根据需要更改
sbit ds1302_ck=P0^6;  //时钟芯片 时钟端口
sbit ds1302_io=P0^5;  //时钟芯片 数据端口
sbit ds1302_ce=P0^4; //时钟芯片 使能端口
uchar num;     //显示切换时刷新屏变量
uchar ds_l,ds_h;  //存储读出温度的高低位  
uchar t_int,t_dec;  //存储温度整数和小数
uchar miao,fen,shi,ri,yue,zhou,nian;//时间读取变量
uchar nnn,yyy,rrr,sss,fff;//储存接受变量值为BCD码
uchar nnn_num,yyy_num,rrr_num,sss_num,fff_num;//储存bcd码转换后的二进制时间值
uchar lc_hw_h;//储存冷藏环境温度高八位数值
uchar lc_hw_l;//储存冷藏环境温度低八位数值
uchar lc_gw_h;//储存冷藏管温温度高八位数值
uchar lc_gw_l;//储存冷藏管温温度低八位数值
uchar ld_hw_h;//储存冷冻环境温度高八位数值
uchar ld_hw_l;//储存冷冻环境温度低八位数值
uchar ld_gw_h;//储存冷冻管温温度高八位数值
uchar ld_gw_l;//储存冷冻环境温度低八位数值
     //上述数值为从机发送
uchar lc_hw_int,lc_hw_dec,lc_gw_int,lc_gw_dec,ld_hw_int,ld_hw_dec,ld_gw_int,ld_gw_dec;
uchar lc_sd,ld_sd,mode,time;//温度设定变量       上面是 //储存转换后的整数小数变量
uint kk;     //死循环延时等待值
uchar fhw_lcgw,fhw_ldgw,fhw_lchw,fhw_ldhw;
void t_tiaozheng(void);   //时间调整函数声明 在中断服务函数里好像必须声明
void delay_ms(uchar tt)   //大约1毫秒延时函数
{
uchar aa,bb;
for(aa=99;aa>0;aa--) for(bb=tt;tt>0;tt--);

}
/******************************************
以下延时函数针对的是12Mhz的晶振
delay(0):延时518us 误差:518-2*256=6
delay(1):延时7us   (原帖写"5us"是错的)
delay(10):延时25us    误差:25-20=5
delay(20):延时45us    误差:45-40=5
delay(100):延时205us 误差:205-200=5
delay(200):延时405us 误差:405-400=5
网上摘录
*******************************************/

void delay_us(uchar cc) //微妙延时函数
{
while(--cc);
}
void wriee_com(uchar com) //上半屏写指令
{
lcd_e1=0;lcd_rs=0;lcd_rw=0;lcd_e1=1;
P1=com;delay_ms(5);lcd_e1=0;delay_ms(5);
}
void writt_com(uchar com) //下半屏写指令
{
lcd_e2=0;lcd_rs=0;lcd_rw=0;lcd_e2=1;
P1=com;delay_ms(5);lcd_e2=0;delay_ms(5);
}
void wriee_dat(uchar date)//  上半屏写数据
{
lcd_e1=0;lcd_rs=1;lcd_rw=0;lcd_e1=1;
P1=date;delay_ms(5);lcd_e1=0;delay_ms(5);
}
void writt_dat(uchar date)// 下半屏写数据
{
lcd_e2=0;lcd_rs=1;lcd_rw=0;lcd_e2=1;
P1=date;delay_ms(5);lcd_e2=0;delay_ms(5);
}
void lcd_init(void)//液晶屏上下屏初始化
{
wriee_com(0x01);wriee_com(0x30);wriee_com(0x0c);wriee_com(0x06);wriee_com(0x14);
writt_com(0x01);writt_com(0x30);writt_com(0x0c);writt_com(0x06);writt_com(0x14);   
}
void open(void) //开关冷藏冷冻门提示后边需加按键抖动延时
{
  for(num;num<2;num++)
  {
   wriee_com(0x01);writt_com(0x01);//清屏指令清除开门后原来显示字符
   }
  wriee_com(0x82);
  wriee_dat(0xbb);wriee_dat(0xb6); //   欢
  wriee_dat(0xd3);wriee_dat(0xad); //   迎
  wriee_dat(0xca);wriee_dat(0xb9); //   使
  wriee_dat(0xd3);wriee_dat(0xc3); //   用
  wriee_dat(0xb6);wriee_dat(0xa8); //   定
  wriee_dat(0xd6);wriee_dat(0xc6); //   制
  wriee_dat(0xcf);wriee_dat(0xb5); //   系
  wriee_dat(0xcd);wriee_dat(0xb3); //   统
  writt_com(0x88);
  writt_com(0x02);
  writt_com(0x83);
  writt_dat(0xc0);writt_dat(0xe4); //冷
  if(k_c)  //判断开门的是冷藏还是冷冻后期需要更改
   {
    writt_dat(0xb2);writt_dat(0xd8);//冻
   }
  else
   {
    writt_dat(0xb6);writt_dat(0xb3);//藏
   }
  writt_dat(0xc3);writt_dat(0xc5); //门
  writt_dat(0xd2);writt_dat(0xd1); //已
  writt_dat(0xb4);writt_dat(0xf2); //打
  writt_dat(0xbf);writt_dat(0xaa); //开
  while(k_c|k_d);   //门开关松手检测 这里是个死循环但是
         //门开关一般不会出现直通。暂时未处理
  wriee_com(0x01);
  writt_com(0x01);
}

void write_1302(uchar com,dat)//ds1302在指定地址写入数据
{
uchar i,temp;
ds1302_ce=0;
ds1302_ck=0;
ds1302_ce=1;
for(i=8;i>0;i--)
{
   ds1302_ck=0;
   temp=com;
   ds1302_io=temp&0x01;
   delay_us(2);
   com=com>>1;
   ds1302_ck=1;
}
  for(i=8;i>0;i--)
{
   ds1302_ck=0;
   temp=dat;
   ds1302_io=temp&0x01;
   delay_us(2);
   dat=dat>>1;
   ds1302_ck=1;
}
}
uchar read_1302(uchar com)//ds1302从指定地址读出时间数据
{
uchar i,temp,ttt;
ttt=0x00;
ds1302_ce=0;
ds1302_ck=0;
ds1302_ce=1;
for(i=8;i>0;i--)
{
   ds1302_ck=0;
   temp=com;
   ds1302_io=temp&0x01;
   delay_us(2);
   com=com>>1;
   ds1302_ck=1;
}
for(i=8;i>0;i--)
{
  delay_us(2);
  ds1302_ck=0;
  ttt=ttt>>1;
  delay_us(2);
  if(ds1302_io)
   ttt=ttt|0x80;
  ds1302_ck=1;   
}
return(ttt);
}
void ds1302_init(void) //时间寄存器初始化写入,加时间调整控制由从机发送第11字节决定
        //时间调整已经完成下一步对时钟进行校准
{
write_1302(WRITE_pro,0x00);         //打开写保护
write_1302(WRITE_sec,((49/10)<<4|(49%10)));  //写入初始时间,秒
write_1302(WRITE_min,((59/10)<<4|(59%10)));  //写入初始时间,分
write_1302(WRITE_hou,((23/10)<<4|(23%10)));  //写入初始时间,时
write_1302(WRITE_jap,((31/10)<<4|(31%10)));  //写入初始时间,日
write_1302(WRITE_mon,((12/10)<<4|(12%10)));  //写入初始时间,月
write_1302(WRITE_wee,((5/10)<<4|(5%10)));  //写入初始时间,周
write_1302(WRITE_yea,((11/10)<<4|(11%10)));  //写入初始时间,年
write_1302(WRITE_pro,0x80);      // 关闭写保护
}
void read_time(void)          //读取时间函数
{

miao=read_1302(0x81);
fen=read_1302(0x83);
shi=read_1302(0x85);
ri=read_1302(0x87);
yue=read_1302(0x89);
zhou=read_1302(0x8b);
nian=read_1302(0x8d);
nnn=nian;
yyy=yue;
rrr=ri;
sss=shi;
fff=fen;         // 保存时间信息用于调整计算
}            
void pic_pic(void)               //屏幕画面显示,暂时只有时间后期需要留出节日空间
{         //温度已经显示暂时感觉总高于室温1-2度可能靠近热源关系
for(num;num>0;num--)   //后期如果确定用语句处理
{
  wriee_com(0x01);writt_com(0x01);//清屏指令清除开门后原来显示字符
}
wriee_com(0x81);    //时间显示初始地址
wriee_dat(0x32);    //下列依次显示2
wriee_dat(0x30);    //0
wriee_dat(0x30+((nian&0x70)>>4));
wriee_dat(0x30+(nian&0x0f));  //年
wriee_dat(0x2d);
wriee_dat(0x30+((yue&0x70)>>4));
wriee_dat(0x30+(yue&0x0f));   //月
wriee_dat(0x2d);
wriee_dat(0x30+((ri&0x70)>>4));
wriee_dat(0x30+(ri&0x0f));   //日
wriee_dat(0x20);
wriee_dat(0x20);

wriee_dat(0x30+((shi&0x70)>>4));
wriee_dat(0x30+(shi&0x0f));   //小时
wriee_dat(0x3a);
wriee_dat(0x30+((fen&0x70)>>4));
wriee_dat(0x30+(fen&0x0f));   //分钟
wriee_dat(0x3a);
wriee_dat(0x30+((miao&0x70)>>4));
wriee_dat(0x30+(miao&0x0f));//秒 ,上述写出基础时间暂不完善
wriee_com(0x92); //温度显示起始地址
wriee_dat(0xb5);
wriee_dat(0xb1); //当
wriee_dat(0xc7);
wriee_dat(0xb0); //前
wriee_dat(0xca);
wriee_dat(0xd2); //室
wriee_dat(0xce);
wriee_dat(0xc2); //温
if(ds_h&0x80)
  wriee_dat(0x2d);
else
  wriee_dat(0x20);   //温度正负标志判断
wriee_dat((t_int/10)+0x30);  //显示温度整数十位
wriee_dat((t_int%10)+0x30);  //显示温度整数个位
wriee_dat(0x2e);    //显示点
wriee_dat(t_dec+0x30);   //显示温度小数位
writt_com(0x80);//下半屏初始地址
writt_dat(0xc0);writt_dat(0xe4); //冷
writt_dat(0xb2);writt_dat(0xd8);//冻
//空两个汉字符后期将显示传送温度值
writt_com(0x86);
writt_dat(0xc0);writt_dat(0xe4); //冷
writt_dat(0xb6);writt_dat(0xb3);//藏
//最后一行暂时打算写入节日制暂时保留
}
void ds18b20_init(void)
{
  ds18b20=1;
  delay_us(1);
  ds18b20=0;
  delay_us(250);
  ds18b20=1;
  delay_us(30); //此处取值读出存在脉冲时间在10-60之间
   delay_us(250);//等待存在脉冲输出完毕
}
void write_da18b20(uchar com)
{
uchar x;
for(x=8;x>0;x--)
{
   ds18b20=0;
   _nop_();
   ds18b20=com&0x01;
   delay_us(15);
   ds18b20=1;
   com>>=1;
   delay_us(1);
}
}
uchar read_ds18b20()
{
uchar x;
uchar dat;
for(x=8;x>0;x--)
{
  ds18b20=0;
  _nop_();
  dat>>=1;
  ds18b20=1;
  delay_us(1);
  if(ds18b20==1)
   dat=dat|0x80;
  delay_us(10);  
}
return (dat);
}
void shiwenwendu(void) //读取室温
{
uchar ds_ds;
ds18b20_init();
write_da18b20(0xcc);
write_da18b20(0x44);
delay_ms(200);
delay_ms(200);
ds18b20_init();
write_da18b20(0xcc);
write_da18b20(0xbe);
ds_l=read_ds18b20();
ds_h=read_ds18b20();
ds18b20_init();
if(ds_h&0x80)
{
  ds_l=~ds_l;
  ds_h=~ds_h;
  ds_ds=ds_l+1;
  ds_l=ds_ds;
  if(ds_ds>255)
   ds_h=ds_h+1;
  t_int=(ds_h*16)+(ds_l/16);
  t_dec=(ds_l%16)*10/16;
  }
  t_int=(ds_h*16)+(ds_l/16);
  t_dec=(ds_l%16)*10/16;
}

void exter0() interrupt 0  //数据接收暂时接受位数为8位char为共计12字节串行传输
{         //关于死循环已经防止   意外导致死循环是显示会静止一两秒自动回复
uchar a;      //后期再观察暂时不是问题
kk=600;      //此函数为中断执行函数其中KK值为死循环等待值
for(a=8;a>0;a--)    //后期需要加入长时间收不到从机发的数据的问题或者干扰造成程序飞
{        //暂时发现在杜邦线传输偶尔会出现温度错 但不影响实际负载控制 后期寻找原因
  lc_hw_l>>=1;    //没收到8个字节存到相应数据中 此程序验证无误
  while(cl&&--kk)    //
  delay_us(20);
  if(io)
   lc_hw_l|=0x80;
  else
   lc_hw_l|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  lc_hw_h>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   lc_hw_h|=0x80;
  else
   lc_hw_h|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  lc_gw_l>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   lc_gw_l|=0x80;
  else
   lc_gw_l|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  lc_gw_h>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   lc_gw_h|=0x80;
  else
   lc_gw_h|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  ld_hw_l>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   ld_hw_l|=0x80;
  else
   ld_hw_l|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  ld_hw_h>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   ld_hw_h|=0x80;
  else
   ld_hw_h|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  ld_gw_l>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   ld_gw_l|=0x80;
  else
   ld_gw_l|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  ld_gw_h>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   ld_gw_h|=0x80;
  else
   ld_gw_h|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  lc_sd>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   lc_sd|=0x80;
  else
   lc_sd|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  ld_sd>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   ld_sd|=0x80;
  else
   ld_sd|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  mode>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   mode|=0x80;
  else
   mode|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
kk=600;
  for(a=8;a>0;a--)
{
  time>>=1;
  while(cl&&--kk);
  delay_us(20);
  if(io)
   time|=0x80;
  else
   time|=0x00;  
  while(~cl&&--kk);
  delay_us(20);   
}
fhw_lchw=lc_hw_h;
fhw_lcgw=lc_gw_h;
fhw_ldhw=ld_hw_h;
fhw_ldgw=ld_gw_h;
}
void xianshizhuanhuan(void)  //显示转换准确性未验证后期需要验证
{
uchar ds_ds;
if(lc_hw_h&0x80)
{
  lc_hw_l=~lc_hw_l;
  lc_hw_h=~lc_hw_h;
  ds_ds=lc_hw_l+1;
  lc_hw_l=ds_ds;
  if(ds_ds>255)
   lc_hw_h=lc_hw_h+1;
  lc_hw_int=(lc_hw_h*16)+(lc_hw_l/16);
  lc_hw_dec=(lc_hw_l%16)*10/16;
  }
  lc_hw_int=(lc_hw_h*16)+(lc_hw_l/16);
  lc_hw_dec=(lc_hw_l%16)*10/16;
////////////////////////////////////////////////////////////////////
  if(lc_gw_h&0x80)
{
  lc_gw_l=~lc_gw_l;
  lc_gw_h=~lc_gw_h;
  ds_ds=lc_gw_l+1;
  lc_gw_l=ds_ds;
  if(ds_ds>255)
   lc_gw_h=lc_gw_h+1;
  lc_gw_int=(lc_gw_h*16)+(lc_gw_l/16);
  lc_gw_dec=(lc_gw_l%16)*10/16;
  }
  lc_gw_int=(lc_gw_h*16)+(lc_gw_l/16);
  lc_gw_dec=(lc_gw_l%16)*10/16;  
//////////////////////////
if(ld_hw_h&0x80)
{
  ld_hw_l=~ld_hw_l;
  ld_hw_h=~ld_hw_h;
  ds_ds=ld_hw_l+1;
  ld_hw_l=ds_ds;
  if(ds_ds>255)
   ld_hw_h=ld_hw_h+1;
  ld_hw_int=(ld_hw_h*16)+(ld_hw_l/16);
  ld_hw_dec=(ld_hw_l%16)*10/16;
  }
  ld_hw_int=(ld_hw_h*16)+(ld_hw_l/16);
  ld_hw_dec=(ld_hw_l%16)*10/16;
/////////////////////////////////////////////////////////
  if(ld_gw_h&0x80)
{
  ld_gw_l=~ld_gw_l;
  ld_gw_h=~ld_gw_h;
  ds_ds=ld_gw_l+1;
  ld_gw_l=ds_ds;
  if(ds_ds>255)
   ld_gw_h=ld_gw_h+1;
  ld_gw_int=(ld_gw_h*16)+(ld_gw_l/16);
  ld_gw_dec=(ld_gw_l%16)*10/16;
  }
  ld_gw_int=(ld_gw_h*16)+(ld_gw_l/16);
  ld_gw_dec=(ld_gw_l%16)*10/16;
////////////////////////////////////  

  writt_com(0x82);   //冷藏环温写入地址
  if(fhw_lchw&0x80)
   writt_dat(0x2d);
  else
   writt_dat(0x20);
  writt_dat((lc_hw_int/10)+0x30);
  writt_dat((lc_hw_int%10)+0x30); //写入冷藏环境温度
  writt_dat(0x2f);
  writt_dat(0x30);
  writt_dat((lc_sd%10)+0x30);    //写入冷藏设定温度
  writt_com(0x88);    //冷冻环温写入地址
  if(fhw_ldhw&0x80)
   writt_dat(0x2d);
  else
   writt_dat(0x20);
  writt_dat((ld_hw_int/10)+0x30);
  writt_dat((ld_hw_int%10)+0x30); //写入冷冻环境温度
  writt_dat(0x2f);
  writt_dat(0x2d);
  writt_dat((ld_sd/10)+0x30);
  writt_dat((ld_sd%10)+0x30);  //写入冷冻设定温度
  writt_com(0x90);    //冷藏管温写入地址
  if(fhw_lcgw&0x80)
   writt_dat(0x2d);
  else
   writt_dat(0x20);
  writt_dat((lc_gw_int/10)+0x30);
  writt_dat((lc_gw_int%10)+0x30); //写入冷藏盘管温度
//  writt_com(0x99);       //冷冻管温写入地址
  if(fhw_ldgw&0x80)
   writt_dat(0x2d);
  else
   writt_dat(0x20);
  writt_dat((ld_gw_int/10)+0x30);
  writt_dat((ld_gw_int%10)+0x30); //写入冷冻盘管温度
}
/*************************************
当前程序弊端1 有很低几率的室温温度瞬间显示错误
是程序在读取温度时进入中断造成 应该程序可以解决
中断后重新读取温度 暂时没有好的解决方法
**************************************/  
void t_tiaozheng(void)   //时间调整告一段落,取值和运行以及操作无误
{        //时间中的秒不做调整
          //
uchar xx=60;            //     调整之后回到主屏等待值
uchar yy=2;            //     调整后清屏         
while(--xx)
  {
  
   for(yy;yy>0;yy--)     //后期如果确定用语句处理
    {
     wriee_com(0x01);
     writt_com(0x01);   //清屏指令清除开门后原来显示字符
    }
   writt_com(0x92);     //调整量指示地址
   writt_dat(0xb5);
   writt_dat(0xb1);     //当
   writt_dat(0xc7);
   writt_dat(0xb0);         //前
   writt_dat(0xb5);
   writt_dat(0xf7);     //调
   writt_dat(0xd5);
   writt_dat(0xfb);     //整
   writt_dat(0xa1);
   writt_dat(0xc3);      //:
   wriee_com(0x84);       //地址写入初始值
   wriee_dat(0xca);   
   wriee_dat(0xb1);     //时
   wriee_dat(0xbc);   
   wriee_dat(0xe4);     //间
   wriee_dat(0xb5);   
   wriee_dat(0xf7);     //调
   wriee_dat(0xd5);   
   wriee_dat(0xfb);     //整
   wriee_com(0x91);     //时间显示初始地址
   wriee_dat(0x32);     //下列依次显示2
   wriee_dat(0x30);     //0
   wriee_dat(0x30+((nian&0x70)>>4));
   wriee_dat(0x30+(nian&0x0f));   //年
   wriee_dat(0x2d);
   wriee_dat(0x30+((yue&0x70)>>4));
   wriee_dat(0x30+(yue&0x0f));    //月
   wriee_dat(0x2d);
   wriee_dat(0x30+((ri&0x70)>>4));
   wriee_dat(0x30+(ri&0x0f));    //日
   wriee_dat(0x20);
   wriee_dat(0x20);
   wriee_dat(0x20);
   wriee_dat(0x30+((shi&0x70)>>4));
   wriee_dat(0x30+(shi&0x0f));    //小时
   wriee_dat(0x3a);
   wriee_dat(0x30+((fen&0x70)>>4));
   wriee_dat(0x30+(fen&0x0f));    //分钟
   wriee_dat(0x3a);
   wriee_dat(0x30+((miao&0x70)>>4));
   wriee_dat(0x30+(miao&0x0f));  //秒 ,上述写出基础时间暂不完善
   if(mode&0x40)  
   {
    nnn_num=(((nnn&0xf0)>>4)*10)+(nnn&0x0f);   //保存初始转换为二进制值
    if(mode&0x02)
     {   
      nnn_num++;
      if(nnn_num>19)
       nnn_num=10;
     }
      writt_com(0x01);   //调整量指示清平
      writt_com(0x82);   //调整量指示地址
      writt_dat(0xa1);   //
      writt_dat(0xfc);   //调整量指示上箭头
      writt_com(0x98);
      writt_dat(0x32);   //下列依次显示2
      writt_dat(0x30);         //0
      writt_dat(0x30+(nnn_num/10));   //x
      writt_dat(0x30+(nnn_num%10));    //x
      writt_dat(0xc4);
      writt_dat(0xea);       //年

    write_1302(WRITE_pro,0x00);          //打开写保护   
    write_1302(WRITE_yea,((nnn_num/10)<<4|(nnn_num%10)));  //写入初始时间,年
    write_1302(WRITE_pro,0x80);         // 关闭写保护
    mode=0x00;                               //关闭年位
    xx=130;             //在调整时间时保证延时刷新
   }         
  if(mode&0x20)
   {
    yyy_num=(((yyy&0x10)>>4)*10)+(yyy&0x0f);   //保存初始转换为二进制值
    if(mode&0x02)
     {
      yyy_num=yyy_num+1;
      if(yyy_num>12)
       yyy_num=1;
     }
      writt_com(0x01);       //调整量指示清平
      writt_com(0x83);       //调整量指示地址
      writt_dat(0xa1);       //
      writt_dat(0xfc);       //调整量指示上箭头
      writt_com(0x98);
      writt_dat(0x30+(yyy_num/10));     //x
      writt_dat(0x30+(yyy_num%10));     //x
      writt_dat(0xd4);
      writt_dat(0xc2);        //月
           
    write_1302(WRITE_pro,0x00);          //打开写保护
    write_1302(WRITE_mon,((yyy_num/10)<<4|(yyy_num%10)));  //写入初始时间,yue
    write_1302(WRITE_pro,0x80);         // 关闭写保护
    mode=0x00;                               //关闭yue位
    xx=130;              //在调整时间时保证延时刷新
   }
  if(mode&0x10)
  {
   rrr_num=(((rrr&0x30)>>4)*10)+(rrr&0x0f);   //保存初始转换为二进制值
   if(mode&0x02)
    {
     rrr_num++;
     if(rrr_num>31)
      rrr_num=1;
    }
     writt_com(0x01);       //调整量指示清平
     writt_com(0x85);       //调整量指示地址
     writt_dat(0xa1);       //
     writt_dat(0xfc);       //调整量指示上箭头
     writt_com(0x98);
     writt_dat(0x30+(rrr_num/10));     //x
     writt_dat(0x30+(rrr_num%10));     //x
     writt_dat(0xc8);
     writt_dat(0xd5);        //日
           
   write_1302(WRITE_pro,0x00);          //打开写保护
   write_1302(WRITE_jap,((rrr_num/10)<<4|(rrr_num%10)));  //写入初始时间,日
   write_1302(WRITE_pro,0x80);         // 关闭写保护
   mode=0x00;                               //关闭yue位
   xx=130;                //在调整时间时保证延时刷新
  }
  if(mode&0x08)
   {
    sss_num=(((sss&0x30)>>4)*10)+(sss&0x0f);   //保存初始转换为二进制值
    if(mode&0x02)
     {
      sss_num++;
      if(sss_num>23)
       sss_num=0;
     }
      writt_com(0x01);       //调整量指示清平
      writt_com(0x88);       //调整量指示地址
      writt_dat(0xa1);       //
      writt_dat(0xfc);       //调整量指示上箭头
      writt_com(0x98);
      writt_dat(0x30+(sss_num/10));     //x
      writt_dat(0x30+(sss_num%10));     //x
      writt_dat(0xca);
      writt_dat(0xb1);        //时
     
    write_1302(WRITE_pro,0x00);          //打开写保护
    write_1302(WRITE_hou,((sss_num/10)<<4|(sss_num%10)));  //写入初始时间,时
    write_1302(WRITE_pro,0x80);         // 关闭写保护
    mode=0x00;                               //关闭yue位
    xx=130;              //在调整时间时保证延时刷新
   }
  if(mode&0x04)
   {
    fff_num=((((fff&0x70)>>4)*10)+(fff&0x0f));    //保存初始转换为二进制值
    if(mode&0x02)
     {
      fff_num++;
      if(fff_num>59)
       fff_num=0;
     }
      writt_com(0x01);       //调整量指示清平
      writt_com(0x89);       //调整量指示地址
      writt_dat(0xa1);       //
      writt_dat(0xfc);       //调整量指示上箭头
      writt_com(0x98);
      writt_dat(0x30+(fff_num/10));     //x
      writt_dat(0x30+(fff_num%10));     //x
      writt_dat(0xb7);
      writt_dat(0xd6);        //分
      
    write_1302(WRITE_pro,0x00);          //打开写保护
    write_1302(WRITE_min,(((fff_num/10)<<4)|(fff_num%10)));  //写入初始时间,分
    write_1302(WRITE_pro,0x80);         // 关闭写保护
    mode=0x00;                             //关闭yue位
    xx=130;             //在调整时间时保证延时刷新
   }
  read_time();             //在设定时间时保证时间实时刷新
  delay_ms(20);
  }
}
void jieri_xianshi(void)
{

  nnn_num=(((nnn&0xf0)>>4)*10)+(nnn&0x0f);
  yyy_num=(((yyy&0x10)>>4)*10)+(yyy&0x0f);
  rrr_num=(((rrr&0x10)>>4)*10)+(rrr&0x0f);
  if((yyy_num==0x01)&(rrr_num==0x01))    //元旦快乐
   {
    writt_com(0x93);
    writt_dat(0xa1);writt_dat(0xfa);
    writt_dat(0xd4);writt_dat(0xaa);
    writt_dat(0xb5);writt_dat(0xa9);
    writt_dat(0xbf);writt_dat(0xec);
    writt_dat(0xc0);writt_dat(0xd6);
    writt_dat(0xa1);writt_dat(0xfb);
   }
  else if((yyy_num==0x03)&(rrr_num==0x08)) //妇女节
   {
     writt_com(0x93);
     writt_dat(0xa2);writt_dat(0xdb);
     writt_dat(0xb8);writt_dat(0xbe);
     writt_dat(0xc5);writt_dat(0xea);
     writt_dat(0xbd);writt_dat(0xda);
     writt_dat(0xa2);writt_dat(0xe0);
   }
  else if((yyy_num==0x03)&(rrr_num==0x12)) //妇女节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xd6);writt_dat(0xb2);
     writt_dat(0xca);writt_dat(0xf7);
     writt_dat(0xbd);writt_dat(0xda);
   }
  else if((yyy_num==0x04)&(rrr_num==0x05)) //植树节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xc7);writt_dat(0xe5);
     writt_dat(0xc3);writt_dat(0xf7);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x05)&(rrr_num==0x01))   //劳动节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xc0);writt_dat(0xcd);
     writt_dat(0xb6);writt_dat(0xaf);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x05)&(rrr_num==0x04))   //青年节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xc7);writt_dat(0xe0);
     writt_dat(0xc4);writt_dat(0xea);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x05)&(rrr_num==0x11))   //世界电信日
   {
     writt_com(0x93);
     writt_dat(0xca);writt_dat(0xc0);
     writt_dat(0xbd);writt_dat(0xe7);
     writt_dat(0xb5);writt_dat(0xe7);
     writt_dat(0xd0);writt_dat(0xc5);
     writt_dat(0xc8);writt_dat(0xd5);
   }
   else if((yyy_num==0x06)&(rrr_num==0x01))   //世界儿童节
   {
     writt_com(0x93);
     writt_dat(0xa2);writt_dat(0xea);
     writt_dat(0xa2);writt_dat(0xe5);
     writt_dat(0xb6);writt_dat(0xf9);
     writt_dat(0xcd);writt_dat(0xaf);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x07)&(rrr_num==0x01))   //建党节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xbd);writt_dat(0xa8);
     writt_dat(0xb5);writt_dat(0xb3);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x08)&(rrr_num==0x01))   //建军节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xbd);writt_dat(0xa8);
     writt_dat(0xbe);writt_dat(0xfc);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x09)&(rrr_num==0x0a))   //教师节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xbd);writt_dat(0xcc);
     writt_dat(0xca);writt_dat(0xa6);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x09)&(rrr_num==0x0a))   //国庆节
   {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0xb9);writt_dat(0xfa);
     writt_dat(0xc7);writt_dat(0xec);
     writt_dat(0xbd);writt_dat(0xda);
   }
   else if((yyy_num==0x0b)&(rrr_num==0x0b))   //光棍节
   {
     writt_com(0x93);
     writt_dat(0xa2);writt_dat(0xf2);
     writt_dat(0xb9);writt_dat(0xe2);
     writt_dat(0xb9);writt_dat(0xf7);
     writt_dat(0xbd);writt_dat(0xda);
     writt_dat(0xa2);writt_dat(0xf2);
   }
   else if((yyy_num==0x0c)&(rrr_num==0x19))   //圣诞节
    {
      writt_com(0x93);
      writt_dat(0x20);writt_dat(0x20);
      writt_dat(0xca);writt_dat(0xa5);
      writt_dat(0xb5);writt_dat(0xae);
      writt_dat(0xbd);writt_dat(0xda);
    }
  /* else if((nnn_num==11)&(yyy_num==0x09)&(rrr_num==0x0c))   //中秋节
    {
      writt_com(0x93);
      writt_dat(0xd6);writt_dat(0xd0);
      writt_dat(0xc7);writt_dat(0xef);
      writt_dat(0xbc);writt_dat(0xd1);
      writt_dat(0xbd);writt_dat(0xda);
    }
   else if((nnn_num==11)&(yyy_num==0x0c)&(rrr_num==0x16))   //dongzhi
    {
      writt_com(0x93);
      writt_dat(0x20);writt_dat(0x20);
      writt_dat(0xb6);writt_dat(0xac);
      writt_dat(0x20);writt_dat(0x20);
      writt_dat(0xd6);writt_dat(0xc1);
    }
   else if((nnn_num==12)&(yyy_num==0x01)&(rrr_num==0x17))   //chunjie
    {
      writt_com(0x93);
      writt_dat(0xd0);writt_dat(0xc2);
      writt_dat(0xc4);writt_dat(0xea);
      writt_dat(0xbf);writt_dat(0xec);
      writt_dat(0xc0);writt_dat(0xd6);
    }
   else if((nnn_num==12)&(yyy_num==0x01)&(rrr_num==0x16))   //chunxi
    {
      writt_com(0x93);
      writt_dat(0xd0);writt_dat(0xc2);
      writt_dat(0xc4);writt_dat(0xea);
      writt_dat(0xbf);writt_dat(0xec);
      writt_dat(0xc0);writt_dat(0xd6);
    }
   else if((nnn_num==12)&(yyy_num==0x01)&(rrr_num==0x18))   //chunxi
    {
      writt_com(0x93);
      writt_dat(0xd0);writt_dat(0xc2);
      writt_dat(0xc4);writt_dat(0xea);
      writt_dat(0xbf);writt_dat(0xec);
      writt_dat(0xc0);writt_dat(0xd6);
    }
   else if((nnn_num==12)&(yyy_num==0x02)&(rrr_num==0x06))   //yuanxiao
    {
      writt_com(0x93);
      writt_dat(0xd4);writt_dat(0xaa);
      writt_dat(0xcf);writt_dat(0xfc);
      writt_dat(0xbc);writt_dat(0xd1);
      writt_dat(0xbd);writt_dat(0xda);
    }
   else if((nnn_num==12)&(yyy_num==0x02)&(rrr_num==0x06))   //yuanxiao
    {
      writt_com(0x93);
      writt_dat(0xd4);writt_dat(0xaa);
      writt_dat(0xcf);writt_dat(0xfc);
      writt_dat(0xbc);writt_dat(0xd1);
      writt_dat(0xbd);writt_dat(0xda);
    }*/
   else
    {
     writt_com(0x93);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0x20);writt_dat(0x20);
     writt_dat(0x20);writt_dat(0x20);
    }
}   
void main(void)
{
k_c=1;
k_d=1;
lc_sd=0;
ld_sd=0;
mode=0;   //初值
time=0;   //初值
delay_ms(200); // 上点延时 时间短后期需延长
kk=1000;//在接收数据是防止干扰造成死循环的延时值 暂时取值1000,后期再作更改
EA=1;
EX0=1;
IT0=1;
lcd_init();    //屏初始化
ds1302_init(); //ds1302初始化
/****************************************
电路板5V散热片小 有点过热
显示程序主要剩下时间调整方面
今天找到一个错误 在读取时间值时把读出的BCD码
误作为二进制值参与运算导致时间数据错误;
问题有两个传感器值不太对
时间需要校准
程序于0826固化 暂不改动
****************************************/
while(1)   //主循环
  {
  k_c=1;
  k_d=1;
  if(k_c|k_d)
  {
   
     open(); //开门子函数由于开门时间往往很长 不用时时相应中断
   
  }
  else
   {
   read_time();//读取时间
   pic_pic(); //主屏显示
   shiwenwendu();//转换室温温度并显示在指定位置
   xianshizhuanhuan();//接受冷藏冷冻数据并转换显示在指定位置
   if(mode&0x80)    //判断最高位是否为1来确定时钟是否调整
    {
     t_tiaozheng();
      num=2;
    }
   delay_ms(10);
   jieri_xianshi();
   }
  
  }
}

原机电路图.jpg 19264显示.jpg congji.jpg 左下角分别是设定温度+5和-10暂时没有放到位.jpg
发表于 2011-9-6 20:23 | 显示全部楼层
厉害,简直天书一般,佩服,看来单片机不好学
发表于 2011-9-6 20:32 | 显示全部楼层
没看程序,先说几点俺的想法:
1. 实际应用最好加上看门狗。
2. 固定使用最好专门做PCB,不用洞洞板,感觉不太靠谱。
3. 继电器输出端要加阻容吸收,或加个压敏。
个人观点,仅供参考,欢迎批评指正。
发表于 2011-9-6 21:16 | 显示全部楼层
貌似51芯片本身的抗干扰性能就很差,换个抗干扰能力强点的芯片吧。
发表于 2011-9-6 22:18 | 显示全部楼层
AT89S的单片机本身就容易受干扰,还是换STC的吧。另外单片机VCC和地之间的104电容要有。
发表于 2011-9-6 22:19 | 显示全部楼层
滤波电容太小  加大
退耦电容太少  加多

特别是89s52板上的电容

还有再加大接地面积
发表于 2011-9-6 22:39 | 显示全部楼层
这好像是冰箱的电路吧
 楼主| 发表于 2011-9-6 22:59 | 显示全部楼层
这好像是冰箱的电路吧   是冰箱的电路  
现在受到的干扰是用于开关灯泡的机械开关干扰到了电路      这个开关设计的很不合理(自我感觉)  属于双刀双掷开关 一段接单片机  另一端接220V火线 在开关灯引起干扰  就是这个东东引起的  
但是同一条线上的stc没事
发表于 2011-9-7 08:26 | 显示全部楼层
楼主用的就是STC呀,图片上有。

51怕继电器,触点吸合断开的时候会打火的,我碰到过,你可以给继电器的触点开关上加一个灭弧电容,在外加屏蔽罩,外壳接地,会有效果的。
至于楼上说STC抗干扰能力强,呵呵,是老妖说的吧

最好的办法是换单片机,换个带硬件看门狗的MCU,比如说PIC
发表于 2011-9-7 09:42 | 显示全部楼层
试试能否把灯泡改固态继电器控制?

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-4-29 18:35 , Processed in 0.079058 second(s), 49 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表