📄 stc12c5410ad温湿度采集并将模拟量通过对半查找法查表转换.c
字号:
/************************************************
文件名称:adc0.c
文件说明:ad转换,采集温度模拟量
*************************************************/
#define ADC_Power_On_Speed_Channel_0 0xc0 //P1.0作为AD输入
#define ADC_Power_On_Speed_Channel_1 0xc1 //P1.1作为AD输入
#define TempHH_AD_50 298 //AD转化最大值
#define TempLL_AD_0 754 //AD转化最小值 (用于故障判断)
#define TempE1_AD 190
#define TempE2_AD 800 //故障状态下AD值
#define HumiHH_AD_90 580
#define HumiLL_AD_10 180
#define HumiE1_AD 600
#define HumiE2_AD 150
//#define Humi_AD_Max
unsigned int tempture = 0; //整型温度值
unsigned int huminity = 0; //整型湿度值
unsigned int moni[2] = {0,0}; //模拟量数组,存放温度和湿度(或温度)
unsigned int moni_AD[2][NUM_of_RESULTS] = {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}; //存放序列通道单次转换的AD值用于滤波处理
uchar Temp_Err_Value = 0; //温度故障标志
uchar Humi_Err_Value = 0; //湿度故障标志
void delay(unsigned char us)
{
unsigned int i,j;
for(i=0;i<us;i++)
{
for(j=0;j<25;j++)
{}
}
}
/***********************************************
名称:init_ADC10
描述:
***********************************************/
void init_adc10(void)
{
ADC_CONTR |= 0x80; //开AD转换电源
delay(32); //上电延时大约1ms
P1M0 |= 0x03;
P1M1 &= 0xfc; //P1.0 P1.1为高阻态模式
delay(5);
}
/************************************************
名称:start_ADC12
描述:启动AD转换
*************************************************/
void start_ADC10(void)
{
static unsigned int index=0;
unsigned int adcdata;
ADC_CONTR = ADC_Power_On_Speed_Channel_0; //选择P1.0为转换通道
delay(10);
ADC_CONTR |= 0x08; //启动ADC10
while((ADC_CONTR&0x10) == 0) {} //等待AD转换完毕
ADC_CONTR &= 0xe7; //清0 ADC_FLAG ,ADC_START位 ,停止AD转换
adcdata = ADC_DATA;
adcdata = adcdata << 2;
ADC_LOW2 &= 0x03; //清除高6位,保留低2位有效值
adcdata = adcdata + ADC_LOW2;
moni_AD[0][index] = adcdata;
ADC_CONTR = ADC_Power_On_Speed_Channel_1; //选择P1.1为转换通道
delay(10); //延时60us
ADC_DATA = 0;
ADC_CONTR |= 0x08; //启动ADC10
while((ADC_CONTR&0x10) == 0) {} //等待AD转换完毕
ADC_CONTR &= 0xe7; //清0 ADC_FLAG ,ADC_START位 ,停止AD转换
adcdata = ADC_DATA;
adcdata = adcdata << 2;
ADC_LOW2 &= 0x03; //清除高6位,保留低2位有效值
adcdata = adcdata + ADC_LOW2;
moni_AD[1][index] = adcdata;
index=(index+1)%NUM_of_RESULTS;
}
/***********************************************
名称:filter
描述:滤波程序,为平均值滤波法
************************************************/
void filter(void)
{
unsigned char i,j;
unsigned long int t;
for(i=0;i<2;i++)
{
t=0;
for(j=0;j<NUM_of_RESULTS;j++)
t=t+(unsigned long)moni_AD[i][j]; //将采集到的模拟值相加求和
moni[i]=t/NUM_of_RESULTS; //求平均值
}
}
/**************************************************************
名称:judg_err
描述:系统错误判断
入口参数:无
出口参数:无
说明:根据各通道的平均模拟量判断系统故障,并向全局变量赋予相应的故障值
***************************************************************/
void judg_err(void)
{
Temp_Err_Value = 0;
Humi_Err_Value = 0;
if((moni[0] < TempE1_AD) || (moni[0] > TempE2_AD))
Temp_Err_Value = 0x01; //故障值
else if(moni[0] < TempHH_AD_50)
Temp_Err_Value = 0x02; //温度过高值
else if(moni[0] > TempLL_AD_0)
Temp_Err_Value = 0x03; //温度过低值
if((moni[1] < HumiE2_AD) || (moni[1] > HumiE1_AD))
Humi_Err_Value = 0x01; //湿度故障值
else if(moni[1] > HumiHH_AD_90)
Humi_Err_Value = 0x02; //湿度过高值
else if(moni[1] < HumiLL_AD_10)
Humi_Err_Value = 0x03; //湿度过低值
}
/********************************************************
名称:check_humi_ku
描述:根据moni[1]的值在温度表中查出对应的湿度值
入口参数:ADdata ,为ADC12采集到的模拟量moni[1]减温度基准TEMPBASE
出口参数:local , 为humi_table中的位置
*********************************************************/
unsigned int check_ADdata_ku(uint ADdata, uint *ADdata_ku, uint num_ku)
{
unsigned char sign=1;
int local;
unsigned int top=0;
unsigned int bottom = num_ku - 1;
unsigned int mid;
if(ADdata < ADdata_ku[0] || ADdata > ADdata_ku[num_ku-1]) //判断AD值是否超出范围
{
sign=0;
local = -1;
}
while((sign == 1) && (top <= bottom)) //使用对折法查找ADdata在温度表中对应的位置
{
mid = ((top+bottom) >> 1);
if(ADdata == ADdata_ku[mid])
{
local = mid;
sign = 0;
}
else if(ADdata < ADdata_ku[mid])
{
if(ADdata > ADdata_ku[mid-1])
{ local = mid-1;
sign = 0;
}
else
bottom = mid-1;
}
else
{
if(ADdata < ADdata_ku[mid+1])
{ local = mid;
sign = 0;
}
else
top = mid+1;
}
}
return local;
}
/****************************************************************
名称:shiji_temp
描述:求实际温度值并放大10倍
入口参数:
出口参数:无
说明:根据AD采样结果用查表法求出实际对应的温度值()
****************************************************************/
void shiji_temp(void)
{
uchar i;
uint temp; //用于指示moni[0]在表中的位置,也代表整型温度值
uint j,k;
temp = check_ADdata_ku(moni[0]-TEMPBASE, temp_table, N_TEMP_TABLE ); //求moni[0]在表中的位置
tempture = temp * 10; //求实际整型温度值扩大10倍放入全局变量tempture中
j = (temp_table[temp+1] - temp_table[temp]); //此温度值的相邻AD间隔差值
k = (moni[0]-temp_table[temp]-TEMPBASE) * 10; //求实际AD值与区间初值的差(对应小数部分)
for(i = 1;i < 10;i++)
{
if(k >= i * j) //求小数部分,分辨力0.1
tempture=tempture + 1;
else
break;
}
if(tempture >= 510)
tempture = 0;
else
tempture = 510 - tempture;
}
/****************************************************************
名称:shiji_humi
描述:求实际湿度值并放大10倍
入口参数:
出口参数:无
说明:根据AD采样结果用查表法求出实际对应的温度值()
****************************************************************/
void shiji_humi(void)
{
unsigned char i;
unsigned int humi; //用于指示moni[1]在表中的位置,也代表整型湿度值
unsigned int j,k;
if(tempture >= 350)
{
humi = check_ADdata_ku(moni[1]-TEMPBASE, humidity_table1, N_HUMI_TABLE); //求moni[0]在表中的位置
huminity = 20 + humi * 5; //求整型湿度
j = (humidity_table1[humi + 1] - humidity_table1[humi]); //此区间相邻间隔的差
k = (moni[1] - humidity_table1[humi] - HUMIBASE)*5; //求实际湿度AD与区间初值的差扩大5倍
for(i=1;i<5;i++)
{
if(k >= i*j)
huminity = huminity + 1;
else
break;
}
}
else
{
humi = check_ADdata_ku(moni[1]-TEMPBASE, humidity_table2, N_HUMI_TABLE);
huminity = 20 + humi * 5; //求整型湿度
j = (humidity_table2[humi + 1] - humidity_table2[humi]); //此区间相邻间隔的差
k = (moni[1] - humidity_table2[humi] - HUMIBASE)*5; //求实际湿度AD与区间初值的差扩大5倍
for(i=1;i<5;i++)
{
if(k >= i*j)
huminity = huminity + 1;
else
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -