打印

采样结果错误

[复制链接]
1167|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangpe|  楼主 | 2021-4-12 19:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

PIC18F25K80定时1ms多通道ADC采集

使用特权

评论回复
沙发
chenho| | 2021-4-12 19:24 | 只看该作者
什么意思?不是很明白你说的什么,能再解释一下这个现象吗

使用特权

评论回复
板凳
wangpe|  楼主 | 2021-4-12 19:27 | 只看该作者
开始考虑的是判断AD状态转换位while (ADCON0bits.GO_nDONE),这种方式可以正常读取转换结果,但是隐隐觉得这种方式不可靠,然后就考虑用定时器,结果不能正常读取。

使用特权

评论回复
地板
wenfen| | 2021-4-12 19:35 | 只看该作者
程序设计思路是啥能说下吗

使用特权

评论回复
5
wangpe|  楼主 | 2021-4-12 19:38 | 只看该作者
1ms定时执行AdcPro,读取A通道结果,通道索引切换到B通道启动转换,读取B通道结果,通道索引切换到C通道启动转换,读取C通道结果,通道索引切换到A通道启动转换,一个循环后采样次数++。

使用特权

评论回复
6
tian111| | 2021-4-12 19:40 | 只看该作者
楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因

使用特权

评论回复
7
wangpe|  楼主 | 2021-4-12 19:42 | 只看该作者

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

使用特权

评论回复
8
wangpe|  楼主 | 2021-4-12 19:44 | 只看该作者
补充一下,只有ADC_CHS_CURRENT_L通道采样结果正常,如果不进行通道转换的话每一路采样结果正常

使用特权

评论回复
9
gongche| | 2021-4-12 19:46 | 只看该作者
为什么觉得隐隐约约不可靠?

使用特权

评论回复
10
xxrs| | 2021-4-12 19:48 | 只看该作者
是因为怕一直在while()循环里面不出来吗?

使用特权

评论回复
11
bqyj| | 2021-4-12 19:50 | 只看该作者
如果是的,你可以加一些超时处理,这样可以增加代码的健壮性

使用特权

评论回复
12
wangpe|  楼主 | 2021-4-12 19:52 | 只看该作者
理论上我这种方式也可以啊

使用特权

评论回复
13
jlyuan| | 2021-4-12 19:54 | 只看该作者
如果因为意外情况 1ms的时候 AD还没采样结束或者是AD异常怎么办呢

使用特权

评论回复
14
stly| | 2021-4-12 19:57 | 只看该作者
异常情况先不考虑,正常情况下1ms时间应该够了

使用特权

评论回复
15
wangpe|  楼主 | 2021-4-12 19:59 | 只看该作者
怎么会犯这种错误 else if(index = ADC_CHS_CURRENT_R)//右边踏板堵转电流采集改成else if(index == ADC_CHS_CURRENT_R)//右边踏板堵转电流采集

使用特权

评论回复
16
wangpe|  楼主 | 2021-4-12 20:00 | 只看该作者
嗯,预料中的结果,多谢大家啦

使用特权

评论回复
17
coshi| | 2021-5-11 14:33 | 只看该作者
错在哪里了啊  说清楚啊

使用特权

评论回复
18
aoyi| | 2021-5-11 14:33 | 只看该作者
用了多少个通道啊

使用特权

评论回复
19
drer| | 2021-5-11 14:34 | 只看该作者
怎么会犯这种低级错误

使用特权

评论回复
20
gwsan| | 2021-5-11 14:38 | 只看该作者
采样频率是不是不够啊

使用特权

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

本版积分规则

938

主题

9837

帖子

2

粉丝