[PIC®/AVR®/dsPIC®产品] 采样结果错误

[复制链接]
1121|26
 楼主| wangpe 发表于 2022-11-11 20:34 | 显示全部楼层 |阅读模式
PIC18F25K80定时1ms多通道ADC采集
 楼主| wangpe 发表于 2022-11-11 20:39 | 显示全部楼层
开始考虑的是判断AD状态转换位while (ADCON0bits.GO_nDONE),这种方式可以正常读取转换结果,但是隐隐觉得这种方式不可靠,然后就考虑用定时器,结果不能正常读取。
wenfen 发表于 2022-11-11 20:41 | 显示全部楼层
程序设计思路是啥能说下吗
 楼主| wangpe 发表于 2022-11-11 20:43 | 显示全部楼层
1ms定时执行AdcPro,读取A通道结果,通道索引切换到B通道启动转换,读取B通道结果,通道索引切换到C通道启动转换,读取C通道结果,通道索引切换到A通道启动转换,一个循环后采样次数++。
heweibig 发表于 2022-11-11 20:45 | 显示全部楼层
楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因
 楼主| wangpe 发表于 2022-11-11 20:47 | 显示全部楼层

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;
}
更多操作
 楼主| wangpe 发表于 2022-11-11 20:49 | 显示全部楼层
补充一下,只有ADC_CHS_CURRENT_L通道采样结果正常,如果不进行通道转换的话每一路采样结果正常
zwll 发表于 2022-11-11 20:54 | 显示全部楼层
为什么觉得隐隐约约不可靠?
huwr 发表于 2022-11-11 20:56 | 显示全部楼层

是因为怕一直在while()循环里面不出来吗?
huangchui 发表于 2022-11-11 20:58 | 显示全部楼层
如果是的,你可以加一些超时处理,这样可以增加代码的健壮性
 楼主| wangpe 发表于 2022-11-11 21:00 | 显示全部楼层
理论上我这种方式也可以啊
huwr 发表于 2022-11-11 21:03 | 显示全部楼层
如果因为意外情况 1ms的时候 AD还没采样结束或者是AD异常怎么办呢
wenfen 发表于 2022-11-11 21:05 | 显示全部楼层
异常情况先不考虑,正常情况下1ms时间应该够了
 楼主| wangpe 发表于 2022-11-11 21:07 | 显示全部楼层
怎么会犯这种错误 else if(index = ADC_CHS_CURRENT_R)//右边踏板堵转电流采集改成else if(index == ADC_CHS_CURRENT_R)//右边踏板堵转电流采集
dengdc 发表于 2022-11-11 21:11 | 显示全部楼层
用了多少个通道啊
jiahy 发表于 2022-11-11 21:14 | 显示全部楼层
怎么会犯这种低级错误
xxrs 发表于 2022-11-11 21:16 | 显示全部楼层
采样频率是不是不够啊
tian111 发表于 2022-11-11 21:18 | 显示全部楼层
读取寄存器读错了吧
dingy 发表于 2022-11-11 21:24 | 显示全部楼层
是顺序采样还是同步采样?
huanghuac 发表于 2022-11-11 21:26 | 显示全部楼层
ADC配置有问题?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

938

主题

9837

帖子

2

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