打印
[技术问答]

新塘M487多通道ADC采集问题,不能为0

[复制链接]
3861|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
plan_1|  楼主 | 2021-6-3 16:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 plan_1 于 2021-6-3 17:03 编辑

现有问题就是 采用软件触发多通道采集ADC,开启了PB的所有通道,通道直接接GND都不能为0之所以用软件触发,就是不想用中断触发AD
时钟配置为clock配置工具配置的,具体见图

引脚配置也是工具生成的,如下图

#include "M487EADC.h"

uint32_t ADCpin = BIT15 | BIT14 | BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0;
uint32_t ADCInputModePin = 0xcfff;
//uint32_t ADCpin = BIT7|BIT6;

void M487EADC_Init(void)
{
  /*复位EADC控制器*/
//  EADC_CONV_RESET(EADC);
        
        /* Set PB.0 ~ PB.3 to input mode */
  PB->MODE &= ~ADCInputModePin;
//        GPIO_SetMode(PB,ADCInputModePin,GPIO_MODE_INPUT);
  /* Set reference voltage to external pin (3.3V) */
  SYS_SetVRef(SYS_VREFCTL_VREF_PIN);
  /* Enable temperature sensor */
  SYS->IVSCTL |= (SYS_IVSCTL_VTEMPEN_Msk  |SYS_IVSCTL_VBATUGEN_Msk);
  /*ADC 结果位数选择12位ADC 结果存入RESULT (EADC_DATn[11:0]).*/
  EADC->CTL &= (~EADC_CTL_RESSEL_Msk);
  EADC->CTL |= EADC_CTL_RESSEL_Msk;
  /* 将输入模式设置为单端并启用A/D转换器 */
  EADC_Open(EADC, EADC_CTL_DIFFEN_SINGLE_END);

  /*设置ADC的触发方式为软件触发*/
  EADC_ConfigSampleModule(EADC, 0, EADC_SOFTWARE_TRIGGER, 0);
  EADC_ConfigSampleModule(EADC, 1, EADC_SOFTWARE_TRIGGER, 1);
  EADC_ConfigSampleModule(EADC, 2, EADC_SOFTWARE_TRIGGER, 2);
  EADC_ConfigSampleModule(EADC, 3, EADC_SOFTWARE_TRIGGER, 3);
  EADC_ConfigSampleModule(EADC, 4, EADC_SOFTWARE_TRIGGER, 4);
  EADC_ConfigSampleModule(EADC, 5, EADC_SOFTWARE_TRIGGER, 5);
  EADC_ConfigSampleModule(EADC, 6, EADC_SOFTWARE_TRIGGER, 6);
  EADC_ConfigSampleModule(EADC, 7, EADC_SOFTWARE_TRIGGER, 7);
  EADC_ConfigSampleModule(EADC, 8, EADC_SOFTWARE_TRIGGER, 8);
  EADC_ConfigSampleModule(EADC, 9, EADC_SOFTWARE_TRIGGER, 9);
  EADC_ConfigSampleModule(EADC, 10, EADC_SOFTWARE_TRIGGER, 10);
  EADC_ConfigSampleModule(EADC, 11, EADC_SOFTWARE_TRIGGER, 11);
  EADC_ConfigSampleModule(EADC, 14, EADC_SOFTWARE_TRIGGER, 14);
  EADC_ConfigSampleModule(EADC, 15, EADC_SOFTWARE_TRIGGER, 15);

  EADC_ConfigSampleModule(EADC, 16, EADC_SOFTWARE_TRIGGER, 16);
  EADC_ConfigSampleModule(EADC, 17, EADC_SOFTWARE_TRIGGER, 17);
  EADC_ConfigSampleModule(EADC, 18, EADC_SOFTWARE_TRIGGER, 18);

  /*设置ADC延长采样时间。*/
  //  EADC_SetExtendSampleTime(EADC, 0, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 1, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 2, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 3, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 4, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 5, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 6, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 7, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 8, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 9, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 10, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 11, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 14, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 15, 0xF);

  //  EADC_SetExtendSampleTime(EADC, 16, 0xF);
  //  EADC_SetExtendSampleTime(EADC, 17, 0x3F);
  //  EADC_SetExtendSampleTime(EADC, 18, 0xF);

  EADC_SetTriggerDelayTime(EADC, 0, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 1, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 2, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 3, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 4, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 5, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 6, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 7, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 8, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 9, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 10, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 11, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 14, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 15, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
        
        EADC_SetTriggerDelayTime(EADC, 16, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 17, 0x3f, EADC_SCTL_TRGDLYDIV_DIVIDER_16);
  EADC_SetTriggerDelayTime(EADC, 18, 0xf, EADC_SCTL_TRGDLYDIV_DIVIDER_16);

  
  /* 禁用GPB0-GPB11,GPB14、GPB15数字输入路径以避免泄漏电流 */
  GPIO_DISABLE_DIGITAL_PATH(PB, ADCpin);
        /* 开启ADC软件触发模式,参数BIT对应相应的通道 */
//  EADC_START_CONV(EADC, ADCpin | BIT16 | BIT17 | BIT18);
}

然后main函数中 使用如下:
int main()
{
                uint16_t Band_gap,Temperature;
//    SYS_Init();
          M487JIDAE_ClockConfigure_init();
                M487JIDAE_PinConfigure_init();
    /* Init UART to 115200-8n1 for print message */
    M487UART_Init(UART0, UART0_IRQn);
                M487UART_Init(UART1, UART1_IRQn);
                M487UART_Init(UART2, UART2_IRQn);
                M487EADC_Init();
                M487TIMER_Init();
    /* Connect UART to PC, and open a terminal tool to receive following message */
    printf("Hello World\n");
                printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

    printf("+-------------------------------------------------+\n");
    printf("|    PH.0(Output) PH.1(Output) PH.2(Output)     |\n");
    printf("+-------------------------------------------------+\n\n");

    /*-----------------------------------------------------------------------------------------------------*/
    /* GPIO Basic Mode Test --- Use Pin Data Input/Output to control GPIO pin                              */
    /*-----------------------------------------------------------------------------------------------------*/

    /* Configure PB.3 as Output mode and PD.8 as Input mode then close it */
    GPIO_SetMode(PH, BIT0, GPIO_MODE_OUTPUT);
    GPIO_SetMode(PH, BIT1, GPIO_MODE_OUTPUT);
                GPIO_SetMode(PH, BIT2, GPIO_MODE_OUTPUT);
               
               
                /* Configure PB.3 and PD.8 to default Quasi-bidirectional mode */
//    GPIO_SetMode(PB, BIT3, GPIO_MODE_QUASI);
//    GPIO_SetMode(PD, BIT8, GPIO_MODE_QUASI);
               
    /* Got no where to go, just loop forever */
               
                /* 开启ADC软件触发模式,参数BIT对应相应的通道 */
                EADC_START_CONV(EADC, ADCpin|BIT16|BIT17|BIT18);
    while(1)
                {
                                
//                        printf("PH0 Delay 1 second\n");
//                        PH0=~PH0;
//                        TIMER_Delay(TIMER0, 1000000);
//                        printf("PH1 Delay 1 second\n");
//                        PH1=~PH1;
//                        TIMER_Delay(TIMER0, 1000000);
//                        printf("PH2 Delay 1 second\n");
                        /* 查询相应通道是否转换完毕 */
                        if((EADC_GET_PENDING_CONV(EADC)&ADCpin) == 0)
                        {
                                printf("EADC_GET_PENDING_CONV=:%x\n",EADC_GET_PENDING_CONV(EADC));
                                printf("ADC0=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 0));
                                printf("ADC1=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 1));
                                printf("ADC2=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 2));
                                printf("ADC3=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 3));
                                printf("ADC4=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 4));
                                printf("ADC5=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 5));
                                printf("ADC6=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 6));
                                printf("ADC7=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 7));
                                printf("ADC8=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 8));
                                printf("ADC9=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 9));
                                printf("ADC10=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 10));
                                printf("ADC11=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 11));
                                printf("ADC14=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 14));
                                printf("ADC15=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 15));
                                
//                                printf("ADC16=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 16));
                                Band_gap=(uint16_t)EADC_GET_CONV_DATA(EADC, 16);
                                printf("Band-gap = %.2f\n", ((float)Band_gap/4095)*(float)(3.3));
                                Temperature=(uint16_t)EADC_GET_CONV_DATA(EADC, 17);
//                                printf("ADC17=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 17));
                                printf("Temperature = %2.1f\n", (25+(((float)Temperature/4095*3300)-675)/(-1.83)));
                                
                                printf("ADC18=:%d\n",(uint16_t)EADC_GET_CONV_DATA(EADC, 18));
                                /* 开启ADC软件触发模式,参数BIT对应相应的通道 */
                                EADC_START_CONV(EADC, ADCpin|BIT16|BIT17|BIT18);
                        }
打印出来的结果是这样的


各个通过怎么都不能为0,用电位器调节时,只扭一半行程就4095了,还有大半圈没有到头

电路板用的是官方 NuMaker-PFM-M487,

这个问题困扰几天了,求大神解答


使用特权

评论回复
沙发
weifeng90| | 2021-6-4 07:21 | 只看该作者
单通道测试一下

使用特权

评论回复
板凳
yangxiaor520| | 2021-6-4 07:49 | 只看该作者
先试一下单通道采集有无问题

使用特权

评论回复
地板
plan_1|  楼主 | 2021-6-4 09:22 | 只看该作者

单通道也是一样的,任何一个通道都试过

使用特权

评论回复
5
plan_1|  楼主 | 2021-6-4 09:23 | 只看该作者
yangxiaor520 发表于 2021-6-4 07:49
先试一下单通道采集有无问题

单通道也是一样的,任何一个通道都试过

使用特权

评论回复
6
sadicy| | 2021-6-16 09:27 | 只看该作者
我想看一下直接接GND的效果,
万用表量一下实际电压是多少。
要不是实际电压有问题,要不是转换有问题,先排除一半

使用特权

评论回复
7
汽车电子| | 2021-6-19 21:28 | 只看该作者
看看时间配置是否有问题?
如果转换时间足够,根本不需要查询,定时读取结果就可以,读取完多个通道结果,即启动下次转换。

使用特权

评论回复
8
kiwis66| | 2021-7-16 11:13 | 只看该作者
楼主解决了吗?都是这样 的话,是不是哪里出问题了

使用特权

评论回复
9
HanGuang001| | 2022-10-21 19:44 | 只看该作者
你好 楼主 你的问题解决了么? 我也遇到类似的问题  芯片是M481SE8AE  我发现PB有几个通道  传感器输出脚悬空的时候输出输出0.636V     接入PB10通道测量也是0.636V  AD读出来结果也基本是正确的,但传感器接入PB8或9通道,用万用表测量电压就变成6.45V了 AD读出的结果基本也是正确的,但不明白为什么电压增高了

使用特权

评论回复
10
HanGuang001| | 2022-10-21 19:46 | 只看该作者
测试连续和单通道模式 都一样  传感器输出脚对地加电容也都测试了 没有用处   不知道为什么凭空就把传感器输出的电压给抬高了

使用特权

评论回复
11
HanGuang001| | 2022-10-21 19:48 | 只看该作者
而且AD输入通道空载的时候我测量电压在3.7V左右  每个通道还不一样

使用特权

评论回复
12
狗啃模拟| | 2022-10-22 23:10 | 只看该作者
那如果是测试连续、单通道都一样不行,传感器输出脚对地加电容也都不行,会不会不是物理原因。

使用特权

评论回复
13
AloneKaven| | 2022-11-2 22:16 | 只看该作者
要不是实际电压有问题,要不是转换有问题

使用特权

评论回复
14
macpherson| | 2022-11-3 20:26 | 只看该作者
这个存在基准电压的。              

使用特权

评论回复
15
lihuami| | 2022-11-3 20:41 | 只看该作者
M487多通道ADC采集存在通道干扰问题。

使用特权

评论回复
16
sdCAD| | 2022-11-3 21:00 | 只看该作者
信号是否有干扰呢?              

使用特权

评论回复
17
robertesth| | 2022-11-3 21:32 | 只看该作者
增加不同转换通道之间的延时时间吧。

使用特权

评论回复
18
kmzuaz| | 2022-11-5 10:04 | 只看该作者
这个多通道干扰问题,检测你的硬件吧。

使用特权

评论回复
19
everyrobin| | 2022-11-5 11:09 | 只看该作者
很多的时候,这个测量不一定是能满足要求 ,你可以使用其他的ADC模块进行测试的。

使用特权

评论回复
20
updownq| | 2022-11-5 12:05 | 只看该作者
不能为0的话,查看是不是跟周边信号数值一样呢?

使用特权

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

本版积分规则

1

主题

6

帖子

0

粉丝