打印
[PIC®/AVR®/dsPIC®产品]

使用MCC学习PIC单片机 – ADCC 计算功能

[复制链接]
4432|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

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()
}






使用特权

评论回复
沙发
734774645| | 2019-3-25 18:53 | 只看该作者
带汉化注释就爽了,好多简称不知道啥意思。

使用特权

评论回复
板凳
oxygenzz|  楼主 | 2019-3-25 19:05 | 只看该作者
本帖最后由 oxygenzz 于 2019-3-25 19:07 编辑
734774645 发表于 2019-3-25 18:53
带汉化注释就爽了,好多简称不知道啥意思。

您说的简写是寄存器名字吧
寄存器名字都是用简写。

MCC界面的描述和英文版的数据手册是一致的的,打开数据手册,搜索,就可以找到了。


使用特权

评论回复
地板
捉虫天师| | 2019-3-25 23:34 | 只看该作者
厉害,还可以预处理了。s

使用特权

评论回复
5
mnmjmkml| | 2019-3-26 15:18 | 只看该作者
非常不错!有些时候很好用。

使用特权

评论回复
6
CoolSilicon| | 2019-3-29 08:40 | 只看该作者
加油加油!!还有17个MCC模块!

使用特权

评论回复
7
muelfox| | 2021-3-15 09:13 | 只看该作者
NB

使用特权

评论回复
8
jack^wu| | 2021-10-15 15:17 | 只看该作者
我也是这样产生的代码,AD读出来的值是00,高手指点一下呗

使用特权

评论回复
9
forgot| | 2024-5-9 13:30 | 只看该作者
谢谢分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

190

帖子

11

粉丝