ADCC外设除了ADC转换之外,还提供了很多实用的计算处理功能。这些计算是在ADC转换结果基础上来完成的,是ADC转换的后处理,可以对连续若干采集结果进行初步整理。 计算的结果,还用来进行门限判断,可以配置成只有超限的数据出现时才触发中断。
1. 功能原理
MCC的计算功能配置界面如下:
计算功能框图:
计算功能由硬件来完成。只要在操作模式下拉框里,选择一种计算模式,就能启动相应的计算功能。无需过多配置。具体应该选择哪一种?根据需要选择。
计算功能可包括三部分:
- 1. 累加/平均/滤波
- 2. 误差计算
- 3. 逻辑计算 – 门限比较
累加/平均/滤波
累加模式:注意累计次数,以防结果溢出。累计寄存器ACC为16位,ADC结果寄存器12位。所以累计次数在16次以内,是不会溢出的。超过16次,要根据应用中输入模拟量的大小范围确定。
平均模式:每次软件或事件触发ADCC,加入一个新的ADC值。对于N次平均,需要N次ADCC转换触发。
突发平均模式:一次软件或事件触发后,ADCC连续做N次采集,然后平均。只需一次触发即可完成一次突发平均计算。
低通滤波器模式:利用累加寄存器ACC与滤波寄存器FILT的多次迭代计算来实现。每次迭代计算,都包含有对以前数据的移位操作。移位的位数决定了滤波器的通带带宽和对噪声的敏感性。一般移位次数小带宽大,对噪声敏感;位数大,则带宽小,一直噪声能力强。
误差计算
有多种模式:
– 单次测量结果的一阶导数
– CVD 模式下的CVD 结果
– 当前结果与设定值之差
– 当前结果与滤波后的结果/平均值计算结果之差
– 滤波后的值/平均值的一阶导数
– 滤波后的值/平均值与设定值之差
比较常用的是,当前结果或滤波后结果与设定值之差。
门限比较
也包含很多种方式:
– 永不中断
– 误差小于阈值下限
– 误差大于或等于阈值下限
– 误差介于阈值上限和阈值下限之间(包含上限和下限)
– 误差超出阈值
– 误差小于或等于阈值上限
– 误差大于阈值上限
– 无论阈值测试结果如何,始终中断
– 如果满足阈值条件,则阈值中断标志ADTIF 置1。
2. 代码解读
MCC生成代码后,ADCC的代码都存在于 adcc.c文件中。
设定采集/计算重复的次数,即计算用到的数据样本数。
void ADCC_SetRepeatCount(uint8_t repeatCount)
{
//Load the ADRPT register.
ADRPT = repeatCount;
}
已经进行的采集/计算次数。
uint8_t ADCC_GetCurrentCountofConversions(void)
{
//Return the contents of ADCNT register
return ADCNT;
}
获取累加器的值。
uint24_t ADCC_GetAccumulatorValue(void)
{
//Return the contents of ADACCU, ADACCH and ADACCL registers
return (((uint24_t)ADACCU << 16)+((uint24_t)ADACCH << 8) + ADACCL);
}
获取滤波后的值。
uint16_t ADCC_GetFilterValue(void)
{
//Return the contents of ADFLTRH and ADFLTRL registers
return ((uint16_t)((ADFLTRH << 8) + ADFLTRL));
}
误差计算设定值。
void ADCC_DefineSetPoint(uint16_t setPoint)
{
//Sets the ADSTPTH and ADSTPTL registers
ADSTPTH = setPoint >> 8;
ADSTPTL = setPoint;
}
获得误差计算值
uint16_t ADCC_GetErrorCalculation(void)
{
//Return the contents of ADERRH and ADERRL registers
return ((uint16_t)((ADERRH << 8) + ADERRL));
}
设置比较上、下比较门限
void ADCC_SetUpperThreshold(uint16_t upperThreshold)
{
//Sets the ADUTHH and ADUTHL registers
ADUTHH = upperThreshold >> 8;
ADUTHL = upperThreshold;
}
void ADCC_SetLowerThreshold(uint16_t lowerThreshold)
{
//Sets the ADLTHH and ADLTHL registers
ADLTHH = lowerThreshold >> 8;
ADLTHL = lowerThreshold;
}
门限超限中断处理函数。采用用户回调函数的形式,组织代码架构。
void ADCC_ThresholdISR(void)
{
// Clear the ADCC Threshold interrupt flag
PIR1bits.ADTIF = 0;
if (ADCC_ADTI_InterruptHandler)
ADCC_ADTI_InterruptHandler();
}
void ADCC_SetADTIInterruptHandler(void (* InterruptHandler)(void)){
ADCC_ADTI_InterruptHandler = InterruptHandler;
}
void ADCC_DefaultInterruptHandler(void){
// add your ADCC interrupt custom code
// or set custom function using ADCC_SetADIInterruptHandler() or ADCC_SetADTIInterruptHandler()
}
|