📄 jf_p1._c
字号:
const unsigned char CRC8_shf15_TAB[256] = {
0,49,98,83,196,245,166,151,185,136,219,234,125,76,31,46,67,114,33,16,
135,182,229,212,250,203,152,169,62,15,92,109,134,183,228,213,66,115,32,17,
63,14,93,108,251,202,153,168,197,244,167,150,1,48,99,82,124,77,30,47,
184,137,218,235,61,12,95,110,249,200,155,170,132,181,230,215,64,113,34,19,
126,79,28,45,186,139,216,233,199,246,165,148,3,50,97,80,187,138,217,232,
127,78,29,44,2,51,96,81,198,247,164,149,248,201,154,171,60,13,94,111,
65,112,35,18,133,180,231,214,122,75,24,41,190,143,220,237,195,242,161,144,
7,54,101,84,57,8,91,106,253,204,159,174,128,177,226,211,68,117,38,23,
252,205,158,175,56,9,90,107,69,116,39,22,129,176,227,210,191,142,221,236,
123,74,25,40,6,55,100,85,194,243,160,145,71,118,37,20,131,178,225,208,
254,207,156,173,58,11,88,105,4,53,102,87,192,241,162,147,189,140,223,238,
121,72,27,42,193,240,163,146,5,52,403,86,120,73,26,43,188,141,222,239,
130,179,224,209,70,119,36,21,59,10,89,104,255,206,157,172
};
unsigned char read_crc_byte(void); //从SHT读1个字节的CRC校验码,无应答
void fun_beep(unsigned char beep_time_temp) //初始化定时器2,开始CTC模式
{
beep_time_ask=beep_time_temp; //蜂鸣器要求响的时间
beep_time=0;; //蜂鸣器响时间清0
TCCR2 = 0x00; //stop
TCNT2 = 0x87; //0x86; // 2048 Khz 0x83; //2khz
OCR2 = 0x79; //0x7a; //0x7d;
TCCR2 = 0x1A; //start
auto_state &=~b_beep_stop; //清间隔计时标志
run_state |=b_beep_onask; //蜂鸣器响标志
}
void fun_fault_beep(void) //20080201增加故障报警蜂鸣器子程序
{
if (mode &b_fast_test)
{fun_beep(10); beep_times=0;} //快测时蜂鸣器响1声
else
{fun_beep(10); beep_times=3; beep_stop_time_ask=90;} //蜂鸣器要求响的时间0.1S,响4次
}
//将AD采样值查表得到温度值20K感温包-分压电阻20K,,15K感温包-分压电阻15K
signed char Fun_ad_20k(unsigned char thAD)
{
unsigned char n; //对应AD查表中的偏移量
unsigned char temp; //AD查表中的偏移量的AD值
unsigned char a_d1; //实际采样值与温度值的差距
unsigned char a_d2; //实际采样值与下一个温度值的差距
signed char th_value; //温度值
if (thAD <=24) {th_value =-20;return(th_value);} //实际采样值小于-20℃的AD(8)时,温度为-20℃
if (thAD >=246) {th_value =117; return(th_value);} //实际采样值大于127℃的AD(232)时,温度为127℃
if (thAD <=167) //实际采样值小于40℃的AD(167)时,如实际采样值大于10℃的AD(86)时,起始步n为45(25℃)
{
if (thAD >=86) n=45; //TH=10-40,TH0=25
else n=20; //TH0=0
}
else //实际采样值大于70℃的AD(218)时,起始步n为100(80℃),否则起始步n为70(50℃)
{
if (thAD >=218) n=100; //TH>=70,TH0=80
else n=70; //TH=40-70,TH0=50
}
temp=TAB20K_20temp[n];
if (thAD ==temp) th_value =n-20; //相等时取温度-20
else
{
if (thAD >temp)
{//实际采样值大于当前步的AD值时,步加,直到实际采样值小于当前步的AD值,再比较离得最近的步为温度。
do
{n++;temp=TAB20K_20temp[n];}
while (thAD >=temp);
a_d1= temp- thAD;
n--;temp=TAB20K_20temp[n];a_d2=thAD-temp;
if (a_d1 >=a_d2) th_value =n-20;
else th_value=n-19;
}
else
{//实际采样值小于当前步的AD值时,步减,直到实际采样值小于当前步的AD值,再比较离得最近的步为温度。
do
{n--;temp=TAB20K_20temp[n];}
while (thAD <=temp);
a_d1=thAD-temp;
n++;temp=TAB20K_20temp[n];a_d2=temp-thAD;
if (a_d1 >=a_d2) th_value=n-20;
else th_value=n-21;
}
}
return(th_value); //返回温度值
}
unsigned char Fun_ad_50k(unsigned char thAD)//将AD采样值查表得到排气温度值50K感温包-分压电阻10K
{
unsigned char n; //对应AD查表中的偏移量
unsigned char temp; //AD查表中的偏移量的AD值
unsigned char a_d1; //实际采样值与温度值的差距
unsigned char a_d2; //实际采样值与下一个温度值的差距
unsigned char th_value;//温度值
if (thAD <=15) {th_value =0;return(th_value);} //实际采样值小于0℃的AD(15)时,温度为0℃
if (thAD >=250) {th_value =199; return(th_value);} //实际采样值大于169℃的AD(254)时,温度为149℃
if (thAD <=138) //实际采样值小于70℃的AD(138)时,如实际采样值大于40℃的AD(71)时,起始步n为60(140)
{
if (thAD >=71) n=60; //TH 40-70 TH TH0=60
else n=20; //TH 0-40 TH0=20
}
else //实际采样值大于70℃的AD(138)时,起始步n为100℃,否则起始步n为120℃
{
if (thAD >=193) n=120; //TH>=100,TH0=120
else n=80; //TH 100-70,TH0=80
}
temp=TAB50K_10temp[n];
if (thAD ==temp) th_value =n; //相等时取温度
else
{
if (thAD >temp)
{//实际采样值大于当前步的AD值时,步加,直到实际采样值小于当前步的AD值,再比较离得最近的步为温度。
do
{n++;temp=TAB50K_10temp[n];}
while (thAD >=temp);
a_d1= temp- thAD;
n--;temp=TAB50K_10temp[n];a_d2=thAD-temp;
if (a_d1 >=a_d2) th_value =n;
else th_value=n+1;
}
else
{//实际采样值小于当前步的AD值时,步减,直到实际采样值小于当前步的AD值,再比较离得最近的步为温度。
do
{n--;temp=TAB50K_10temp[n];}
while (thAD <=temp);
a_d1=thAD-temp;
n++;temp=TAB50K_10temp[n];a_d2=temp-thAD;
if (a_d1 >=a_d2) th_value=n;
else th_value=n-1;
}
}
return(th_value); //返回温度值
}
//******************************
//******************************
void ADStartP(void)
{//ADSC=1启动ADC,等待采样工作完成;
ADCSRA |=0x40; //ADSC=1启动ADC
while (!(ADCSRA & 0x10)) WDR(); //ADIF=1时AD转换结束且数据更新
ADCSRA |=0x10; //ADIF=1软件写1清ADC中断完成位
}
//************************************************************************************
//CD4052-A:PORTA1,CD4052-B:PORTA0,在每次AD转换后置CD4052动作,再进行下2AD。00-01-11-10
//20070813改为PF3[ADC3] 排气温度EXHAUST,50K感温包,PF2[ADC2] 预留环境采样15KOUTROOM,
//PF0[ADC0]除湿电流I-HUMID。去掉CD4052
//************************************************************************************
void funADsample(void) //AD采样程序
{
//SFIOR =0x04; //不允许任何上拉
ADCSRA =0x86; //ADEN=1使能AD,6=110分频64
ADMUX =0x42; //选择ADC2、右对齐,y0-管温
delay_20us();
ADStartP();
i_defrost_sumADL +=ADCL;////y0-管温读低8位AD值,累加。
i_defrost_sumADH +=(ADCH & 0x03);
NOP();
ADMUX =0x41; //选择ADC2、右对齐,y0-管温
delay_20us();
ADStartP();
i_evin_sumADL +=ADCL;////y0-管温读低8位AD值,累加。
i_evin_sumADH +=(ADCH & 0x03);
NOP();
ADMUX =0x40; //选择ADC0加湿电流、右对齐
delay_20us();
ADStartP();
i_i_humid_sumADL +=ADCL; //加湿电流读低8位AD值,累加。
i_i_humid_sumADH +=(ADCH & 0x03);//读高8位AD值,累加。
NOP();
ADMUX =0x43; //选择ADC3排气温度、右对齐
delay_20us();
ADStartP(); //启动AD并等待转换完成
i_exghaust_sumADL +=ADCL; //读低8位AD值,累加。
i_exghaust_sumADH +=(ADCH & 0x03); //读高8位AD值,累加。
NOP();
ADCSRA =0x00; //采样完成后禁止AD
}
/***********************************************************************
每隔100ms启动一次AD采样funADsample(),采64次后取高8位为AD值,清除所有累加值。
adtempsum-ADH+ADL的高8位,再右移8位得到最后的AD值。*/
void funADsum(void)////AD累加程序
{
funADsample(); //AD采样程序
ADsum_times+=1; //采样次数+1
ADsumTH_times+=1; //排气感温包AD采样次数+1
NOP();
if (ADsumTH_times>=16) //采样次数到16次否?到则求AD平均值
{//采样16次 1.6s
// exghaust_AD=i_exghaust_sumADH+(unsigned char)(i_exghaust_sumADL>>8); //20080128取高8位
// defrost_AD=i_defrost_sumADH+(unsigned char)(i_defrost_sumADL>>8); //20080128取高8位
exghaust_AD=(i_exghaust_sumADH<<2)+(unsigned char)(i_exghaust_sumADL>>6);
defrost_AD=(i_defrost_sumADH<<4)+ (i_defrost_sumADL>>4); //
evin_AD=(i_evin_sumADH<<4) + (i_evin_sumADL>>4)
exghaust_TH =Fun_ad_50k(exghaust_AD);//将AD采样值查表得到温度值
if (defrost_AD>=29 && defrost_AD<=968) defrost_TH =Fun_ad_20k10(defrost_AD); //管温值=环境温度
else if (defrost_AD>=20 && defrost_AD<29) defrost_TH=-40;
else if (defrost_AD>968 && defrost_AD<=1000) defrost_TH=105;
else if (defrost_time>=30) b_defrosterr=1;
if (evin_AD>=29 && evin_AD<=968) evin_TH =Fun_ad_20k10(evin_AD); //管温值=环境温度
else if (evin_AD>=20 && evin_AD<29) evin_TH=-40;
else if (evin_AD>968 && evin_AD<=1000) evin_TH=105;
else if (evin_time>=30) b_evinerr=1;
i_exghaust_sumADH=00;
i_exghaust_sumADL=00;
i_defrost_sumADH=00; //
i_defrost_sumADL=00; //
i_evin_sumADL=0;
i_evin_sumADH=0;
ADsumTH_times=0; //
}
if (ADsum_times>=64) //20080128采样次数到64次否?到则求AD平均值
{//20080128 加湿采样64次
i_humid_AD=i_i_humid_sumADH+(unsigned char)(i_i_humid_sumADL>>8); //20080128取高8位
if (i_humid_AD<=9) i_humid10 =0; //20071229无电压时为0.1635V(AD=9)
else i_humid10 =i_humid_AD*0.8-3; //20071105 5A时电压为1.234V,4A时电压为1V。
ADsum_times=0;
i_i_humid_sumADH=00; //
i_i_humid_sumADL=00; //
}
}
/**************************************************/
//writes a byte on the Sensibus and checks the acknowlege
//char s_write_byte(unsigned char value)
void s_write_byte(unsigned char value)
{
unsigned char i,error=0;
for (i=0x80;i>0;i/=2) //从最高位开始取数据,右移8次,送到DATA线上后,置SCK脉冲输出
{
if (i & value) PORTC |=b_rt1_data; //1则置DATA=1
else PORTC &=~b_rt1_data; //0则置DATA=0
NOP(); NOP();NOP(); NOP();NOP(); NOP();
PORTD |=b_rt1_sck; //sck=1
delay_20us();
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
}
PORTC |=b_rt1_data; //送完8位-1个字节后将数据线置高,检查SHT的应答。
NOP();NOP();
PORTD |=b_rt1_sck; //sck=1
NOP();NOP();
DDRC &=~b_rt1_data; //DATA置0为输入口
NOP(); NOP();//检测SHT的应答改在测量程序中,如有应答则等待测试完成后读,如无应答则发复位
}
//从SHT读1个字节
unsigned char s_read_byte_old(unsigned char ack) //读字节
{
unsigned char i,val=0;
DDRC &=~b_rt1_data; //DATA置0为输入口
NOP(); NOP(); NOP(); NOP();
NOP(); NOP(); NOP();
for (i=0x80;i>0;i/=2) //从最高位开始取数据,右移8次,读入DATA线上数据后,置SCK脉冲输出
{PORTD |=b_rt1_sck; //sck=1
delay_20us();
if (PINC &b_rt1_data) val=(val | i); //读入数据为1时,字节该位置1
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
}
DDRC |=b_rt1_data; //DATA置1为输出口
NOP(); NOP(); NOP(); NOP();
if (ack) PORTC |=b_rt1_data; //应答1继续通讯
else PORTC &=~b_rt1_data; //应答0结束通讯
NOP(); NOP(); NOP(); NOP();NOP(); NOP();
PORTD |=b_rt1_sck; //sck=1
delay_20us();
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
PORTC |=b_rt1_data; //data=1
delay_20us();
return val; //返回读入值
}
void s_transstart(void) //起始步
{
DDRC |=b_rt1_data; //DATA置1为输出口
delay_20us();
PORTC |=b_rt1_data; //data=1
delay_20us();
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
PORTD |=b_rt1_sck; //sck=1
delay_20us();
PORTC &=~b_rt1_data; //data=0
delay_20us();
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
PORTD |=b_rt1_sck; //sck=1
delay_20us();
PORTC |=b_rt1_data; //data=1
delay_20us();
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
}
void s_connectionreset(void) //SHT失控时连续发9个SCK使其复位
{
unsigned char i;
DDRC |=b_rt1_data; //DATA置1为输出口
NOP();
NOP();
PORTC |=b_rt1_data; //data=1
PORTD &=~b_rt1_sck; //sck=0
NOP();
for(i=0; i<9; i++) //9 SCK cycle
{
PORTD |=b_rt1_sck; //sck=1
delay_20us();
PORTD &=~b_rt1_sck; //sck=0
delay_20us();
}
s_transstart(); //起始步
}
void fun_measure_temp(void) //测量温度程序
{
unsigned char error=0;
unsigned int i;
s_transstart(); //起始步
s_write_byte(MEASURE_TEMP);//写入SHT温度测量命令
if (PINC &b_rt1_data) //无应答error=1;
{
PORTD &=~b_rt1_sck; //sck=0
DDRC |=b_rt1_data; //DATA置1为输出口
delay_tt(20); //延时0.4ms
s_connectionreset(); //连续发9个脉冲让SHT复位
s_write_byte(RESET); //向SHT发复位命令
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -