來源:HANTA (suzhou) LTD 作者:Sunli /******************************************************** * Description: 468N RC temperature * * Company: HANTA (suzhou) LTD. * * Author: Sunli * * Date: 03/09/2007 * 最后更新日期:13/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關(guān) #define COOL_IF_H R57==1 //如果COOL開 #define HEAT_IF_L R56==0 //如果HEAT關(guān) #define HEAT_IF_H R56==1 //如果HEAT開 #define SCL_L R63=0 //I2總線時鐘線 #define SCL_H R63=1 #define SDA_L R62=0 //I2總線數(shù)據(jù)線 #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() //設(shè)數(shù)據(jù)線位輸入 #define SDA_TO_OUT P6CR&=0xfb; NOP() //設(shè)數(shù)據(jù)線位輸出 #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 //寫字節(jié)命令及器件地址(根據(jù)地址實際情況改變), 1010 A2 A1 A0 0 #define R_ADD_COM 0xa1 //讀命令字節(jié)及器件地址(根據(jù)地址實際情況改變), 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; /******************函數(shù)聲明********************/ 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; }
//把一個字節(jié)數(shù)據(jù)輸入器件,并以收到應(yīng)答信號為止 //寫入成功返回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) //測試有無應(yīng)答 { SDA_TO_OUT; return(1); //有應(yīng)答 } else { SDA_TO_OUT; return(0); //無應(yīng)答 } }
//i2c讀要調(diào)用的函數(shù) //從器件讀出一個字節(jié) uchar i2crd(void) { uchar i,temp; for(i=0;i<8;i++) { SCL_L; DELAY_us; SDA_H; DELAY_us; //置數(shù)據(jù)線接上內(nèi)部上拉(數(shù)據(jù)輸入方式),此為必須 SCL_H; DELAY_us; temp<<=1; SDA_TO_IN; if(SDA_IF_H) temp+=1; DELAY_us; SDA_TO_OUT; } SCL_L; DELAY_us; //主器件應(yīng)答脈沖 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(); //發(fā)送起始信號 if(i2cwt(W_ADD_COM)) //發(fā)送寫字節(jié)命令及器件地址 { i2cwt(ad); //ad_dst的低位到器件 for(;n>0;n--) //發(fā)送要寫入的數(shù)據(jù) { i2cwt(*p); p++; } } // else syserr=I2C_ERR; //寫字節(jié)命令及器件地址錯 i2cstop(); tms(6); //延時6ms return(*p); }
//從24cxx讀出數(shù)據(jù) //參數(shù): *p_dst要讀入數(shù)據(jù)的主機(jī)內(nèi)存地址指針; ad_rsc要輸出數(shù)據(jù)的i2c的地址(整形); num數(shù)據(jù)個數(shù)(整形) //參數(shù)條件: ad_dst+(num-1)不能大于器件的最高地址; num必須>0; void rd24c(uchar *p_dst, uchar ad_rsc, uchar num) { uchar t=0; i2cstart(); //發(fā)送起始信號 if(i2cwt(W_ADD_COM)) //發(fā)送寫字節(jié)命令及器件地址 { i2cwt(ad_rsc); //ad_rsc的低位 i2cstart(); //再發(fā)送起始信號 i2cwt(R_ADD_COM); //發(fā)送SLA_R, 讀命令字節(jié)及器件地址 for(;num>0;num--) { *p_dst=i2crd(); //從器件讀出一個字節(jié) p_dst++; } } // else syserr=I2C_ERR; //寫字節(jié)命令及器件地址錯或?qū)Ψ綗o應(yīng)答 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; //用基準(zhǔn)電阻充電 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])//查表微調(diào) { /*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; //風(fēng)速+冷熱 LCD_ADDR=0; LCD_DB=tamp_v; LCD_ADDR=23; _asm { swap %tamp_v } LCD_DB=tamp_v; //當(dāng)時溫度 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; //設(shè)置溫度 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; //讀參數(shù) b=0x00; c=2; w=w_buf; //寫參數(shù) 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(); } } |