/********************************************************
* 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();
}
} |