查看: 1759|回复: 9

[求助] MKV30差分ADC输入电压很奇怪,

[复制链接]
  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
    发表于 2020-11-18 16:44:34 | 显示全部楼层 |阅读模式
    调了很多天把ADC的差分输入搞好了,但是出现了一个很奇怪的问题,在不使用差分输入的时候,采集到的数据是正确的正弦信号,但是使用差分就会出现波形错乱。
    微信图片_20201118164312.png

    #include "ADC.h"
    /*******************************************************************************
    * Definitions
    ******************************************************************************/
    #define DEMO_ADC16_CHANNEL       1U
    #define DEMO_ADC16_CHANNEL_GROUP 0U
    #define DEMO_ADC16_BASEADDR      ADC0
    #define DEMO_DMAMUX_BASEADDR     DMAMUX0
    #define DEMO_DMA_CHANNEL         1U
    #define DEMO_DMA_ADC_SOURCE      40U
    #define DEMO_DMA_BASEADDR        DMA0
    #define ADC16_RESULT_REG_ADDR    0x4003b010U
    #define DEMO_DMA_IRQ_ID          DMA0_IRQn
    #define DEMO_ADC16_SAMPLE_COUNT 8U /* The ADC16 sample count. */
    /*******************************************************************************/
    //#define EXAMPLE_DMA    DMA0
    //#define EXAMPLE_DMAMUX DMAMUX0
    //#define BUFF_LENGTH 4U
    /*******************************************************************************
    * Variables
    ******************************************************************************/
    volatile bool g_Transfer_Done = false; /* DMA transfer completion flag. */
    AT_NONCACHEABLE_SECTION_INIT(uint32_t g_adc16SampleDataArray[8]);
    uint32_t g_avgADCValue = 0U; /* Average ADC value .*/
    edma_handle_t g_EDMA_Handle; /* Edma handler. */
    edma_transfer_config_t g_transferConfig;
    edma_transfer_config_t transferConfig;
    const uint32_t g_Adc16_16bitFullRange = 65536U;
    AT_NONCACHEABLE_SECTION_INIT(uint32_t ADC16_RESULT_REG_ADD[8]) = {0x01,0x02,0x03,0xBB,0x01,0x02,0x03,0x23};
    AT_NONCACHEABLE_SECTION_INIT(uint32_t srcAddr[4])  = {0x11, 0x22, 0x33, 0x44};
    AT_NONCACHEABLE_SECTION_INIT(uint32_t destAddr[4]) = {0x00, 0x00, 0x00, 0x00};
    static void Edma_Callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
    {
        /* Clear Edma interrupt flag. */
        EDMA_ClearChannelStatusFlags(DEMO_DMA_BASEADDR, DEMO_DMA_CHANNEL, kEDMA_InterruptFlag);
        /* Setup transfer */
            EDMA_PrepareTransfer_For_ADC(&transferConfig, (void *)ADC16_RESULT_REG_ADDR, sizeof(uint32_t),
                                             (void *)g_adc16SampleDataArray, sizeof(uint32_t), sizeof(uint32_t),
                                             sizeof(g_adc16SampleDataArray), kEDMA_PeripheralToMemory);
        EDMA_SetTransferConfig_For_ADC(DEMO_DMA_BASEADDR, DEMO_DMA_CHANNEL, &transferConfig, NULL);
        /* Enable transfer. */
        EDMA_StartTransfer_For_ADC(&g_EDMA_Handle);
        g_Transfer_Done = true;
                if (transferDone)
        {
            g_Transfer_Done = true;
        }
    }
    void EDMA_Callback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
    {
        if (transferDone)
        {
            g_Transfer_Done = true;
        }
    }
    //const edma_config_t DMA_config = {
    //  .enableContinuousLinkMode = false,
    //  .enableHaltOnError = false,
    //  .enableRoundRobinArbitration = false,
    //  .enableDebugMode = false
    //};
    void DMAMUX_Configuration(void)
    {

    }

    void EDMA_Configuration(void)
    {

        edma_config_t userConfig;
                /* Configure DMAMUX */
        DMAMUX_Init(DMAMUX);
        DMAMUX_SetSource(DMAMUX, 1, 40); /* Map ADC source to channel 0 */
        DMAMUX_EnableChannel(DMAMUX, 1);
        EDMA_GetDefaultConfig(&userConfig);
        EDMA_Init(DMA0, &userConfig);
        EDMA_CreateHandle(&g_EDMA_Handle, DMA0, 1);
        EDMA_SetCallback(&g_EDMA_Handle, Edma_Callback, NULL);
            /*eDMA传输结构配置*/
    //    EDMA_PrepareTransfer_For_ADC(&transferConfig, srcAddr, sizeof(srcAddr[0]), destAddr, sizeof(destAddr[0]),
    //                         sizeof(srcAddr[0]), sizeof(srcAddr), kEDMA_MemoryToMemory);
            EDMA_PrepareTransfer_For_ADC(&transferConfig, (void *)ADC16_RESULT_REG_ADDR, sizeof(uint32_t),
                                             (void *)g_adc16SampleDataArray, sizeof(uint32_t), sizeof(uint32_t),
                                             sizeof(g_adc16SampleDataArray), kEDMA_PeripheralToMemory);
        EDMA_SubmitTransfer_For_ADC(&g_EDMA_Handle, &transferConfig);
        /* Enable interrupt when transfer is done. */
        EDMA_EnableChannelInterrupts(DEMO_DMA_BASEADDR, DEMO_DMA_CHANNEL, kEDMA_MajorInterruptEnable);
    #if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT
        /* Enable async DMA request. */
        EDMA_EnableAsyncRequest(DEMO_DMA_BASEADDR, DEMO_DMA_CHANNEL, true);
    #endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */
        /* Enable transfer. */
        EDMA_StartTransfer_For_ADC(&g_EDMA_Handle);


    }
    /***********************************************************************************************************************
    * ADC0 initialization code
    **********************************************************************************************************************/

    adc16_channel_config_t ADC0_channelsConfig[1] = {
      {
        .channelNumber = 1U,
        .enableDifferentialConversion = true,  //差分模式
        .enableInterruptOnConversionCompleted = true,
      }
    };
    const adc16_config_t ADC0_config = {
      .referenceVoltageSource = kADC16_ReferenceVoltageSourceVref,
      .clockSource = kADC16_ClockSourceAsynchronousClock,
      .enableAsynchronousClock = true,
      .clockDivider = kADC16_ClockDivider8,
      .resolution = kADC16_ResolutionSE16Bit,
      .longSampleMode = kADC16_LongSampleDisabled,
      .enableHighSpeed = true,
      .enableLowPower = false,
      .enableContinuousConversion = true//连续的转换
    };
    const adc16_channel_mux_mode_t ADC0_muxMode = kADC16_ChannelMuxA;
    const adc16_hardware_average_mode_t ADC0_hardwareAverageMode = kADC16_HardwareAverageCount8;

    void ADC0_init(void) {
      /* Initialize ADC16 converter */
      ADC16_Init(ADC0_PERIPHERAL, &ADC0_config);
      /* Make sure, that software trigger is used */
      ADC16_EnableHardwareTrigger(ADC0_PERIPHERAL, false);
      /* Configure hardware average mode */
      ADC16_SetHardwareAverage(ADC0_PERIPHERAL, ADC0_hardwareAverageMode);
      /* Configure channel multiplexing mode */
      ADC16_SetChannelMuxMode(ADC0_PERIPHERAL, ADC0_muxMode);
      /* Initialize channel */
      ADC16_SetChannelConfig(ADC0_PERIPHERAL, 0U, &ADC0_channelsConfig[0]);
      /* Perform auto calibration */
      ADC16_DoAutoCalibration(ADC0_PERIPHERAL);
      /* Enable DMA. */
      ADC16_EnableDMA(ADC0_PERIPHERAL, true);
    }

    最佳答案

    差分时候,变量不要定义成uint类型,差分是有小于0的情况,差分时候,寄存器最高位表示符号位,看RM
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20015
    最后登录
    2024-4-25
    发表于 2020-11-19 09:37:17 | 显示全部楼层
    差分时候,变量不要定义成uint类型,差分是有小于0的情况,差分时候,寄存器最高位表示符号位,看RM
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
     楼主| 发表于 2020-11-19 10:44:12 | 显示全部楼层
    小恩GG 发表于 2020-11-19 09:37
    差分时候,变量不要定义成uint类型,差分是有小于0的情况,差分时候,寄存器最高位表示符号位,看RM ...

    我的输入的电压差分后的范围是0~65535,不存在小于0的,最高位是符号位也不会影响波形成这样吧。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20015
    最后登录
    2024-4-25
    发表于 2020-11-19 14:18:22 | 显示全部楼层
    鹰宫璞爱惟 发表于 2020-11-19 10:44
    我的输入的电压差分后的范围是0~65535,不存在小于0的,最高位是符号位也不会影响波形成这样吧。 ...

    你怎么测差分信号的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
     楼主| 发表于 2020-11-19 14:27:36 | 显示全部楼层
    小恩GG 发表于 2020-11-19 14:18
    你怎么测差分信号的

    示波器测量的,输入信号是经过很多次测试的,两路输入信号是互补的,一个是正弦,一个是余弦,一个在最大值,另一个一定在最小值,最大值是32768,最小值是0,两路信号互补下来最大是65536,最小是0。 微信图片_20201119142703.png
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20015
    最后登录
    2024-4-25
    发表于 2020-11-19 14:34:06 | 显示全部楼层
    鹰宫璞爱惟 发表于 2020-11-19 14:27
    示波器测量的,输入信号是经过很多次测试的,两路输入信号是互补的,一个是正弦,一个是余弦,一个在最大 ...

    第一个半波是dp>dm, 下一个半波是dp<dm出现负数了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
     楼主| 发表于 2020-11-19 14:56:50 | 显示全部楼层
    小恩GG 发表于 2020-11-19 14:34
    第一个半波是dp>dm, 下一个半波是dp

    我忘了说了,我的基准电压是1.6V,所以两个差分之后不会有负数的
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20015
    最后登录
    2024-4-25
    发表于 2020-11-19 15:03:18 | 显示全部楼层
    鹰宫璞爱惟 发表于 2020-11-19 14:56
    我忘了说了,我的基准电压是1.6V,所以两个差分之后不会有负数的

    这跟你基准电压没关系,差分值始终都是dp-dm. 到后半周,dp-dm<0就会是负数 1.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2021-1-15 10:56
  • 签到天数: 39 天

    [LV.5]常住居民I

    21

    主题

    116

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    436
    最后登录
    2021-10-9
     楼主| 发表于 2020-11-20 12:09:45 | 显示全部楼层
    小恩GG 发表于 2020-11-19 15:03
    这跟你基准电压没关系,差分值始终都是dp-dm. 到后半周,dp-dm

    感谢小恩GG的帮助,确实是有负的,单片机输出直接输出了补码,导致数据出错,我做一下处理就完美输出了,这段时间感谢小恩GG的帮助。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8

    主题

    27

    帖子

    0

    注册会员

    Rank: 2

    积分
    148
    最后登录
    2022-5-12
    发表于 2021-11-16 15:08:15 | 显示全部楼层
    小恩GG 发表于 2020-11-19 14:18
    你怎么测差分信号的

    版主好专业啊
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-25 19:24 , Processed in 0.150254 second(s), 32 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表