/******************************************************** 
 *  Description: EM78P468N NTC  RC temperature                    *   * 
 *  Author:      Sunli                     * 
 *  Date:        03/09/2007 
 *  Version:     v1.0                                   * 
 *******************************************************/ 
#i nclude "em78x468xx.h" 
#i nclude "temp_table.h" 
#define DISI() _asm{disi} 
#define ENI() _asm{eni} 
#define SLEP() _asm{slep} 
#define NOP() _asm{nop} 
#define WDTC() _asm{wdtc} 
#define uchar unsigned char 
#define ushort unsigned short 
#define ulong unsigned long 
#define Rp R55 
#define Rc R61 
#define Rm R60 
#define SCL R63 
#define SDA R62 
#define LOW R65 
#define MID R66 
#define HI  R67 
#define COOL R85 
#define HOT  R86 
#define COL_RST R87 
#define LED R54 
#define COOL_IF_L R57==0 //如果COOL关 
#define COOL_IF_H R57==1 //如果COOL开 
#define HEAT_IF_L R56==0 //如果HEAT关 
#define HEAT_IF_H R56==1 //如果HEAT开  
#define SCL_L R63=0 //I2总线时钟线 
#define SCL_H R63=1 
#define SDA_L R62=0 //I2总线数据线 
#define SDA_H R62=1 
#define Rp_TO_IN P5CR|=0x20;NOP() 
#define Rp_TO_OUT P5CR&=0xdf;NOP() 
#define SDA_TO_IN P6CR|=0x04; NOP() //设数据线位输入 
#define SDA_TO_OUT P6CR&=0xfb; NOP() //设数据线位输出 
#define SDA_IF_L R62==0  //如果sda为低 
#define SDA_IF_H R62==1   //如果sda为高 
#define DELAY_us NOP();NOP();NOP();NOP() 
#define PAGE_SIZE 8 
#define SIZE 0x00ff 
#define ON_OFF    0x1e 
#define MODE      0x1d 
#define FAN       0x1b 
#define INCREASE  0x17 
#define DECREASE  0x0f 
#define W_ADD_COM 0xa0 //写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0 
#define R_ADD_COM 0xa1 //读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1 
#define lcd_init(init_v) _asm{mov a,@init_v}\ 
       _asm{mov %LCDCR,a} 
uchar lcd_ram[10]= 
{ // 0  , 1  ,  2 , 3 ,  4  ,  5 , 6,   7  , 8 ,  9 
 0xdf,0x0e,0xeb,0xaf,0x3e,0xbd,0xfd,0x0f,0xff,0xbf 
}; 
ushort dly;  
ushort test_temp[6]; 
ushort Rm_t,Rc_t; 
uchar RC_num,Rmin_p,Rmax_p; 
ushort Rmin_t,Rmax_t; 
ulong Ttmp; 
uchar key_state = 0;//按键值 
uchar new_key = 0; 
uchar key_tcc = 0; 
uchar key_temp= 0; 
uchar timer_cnt=0; 
uchar r_buf[2]; 
uchar w_buf[2]; 
uchar set_temper =0; 
uchar fan_st   = 0; 
uchar mode_on_off=0; 
uchar timer1,times; 
//ushort timer; 
bit key_flag=0; 
bit timer_2ms_ok=0; 
bit COL_RST_FLAG=0; 
/******************函数声明********************/ 
void main(void); 
void sys_init(void); 
void tms(uchar i); 
void i2cstart(void); 
uchar i2cwt(uchar a); 
uchar i2crd(void); 
void i2cstop(void); 
uchar wt24c(uchar *p, uchar ad, uchar n); 
void rd24c(uchar *p_dst, uchar ad_rsc, uchar num); 
uchar KeyScan(void); 
void KeyDo(uchar key); 
//void   key_find(void); 
void display(uchar temp_v,uchar tamp_v,uchar set_tmp); 
unsigned char test_temperature(void); 
unsigned char Bin1toBcd(unsigned char Xbin1); 
/*********************end*********************/ 
void sys_init(void) 
{ 
 SBPCR=0x17; //rc 2.13mhz,sleep->Idle mode,sub-clock run program 
 IRCR=0;  //disable IR/PWM,port5 is general i/o 
 ISR=0;  //clear count1 interrupt flag bit 
  
 P5CR=0xc3;  //port7 is lcd segment,port8 is general i/o 
 P6CR=0x00; 
 P7CR=0; 
 P8CR=0x1f; 
 CNT12CR=0x06; 
 CNT1PR=5; 
 CNT1EN=1; 
 HPWTPR=0; 
 LPWTPR=0; 
 IMR|=0x08;  //enable count1 interrupt 
  
// WUCR=0x70; //enable p60~3 wake up 
// TCCCR=0x0f; //disable main interrupt,TCC pre-scaler 1:256 
 WDTCR=0xff; //0xf7; //disable WDT   
 HLPWTCR=0x77; 
 P6PH=0xff;  //enable  port6 internal pull high 
 P6OD=0;  //disable por6 open-drain 
 P8PH=0xff;  //disable port8 internal pull high 
 P6PL=0;  //disable port6 internal pull down 
 PORT5=0x00; 
 PORT6=0x00; 
 PORT8=0x00; 
 //变量清零 
 COL_RST_FLAG=0; 
  
} 
void tms(uchar i) 
{ 
 uchar j; 
 for(;i>0;i--) 
  { 
   for(j=0;j<200;j++); 
   WDTC(); 
   } 
} 
/**********************W/R EEPROM*******************************************/ 
//起始信号 
void i2cstart(void) 
{   
 SCL_L; DELAY_us; 
    SDA_H; DELAY_us; 
    SCL_H; DELAY_us; 
    SDA_L; DELAY_us; 
    SCL_L; DELAY_us; 
} 
//把一个字节数据输入器件,并以收到应答信号为止 
//写入成功返回1,失败返回0 
uchar i2cwt(uchar a) 
{   uchar i; 
  
    for(i=0;i<8;i++) 
    {   SCL_L; DELAY_us; 
        if((a<<i)&0x80) SDA_H; 
     else SDA_L; 
     DELAY_us; 
        SCL_H; DELAY_us; 
        
    } 
    SCL_L; DELAY_us; 
    SDA_H; DELAY_us; 
    SCL_H; DELAY_us; 
  
 SDA_TO_IN;    
  
    if(SDA_IF_L)  //测试有无应答 
    { SDA_TO_OUT; 
     return(1);  //有应答 
    } 
    else 
    { SDA_TO_OUT; 
     return(0);  //无应答 
    } 
} 
//i2c读要调用的函数 
//从器件读出一个字节 
uchar i2crd(void) 
{   uchar i,temp; 
            
    for(i=0;i<8;i++) 
    {   SCL_L; DELAY_us;  
        SDA_H; DELAY_us;    //置数据线接上内部上拉(数据输入方式),此为必须 
        SCL_H; DELAY_us; 
        temp<<=1; 
        
        SDA_TO_IN;    
        
  if(SDA_IF_H) temp+=1; 
        DELAY_us; 
        
        SDA_TO_OUT;    
 } 
    SCL_L; DELAY_us;  //主器件应答脉冲 
    SDA_L; DELAY_us; 
    SCL_H; DELAY_us; 
    return(temp); 
} 
//停止信号 
void i2cstop(void) 
{   SCL_L; DELAY_us; 
    SDA_L; DELAY_us; 
    SCL_H; DELAY_us; 
    SDA_H; 
} 
uchar wt24c(uchar *p, uchar ad, uchar n) 
{ uchar t=0; 
  
 i2cstart();     //发送起始信号 
   
 if(i2cwt(W_ADD_COM))  //发送写字节命令及器件地址 
 {  
  i2cwt(ad);    //ad_dst的低位到器件 
    
  for(;n>0;n--)   //发送要写入的数据 
  {   i2cwt(*p); 
   p++; 
  } 
 } 
// else syserr=I2C_ERR;  //写字节命令及器件地址错 
  
 i2cstop(); 
    tms(6);      //延时6ms 
  
 return(*p); 
} 
//从24cxx读出数据 
//参数: *p_dst要读入数据的主机内存地址指针; ad_rsc要输出数据的i2c的地址(整形); num数据个数(整形) 
//参数条件:  ad_dst+(num-1)不能大于器件的最高地址; num必须>0; 
void rd24c(uchar *p_dst, uchar ad_rsc, uchar num) 
{  
    uchar t=0; 
 i2cstart();     //发送起始信号 
   
 if(i2cwt(W_ADD_COM))  //发送写字节命令及器件地址 
 {  
  i2cwt(ad_rsc);   //ad_rsc的低位 
     
  i2cstart();    //再发送起始信号 
  i2cwt(R_ADD_COM);  //发送SLA_R, 读命令字节及器件地址 
     
  for(;num>0;num--) 
  {   *p_dst=i2crd();  //从器件读出一个字节 
   p_dst++; 
  } 
 } 
// else syserr=I2C_ERR;  //写字节命令及器件地址错或对方无应答 
   
 i2cstop(); 
} 
/***************************************************************************/ 
unsigned char Bin1toBcd(unsigned char Xbin1) 
{ 
 unsigned short xBCD=0; 
 do 
 { 
  //if(Xbin1>=100) 
  //{ 
  // Xbin1-=100; 
  // xBCD+=0x100; 
  //} 
  //else 
  //{ 
   if(Xbin1>=10) 
   { 
    Xbin1-=10; 
    xBCD+=0x10; 
   } 
   else 
   { 
    xBCD+=Xbin1; 
    break; 
   } 
  //} 
 }while(1); 
 return xBCD; 
} 
unsigned char test_temperature(void) 
{   
    uchar tamp=0; 
    Ttmp=0; 
 RC_num=0; 
 do 
 { 
  P6CR&=0xfc; 
  Rp_TO_OUT; 
  Rm=0; 
  Rc=0; 
  Rp=0; 
  for(dly=0xa00;dly;dly--) 
  { 
   WDTC(); 
  } 
  
  Rm_t=0; 
  P6CR|=0x02; 
  Rp_TO_IN; 
  Rm=1;      //用基准电阻充电 
  while(1) 
  { 
   if(Rp) 
   { 
    break; 
   } 
   Rm_t++; 
  } 
  WDTC(); 
  test_temp[RC_num]=Rm_t; 
  RC_num++; 
 }while(RC_num<6); 
  
 RC_num=0;   
 Rmin_p=0; 
 Rmax_p=5; 
 Rmin_t=test_temp[0]; 
 Rmax_t=test_temp[5]; 
 do 
 { 
  if(test_temp[RC_num+1]<Rmin_t) 
  { 
   Rmin_t=test_temp[RC_num+1]; 
   Rmin_p=RC_num+1; 
  } 
  if(test_temp[4-RC_num]>Rmax_t) 
  { 
   Rmax_t=test_temp[4-RC_num]; 
   Rmax_p=4-RC_num; 
  } 
  RC_num++; 
 }while(RC_num<5); 
  
 RC_num=0; 
 Rm_t=0; 
 do 
 { 
  if(RC_num!=Rmin_p) 
  { 
   if(RC_num!=Rmax_p) 
   { 
    Rm_t+=test_temp[RC_num]; 
   } 
  } 
  RC_num++; 
 }while(RC_num<6);//去max,min,取平均值 
 Rm_t>>=2; 
 RC_num=0; 
 do 
 { 
  P6CR&=0xfc; 
  Rp_TO_OUT; 
  Rm=0; 
  Rc=0; 
  Rp=0; 
  for(dly=0xa00;dly;dly--) 
  { 
   WDTC(); 
  } 
  
  Rc_t=0; 
  P6CR|=0x01;//用NTC充电 
  Rp_TO_IN; 
  Rc=1; 
  while(1) 
  { 
   if(Rp) 
   { 
    break; 
   } 
   Rc_t++; 
  } 
  WDTC(); 
  test_temp[RC_num]=Rc_t; 
  RC_num++; 
 }while(RC_num<6); 
  
 RC_num=0;   
 Rmin_p=0; 
 Rmax_p=5; 
 Rmin_t=test_temp[0]; 
 Rmax_t=test_temp[5]; 
 do 
 { 
  if(test_temp[RC_num+1]<Rmin_t) 
  { 
   Rmin_t=test_temp[RC_num+1]; 
   Rmin_p=RC_num+1; 
  } 
  if(test_temp[4-RC_num]>Rmax_t) 
  { 
   Rmax_t=test_temp[4-RC_num]; 
   Rmax_p=4-RC_num; 
  } 
  RC_num++; 
 }while(RC_num<5); 
  
 RC_num=0; 
 Rc_t=0; 
 do 
 { 
  if(RC_num!=Rmin_p) 
  { 
   if(RC_num!=Rmax_p) 
   { 
    Rc_t+=test_temp[RC_num]; 
   } 
  } 
  RC_num++; 
 }while(RC_num<6);//去max,min,取平均值 
 Rc_t>>=2; 
  
 Ttmp=(unsigned long)Rc_t*9950; 
 Ttmp=Ttmp/Rm_t;//求ntc值 
  
 if(Ttmp>=32960) 
 { 
  return 0; 
 } 
 if(Ttmp<=3588) 
 { 
  return 0x50; 
 } 
  
 RC_num=0; 
 Rm_t=Ttmp; 
 do 
 { 
  if(Rm_t>=temp_table[RC_num+1])//查表微调 
  { 
   /*Rm_t-=temp_table[RC_num+1]; 
   Rc_t=temp_table[RC_num]-temp_table[RC_num+1]; 
   Rm_t*=10; 
   Rm_t=Rm_t/Rc_t; 
//   RC_num++;*/ 
   break; 
  } 
  RC_num++; 
 }while(RC_num<48); 
 tamp=Bin1toBcd(RC_num); 
 //Rc_t<<=4; 
 //Rm_t|=Rc_t; 
 P6CR&=0xfC; 
 PORT6&=0xfC; 
 return tamp; 
} 
void display(uchar temp_v,uchar tamp_v,uchar set_tmp) 
{       
        uchar real_dep,tmp1; 
        
        LCD_ADDR=6; 
        LCD_DB=0x08; 
        //风速+冷热 
        LCD_ADDR=0; 
        LCD_DB=tamp_v; 
        LCD_ADDR=23; 
      _asm 
  { 
   swap %tamp_v 
  } 
     LCD_DB=tamp_v; 
     //当时温度 
     real_dep=temp_v; 
     temp_v>>=4; 
   
     real_dep&=0x0f;  
  LCD_ADDR=4; 
  tmp1=lcd_ram[real_dep]; 
  tmp1&=0xf7; 
  LCD_DB=tmp1; 
   
  LCD_ADDR=3; 
  _asm 
  { 
   swap %tmp1 
  } 
  LCD_DB=tmp1;   
   
  tmp1=temp_v&0x0f;  
  LCD_ADDR=2; 
  tmp1=lcd_ram[tmp1]; 
  LCD_DB=tmp1; 
  LCD_ADDR=1; 
  _asm 
  { 
   swap %tmp1 
  } 
  LCD_DB=tmp1; 
  //设置温度 
  real_dep=set_tmp; 
     set_tmp>>=4; 
   
     real_dep&=0x0f;  
  LCD_ADDR=10; 
  tmp1=lcd_ram[real_dep]; 
  LCD_DB=tmp1; 
   
  LCD_ADDR=9; 
  _asm 
  { 
   swap %tmp1 
  } 
  LCD_DB=tmp1;   
   
  tmp1=set_tmp&0x0f;  
  LCD_ADDR=8; 
  tmp1=lcd_ram[tmp1]; 
  LCD_DB=tmp1; 
  LCD_ADDR=7; 
  _asm 
  { 
   swap %tmp1 
  } 
  LCD_DB=tmp1;    
} 
/*void lcd_on_off(void) 
{   
    uchar i; 
 for(i=0;i<32;i++) 
 { 
  LCD_ADDR=i; 
  LCD_DB=0xff; 
 } 
  
 for(dly=0x00ff;dly;dly--) 
 { 
  WDTC(); 
 } 
    
 for(i=32;i;i--) 
 { 
  LCD_ADDR=i; 
  LCD_DB=0; 
 } 
  
 for(dly=0x1fff;dly;dly--) 
 { 
  WDTC();  
 } 
   
}*/ 
/******************************按键扫描************************/ 
/*****************************按键处理************************/ 
void KeyDo(uchar key) 
{   
    uchar fan_temp; 
    if (key == ON_OFF){ 
      if(mode_on_off==0) 
        { 
         key_flag=1; 
         mode_on_off=1; 
        } 
      else 
        { 
         mode_on_off=0; 
        } 
    } 
    else if (key == FAN) 
    { 
     timer1=0; 
      key_flag=1; 
        if(mode_on_off==1) 
         { 
         fan_temp=fan_st&0xe0; 
         if(fan_temp==0x80) 
          { 
           fan_st|=0x40; 
           fan_st&=0x7f; 
          } 
         else if(fan_temp==0x40) 
          { 
           fan_st|=0x20; 
           fan_st&=0xbf; 
          } 
         else if(fan_temp==0x20) 
          { 
           fan_st|=0x80; 
           fan_st&=0xdf; 
          } 
         } 
    } 
   else if (key == MODE) 
   { 
    timer1=0; 
     key_flag=1; 
     if(mode_on_off==1) 
      { 
        fan_temp=fan_st&0x03; 
        if(fan_temp==0x01) 
           fan_st++; 
           else 
           { 
           fan_st|=0x01; 
           fan_st&=0xfd; 
           }      
      } 
    } 
    else if (key == DECREASE) 
    {       
           timer1=0; 
           key_flag=1; 
            if (set_temper == 10) 
            { 
                set_temper = 10; 
            } 
            else 
            { 
                set_temper--; 
            } 
    } 
    else if (key == INCREASE) 
    {       timer1=0; 
           key_flag=1; 
            set_temper++; 
            if (set_temper > 30) 
            { 
               set_temper = 30; 
            } 
    } 
} 
uchar KeyScan(void) 
{ 
      uchar temp = 0; 
      temp = PORT8; 
      temp&=0x1f; 
      if(temp!=0x1f) 
      return temp; 
    return 0x1f; 
} 
void _intcall counter1_l(void) @ 0x0C:low_int 3 
{ 
  
} 
void _intcall counter1(void) @ int 3 
{ 
  //backup R4 
  _asm 
   { 
     SWAPA 0x04 
     MOV 0x1F,A 
   }    
  
   //backup C system 
  _asm 
    { 
    BS 0X4,6 
    BS 0X4,7    
 MOV A,0X10 // USE 1 BYTE C TYPE,C SYSTEM BACKUP 
 MOV 0X3C+1,A 
 MOV A,0X14 
 MOV 0X3B+1,A 
 MOV A,0X18 
 MOV 0X3A+1,A 
 MOV A,0X1B 
 MOV 0X39+1,A 
 MOV A,0X1C 
 MOV 0X38+1,A 
    } 
    
            ISR=0; 
            timer_2ms_ok=1; 
            if (key_state == 0) 
           { 
            new_key = KeyScan(); 
            if (new_key != 0x1f) 
            { 
                key_state++; 
            } 
           } 
        else if (key_state < 5) 
        { 
            if (KeyScan() == new_key) 
            { 
                key_state++; 
            } 
            else 
            { 
                key_state = 0; 
            } 
        } 
        else if (key_state == 5) 
        { 
            key_state++; 
            KeyDo(new_key); 
        } 
        else if (key_state == 6) 
        { 
            key_temp = KeyScan(); 
            if (key_temp == 0x1f) 
            { 
                key_state ++; 
            } 
            else if (key_temp == DECREASE || key_temp == INCREASE) 
            { 
                if (key_tcc >= 10) 
                { 
                    key_tcc = 5; 
                    KeyDo(key_temp); 
                } 
                else 
                { 
                    key_tcc++; 
                } 
            } 
        } 
        else if (key_state < 10) 
        { 
            if (KeyScan() == 0x1f) 
            { 
                key_state ++; 
            } 
            else 
            { 
                key_state = 6; 
            } 
        } 
        else if (key_state == 10) 
        { 
            key_state = 0; 
            key_tcc = 0; 
        
        } 
     if(mode_on_off) 
     { 
     times++; 
     timer1++; 
     //rst_tim++; 
     } 
  
  // Write your code (inline assembly or C) here 
  
   //restore C system 
  _asm 
    {  
    BS 0X4,6 
    BS 0X4,7 
 MOV A,0X3C+1 // USE 1 BYTE C TYPE,C SYSTEM RESTORE 
 MOV 0X10,A 
 MOV A,0X3B+1 
 MOV 0X14,A 
 MOV A,0X3A+1 
 MOV 0X18,A 
 MOV A,0X39+1 
 MOV 0X1B,A 
 MOV A,0X38+1 
 MOV 0X1C,A 
    } 
 //restore R4 
  _asm 
   { 
     SWAPA 0x1F 
     MOV 0X04,A 
   } 
} 
void  main() 
  { 
  uchar temp1,temp2; 
  uchar i,j; 
  uchar *r; 
     uchar b; 
     uchar c; 
     uchar stst; 
     uchar *w; 
     uchar x; 
     uchar y; 
       DISI();  
    tms(10); 
    sys_init(); 
    //lcd_init(0xf7); 
       r_buf[0]=0; 
       r_buf[1]=0; 
     r=r_buf; //读参数 
     b=0x00; 
     c=2; 
     w=w_buf; //写参数 
     x=0x00; 
     y=2; 
     
     //w_buf[0]=0x81; 
     //w_buf[1]=0x19; 
     // wt24c(w,x,y); //出厂写EEPROM 
     rd24c(r,b,c); //初始读EEPROM 
     fan_st=r_buf[0]; 
     set_temper=r_buf[1]; 
     temp1=test_temperature(); 
  for(i=0;i<32;i++)// 清屏 
 { 
  LCD_ADDR=i; 
  LCD_DB=0; 
 } 
  for(dly=0x1fff;dly;dly--) 
 { 
  WDTC();  
 } 
 //LED=1; 
 ENI(); 
 while(1) 
 {   
     //key_find(); 
   while(timer_2ms_ok) 
   { 
   timer_2ms_ok=0; 
   if(mode_on_off==1) 
    { 
     lcd_init(0xf7); 
     if(key_flag) 
     { 
     LED=1; 
     if(timer1>=200) 
      { 
      timer1=0; 
      LED=0; 
      if((r_buf[0]!=fan_st)||(r_buf[1]!=set_temper)) 
      { 
      r_buf[0]=fan_st; 
      r_buf[1]=set_temper; 
      w_buf[0]=fan_st; 
      w_buf[1]=set_temper; 
      wt24c(w,x,y); //写 
      } 
      key_flag=0;       
         } 
      } 
        if(times>=250) 
         { 
          temp1=test_temperature(); 
       times=0; 
      } 
       temp2=Bin1toBcd(set_temper); 
    display(temp1,fan_st,temp2); 
    PORT6=fan_st&0xe0; 
    stst=fan_st&0x01; 
    if(stst==0x01) 
    {  
       COOL=1; 
       HOT=0; 
       tms(1); 
       if((temp1>temp2)&&(COL_RST_FLAG==0)) 
         {  
            j=0; 
          while((COOL_IF_L)&&(j<=3)) 
            { 
             j++; 
             COL_RST=1; 
                   tms(10); 
                   COL_RST=0; 
             COL_RST_FLAG=1;                   
             }         
                   j=0; 
          } 
        else if((temp1<temp2)&&(COL_RST_FLAG==1)) 
         {   
            j=0; 
        while((COOL_IF_H)&&(j<=3)) 
             { 
             j++;   
             COL_RST=1; 
                   tms(10); 
                   COL_RST=0; 
             COL_RST_FLAG=0;                   
             }         
                  j=0; 
         }          
    } 
        //stst=fan_st&0x02; 
    else 
     {  
        COOL=0; 
         if((temp1<temp2)&&(HEAT_IF_H)) 
         HOT=1; 
         else 
         HOT=0; 
      }  
    } 
    else 
    { 
     LED=0; 
     lcd_init(0x00); 
     LOW=0; 
     MID=0; 
     HI=0; 
     COOL=0; 
     HOT=0; 
     } 
 WDTC();  
   }  
 WDTC();  
 } 
  }  |