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

PIC18F25K80定时1ms多通道ADC采集,采样结果错误

[复制链接]
2699|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cyhuaxiang|  楼主 | 2017-7-26 15:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
        开始考虑的是判断AD状态转换位while (ADCON0bits.GO_nDONE),这种方式可以正常读取转换结果,但是隐隐觉得这种方式不可靠,然后就考虑用定时器,结果不能正常读取。程序设计思路:1ms定时执行AdcPro,读取A通道结果,通道索引切换到B通道启动转换,读取B通道结果,通道索引切换到C通道启动转换,读取C通道结果,通道索引切换到A通道启动转换,一个循环后采样次数++。
FOSC = 32Mhz
ADC初始化
/*
*********************************************************************************************************
*        函 数 名: ADC_Init
*        功能说明: ADC初始化
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void ADC_Init()
{
    VBAT_SEN_EN_SetDigitalOutput();
    VHALL_SEN_EN_SetDigitalOutput();         
    TRISA = 0xFF; //PORTA as input
    ANCON0 = 0X0F; //引脚配置为模拟通道

    ADCON1 = 0x00; // 外部正参考电压,AVdd为负电压,模拟反相通道为AVss
    ADCON2 = 0xA9; // FOSC/8 as conversion clock, Result is right justified,Aquisition time of 12 TAD   
    ADC_StartConversion(ADC_CHS_VBAT);
}

ADC处理
/*
*********************************************************************************************************
*        函 数 名: AdcPro
*        功能说明: ADC滤波处理
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void AdcPro(void)
{
        static uint16_t buf[ADC_SAMP_CNT][ADC_CHS_NUM];// ADC_SAMP_CNT = 3,ADC_CHS_NUM = 3
        static uint8_t write = 0;
        static uint8_t index = ADC_CHS_VBAT;
        uint16_t sum;
        uint8_t i;

    if(index == ADC_CHS_VBAT)//电池电压采集
    {
        buf[write][ADC_CHS_VBAT] = ADC_GetConversionValue();

        /* 下面这段代码采用求平均值的方法进行滤波
            也可以改善下,选择去掉最大和最下2个值,使数据更加精确
        */
        sum = 0;
        for (i = 0; i < ADC_SAMP_CNT; i++)
        {
            sum += buf[i][ADC_CHS_VBAT];
        }
        SysRunData.ADC_Buf[ADC_CHS_VBAT] = sum / ADC_SAMP_CNT;        /* ADC采样值由若干次采样值平均 */
        index = ADC_CHS_CURRENT_R;
        ADC_StartConversion(ADC_CHS_CURRENT_R);        /* 软件启动下次ADC转换 */
    }
    else if(index = ADC_CHS_CURRENT_R)//右边踏板堵转电流采集
    {
        buf[write][ADC_CHS_CURRENT_R] = ADC_GetConversionValue();
        /* 下面这段代码采用求平均值的方法进行滤波
            也可以改善下,选择去掉最大和最下2个值,使数据更加精确
        */
        sum = 0;
        for (i = 0; i < ADC_SAMP_CNT; i++)
        {
            sum += buf[i][ADC_CHS_CURRENT_R];
        }
        SysRunData.ADC_Buf[ADC_CHS_CURRENT_R] = sum / ADC_SAMP_CNT;        /* ADC采样值由若干次采样值平均 */
        index = ADC_CHS_CURRENT_L;
        ADC_StartConversion(ADC_CHS_CURRENT_L);        /* 软件启动下次ADC转换 */
    }
    else if(index == ADC_CHS_CURRENT_L)//左边踏板堵转电流采集
    {
        buf[write][ADC_CHS_CURRENT_L] = ADC_GetConversionValue();
        if (++write >= ADC_SAMP_CNT)
        {
            write = 0;
        }
        /* 下面这段代码采用求平均值的方法进行滤波
            也可以改善下,选择去掉最大和最下2个值,使数据更加精确
        */
        sum = 0;
        for (i = 0; i < ADC_SAMP_CNT; i++)
        {
            sum += buf[i][ADC_CHS_CURRENT_L];
        }
        SysRunData.ADC_Buf[ADC_CHS_CURRENT_L] = sum / ADC_SAMP_CNT;        /* ADC采样值由若干次采样值平均 */
        index = ADC_CHS_VBAT;
        ADC_StartConversion(ADC_CHS_VBAT);        /* 软件启动下次ADC转换 */
    }
}

读取转换结果函数
uint16_t ADC_GetConversionValue()
{
    // Conversion finished, return the result
    return ((ADRESH << 8) + ADRESL);
}
启动ADC转换
void ADC_StartConversion(uint8_t channel)
{
    // select the A/D channel
    ADCON0bits.CHS = channel;

    // Turn on the ADC module
    ADCON0bits.ADON = 1;
    // Acquisition time delay
//    __delay_us(ACQ_US_DELAY);

    // Start the conversion
    ADCON0bits.GO_NOT_DONE = 1;
}



沙发
cyhuaxiang|  楼主 | 2017-7-26 16:16 | 只看该作者
本帖最后由 cyhuaxiang 于 2017-7-26 17:57 编辑

补充一下,只有ADC_CHS_CURRENT_L通道采样结果正常,如果不进行通道转换的话每一路采样结果正常

使用特权

评论回复
板凳
feelhyq| | 2017-7-26 23:24 | 只看该作者
为什么觉得隐隐约约不可靠?是因为怕一直在while()循环里面不出来吗?

使用特权

评论回复
地板
feelhyq| | 2017-7-26 23:25 | 只看该作者
如果是的,你可以加一些超时处理,这样可以增加代码的健壮性

使用特权

评论回复
5
cyhuaxiang|  楼主 | 2017-7-27 09:20 | 只看该作者
feelhyq 发表于 2017-7-26 23:25
如果是的,你可以加一些超时处理,这样可以增加代码的健壮性

理论上我这种方式也可以啊

使用特权

评论回复
6
feelhyq| | 2017-7-27 09:35 | 只看该作者
cyhuaxiang 发表于 2017-7-27 09:20
理论上我这种方式也可以啊

如果因为意外情况 1ms的时候 AD还没采样结束或者是AD异常怎么办呢

使用特权

评论回复
7
cyhuaxiang|  楼主 | 2017-7-27 10:11 | 只看该作者
feelhyq 发表于 2017-7-27 09:35
如果因为意外情况 1ms的时候 AD还没采样结束或者是AD异常怎么办呢

异常情况先不考虑,正常情况下1ms时间应该够了

使用特权

评论回复
8
cyhuaxiang|  楼主 | 2017-7-27 16:22 | 只看该作者
问题解决了,这个问题浪费了我接近2天的时间真的很无奈,怎么会犯这种错误 else if(index = ADC_CHS_CURRENT_R)//右边踏板堵转电流采集改成else if(index == ADC_CHS_CURRENT_R)//右边踏板堵转电流采集

使用特权

评论回复
9
13249060342| | 2017-10-24 11:43 | 只看该作者
此款芯片我司常备现货库存先到先得,需要的请联系13430885511颜R,谢谢

使用特权

评论回复
10
mcumail| | 2017-10-27 07:53 | 只看该作者
cyhuaxiang 发表于 2017-7-27 16:22
问题解决了,这个问题浪费了我接近2天的时间真的很无奈,怎么会犯这种错误 else if(index = ADC_CHS_CURREN ...

使用特权

评论回复
11
yangzj1974| | 2018-2-13 13:42 | 只看该作者
学习

使用特权

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

本版积分规则

4

主题

53

帖子

3

粉丝