采样结果错误

[复制链接]
125|15
 楼主 | 2020-1-1 14:04 | 显示全部楼层 |阅读模式
PIC18F25K80定时1ms多通道ADC采集

使用特权

评论回复
| 2020-1-1 14:08 | 显示全部楼层

什么意思?不是很明白你说的什么,能再解释一下这个现象吗

使用特权

评论回复
 楼主 | 2020-1-1 14:11 | 显示全部楼层
开始考虑的是判断AD状态转换位while (ADCON0bits.GO_nDONE),这种方式可以正常读取转换结果,但是隐隐觉得这种方式不可靠,然后就考虑用定时器,结果不能正常读取。

使用特权

评论回复
| 2020-1-1 14:14 | 显示全部楼层
程序设计思路是啥能说下吗

使用特权

评论回复
 楼主 | 2020-1-1 14:17 | 显示全部楼层
1ms定时执行AdcPro,读取A通道结果,通道索引切换到B通道启动转换,读取B通道结果,通道索引切换到C通道启动转换,读取C通道结果,通道索引切换到A通道启动转换,一个循环后采样次数++。

使用特权

评论回复
| 2020-1-1 14:22 | 显示全部楼层

楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因

使用特权

评论回复
 楼主 | 2020-1-1 14:26 | 显示全部楼层

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;
}

使用特权

评论回复
 楼主 | 2020-1-1 14:30 | 显示全部楼层
补充一下,只有ADC_CHS_CURRENT_L通道采样结果正常,如果不进行通道转换的话每一路采样结果正常

使用特权

评论回复
| 2020-1-1 14:33 | 显示全部楼层

为什么觉得隐隐约约不可靠?

使用特权

评论回复
| 2020-1-1 14:36 | 显示全部楼层
是因为怕一直在while()循环里面不出来吗?

使用特权

评论回复
| 2020-1-1 14:40 | 显示全部楼层
如果是的,你可以加一些超时处理,这样可以增加代码的健壮性

使用特权

评论回复
 楼主 | 2020-1-1 14:50 | 显示全部楼层
理论上我这种方式也可以啊

使用特权

评论回复
| 2020-1-1 14:52 | 显示全部楼层
如果因为意外情况 1ms的时候 AD还没采样结束或者是AD异常怎么办呢

使用特权

评论回复
 楼主 | 2020-1-1 14:56 | 显示全部楼层
异常情况先不考虑,正常情况下1ms时间应该够了

使用特权

评论回复
 楼主 | 2020-1-1 15:02 | 显示全部楼层
怎么会犯这种错误 else if(index = ADC_CHS_CURRENT_R)//右边踏板堵转电流采集改成else if(index == ADC_CHS_CURRENT_R)//右边踏板堵转电流采集

使用特权

评论回复
 楼主 | 2020-1-1 15:05 | 显示全部楼层

嗯,预料中的结果,多谢大家啦

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表