前言
前面我们在根据AD值计算温度时,用到的是二分查找法,此种方法的复杂度为O( log 2 n \log_{2}{n} log2n),如果n较大时,仍然有不小的工作量,因此本文在此方法的基础上进一步改进,减少计算复杂度。
思路
二分法的计算方法如下:
m i d = b e g i n + ( e n d − b e g i n ) / 2 mid = begin + (end - begin)/2 mid=begin+(end−begin)/2
我们可以将 1 2 \frac{1}{2} 21更改为更接近于目标值的位置,一般来说温度与AD值是成反比的,因此我们可以进行如下更改:
m i d = b e g i n + ∗ ( R T t a b l e + b e g i n ) − A d c V a l ∗ ( R T t a b l e + b e g i n ) − ∗ ( R T t a b l e + e n d ) × ( e n d − b e g i n ) mid = begin + \frac{*(RTtable + begin) - AdcVal}{*(RTtable + begin) - *(RTtable + end)} \times (end - begin) mid=begin+∗(RTtable+begin)−∗(RTtable+end)∗(RTtable+begin)−AdcVal×(end−begin)
此时的计算复杂度为O( log 2 ( log 2 n ) ) \log_{2}({\log_{2}{n}})) log2(log2n)),计算度更小。
void FindAdcTemp(u16_t wAdcVal, u8_t *wRTtable, u16_t wTempData)
{
u8_t nBegin = 0;
u8_t nEnd= 0;
u8_t nMiddle = 0;
/* 首先判断是否超出表格的最大最小值 */
nEnd = RT_NUM -1;
if (wAdcVal <= *(wRTtable + nEnd))
{
wTempData = RT_NUM + MINTEMP;
}
else if (wAdcVal >= *(wRTtable + nBegin))
{
wTempData = MINTEMP;
}
else /* 当温度在表格范围内 */
{
while ((nBegin < nEnd) && (wAdcVal != *(wRTtable + nMiddle)))
{
nMiddle = nBegin + (nEnd - nBegin) * (*(wRTtable + begin) - wAdcVal) / (*(wRTtable + begin) - *(wRTtable + end));
if (wAdcVal > *(wRTtable + nMiddle))
{
nEnd = nMiddle - 1;
}
else
{
nBegin = nMiddle + 1;
}
}
wTempData = MINTEMP + (nBegin -1);
/* 接下来要计算当前的值更偏向于前一个还是后一个数 */
if (wAdcVal < *(wRTtable + nBegin -1))
{
wDiffAdcVal = (*(wRTtable + nBegin -1) - wAdcVal)*10;
wDiffAdcVal /= *(wRTtable + nBegin -1) - *(wRTtable + nBegin);
if (wDiffAdcVal >= 5) // 四舍五入
{
wTempData = MINTEMP + nBegin;
}
}
}
}
// 四舍五入
{
wTempData = MINTEMP + nBegin;
}
}
}
}