搜索
bottom↓
回复: 5

飞思卡尔的MKV30的ADC差分输入,使用DMA。

[复制链接]

出0入0汤圆

发表于 2020-11-16 16:16:57 | 显示全部楼层 |阅读模式
在使用MKV30的时候遇到问题,现在需要使用MKV30的ADC的差分输入功能,到使用DMA来获取数据。在一番折腾之后有问题,

结合SDK以及论坛的帖子写了一个MKV30的ADC的DMA差分输入,debug时候发现可以采集到电压,但是DMA的接收缓存数组g_adc16SampleDataArray[16]只有第一个有数据,后面都是空的。我在主函数循环void DifferentialSample_DC(void)这个函数,ADC_Value是有值的。

可有偿


#include "ADC.h"
/***********************************************************************************************************************
* BOARD_InitPeripherals functional group
**********************************************************************************************************************/
#define ADC16_RESULT_REG_ADDR    0x4003b010U
#define DEMO_ADC16_SAMPLE_COUNT 16U /* The ADC16 sample count. */

volatile bool g_Transfer_Done = false; /* DMA transfer completion flag. */
edma_transfer_config_t g_transferConfig;
uint32_t g_adc16SampleDataArray[DEMO_ADC16_SAMPLE_COUNT];
/***********************************************************************************************************************
* DMA initialization code
**********************************************************************************************************************/

static void Edma_Callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
    /* Clear Edma interrupt flag. */
    EDMA_ClearChannelStatusFlags(DMA_DMA_BASEADDR, DMA_CH1_DMA_CHANNEL, kEDMA_InterruptFlag);
    /* Setup transfer */
    EDMA_PrepareTransfer(&g_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(DMA_DMA_BASEADDR, DMA_CH1_DMA_CHANNEL, &g_transferConfig, NULL);
    /* Enable transfer. */
    EDMA_StartTransfer(&DMA_CH1_Handle);
    g_Transfer_Done = true;
}

const edma_config_t DMA_config = {
  .enableContinuousLinkMode = false,
  .enableHaltOnError = false,
  .enableRoundRobinArbitration = false,
  .enableDebugMode = false
};
edma_handle_t DMA_CH1_Handle;
edma_handle_t DMA_CH2_Handle;

void ADC_DMA_init(void) {

  /* Channel CH1 initialization */
        DMAMUX_Init(DMAMUX);
  /* Set the source kDmaRequestMux0ADC0 request in the DMAMUX */
  DMAMUX_SetSource(DMA_DMAMUX_BASEADDR, DMA_CH1_DMA_CHANNEL, 40);
  /* Enable the channel 1 in the DMAMUX */
  DMAMUX_EnableChannel(DMA_DMAMUX_BASEADDR, DMA_CH1_DMA_CHANNEL);
  /* Create the eDMA DMA_CH1_Handle handle */
  EDMA_CreateHandle(&DMA_CH1_Handle, DMA_DMA_BASEADDR, DMA_CH1_DMA_CHANNEL);

}
void EDMA_Configuration(void)
{
        edma_config_t userConfig;

    EDMA_GetDefaultConfig(&userConfig);
    EDMA_Init(DMA_DMA_BASEADDR, &userConfig);
    EDMA_CreateHandle(&DMA_CH1_Handle, DMA_DMA_BASEADDR, DMA_CH1_DMA_CHANNEL);
    EDMA_SetCallback(&DMA_CH1_Handle, Edma_Callback, NULL);
    EDMA_PrepareTransfer(&g_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(&DMA_CH1_Handle, &g_transferConfig);
    /* Enable interrupt when transfer is done. */
    EDMA_EnableChannelInterrupts(DMA_DMA_BASEADDR, DMA_CH1_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(DMA_DMA_BASEADDR, DMA_CH1_DMA_CHANNEL, true);
#endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */
    /* Enable transfer. */
    EDMA_StartTransfer(&DMA_CH1_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,
  .clock Source = kADC16_Clock SourceAsynchronousClock,
  .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]);
  /* Enable DMA. */
  ADC16_EnableDMA(ADC0_PERIPHERAL, true);
}

void ADC_Differential_DC_Channel_Config(void)
{
        ADC0_channelsConfig[0].channelNumber = 0;
        ADC0_channelsConfig[0].enableDifferentialConversion =true;
        ADC0_channelsConfig[0].enableInterruptOnConversionCompleted = true;
}
uint32_t ADC_Value = 0;

void DifferentialSample_DC(void)
{
       ADC_Differential_DC_Channel_Config();
      ADC16_SetChannelConfig(ADC0_PERIPHERAL, 0U, &ADC0_channelsConfig[0]);
//        while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(ADC0, 0)))
//        {
//        }
        ADC_Value = ADC16_GetChannelConversionValue(ADC0, 0);
        ADC_Value = ADC_Value*3000/4095;
}
/***********************************************************************************************************************
* Initialization functions
**********************************************************************************************************************/
void ADC_InitPeripherals(void)
{
        ADC_DMA_init();
  EDMA_Configuration();
  ADC0_init();

}

/***********************************************************************************************************************
* BOARD_InitBootPeripherals function
**********************************************************************************************************************/
void ADC_InitBootPeripherals(void)
{
  ADC_InitPeripherals();
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入79汤圆

发表于 2020-11-17 08:00:35 来自手机 | 显示全部楼层
飞思卡尔的好是好,就是对小客户不太友好。

出0入0汤圆

 楼主| 发表于 2020-11-17 09:57:23 | 显示全部楼层
motor_control 发表于 2020-11-17 08:00
飞思卡尔的好是好,就是对小客户不太友好。

太不友好了,十六位的AD,100M的主频,价格还便宜,真心好,但是用起来简直头大,一开始串口通讯时间超时,因为它的库函数写的太啰嗦,删了一大堆库才搞好,现在这个ADC又头疼

出0入79汤圆

发表于 2020-11-17 11:17:20 | 显示全部楼层
呐咯密密 发表于 2020-11-17 09:57
太不友好了,十六位的AD,100M的主频,价格还便宜,真心好,但是用起来简直头大,一开始串口通讯时间超时 ...


一直想用飞思卡尔的KV10系列,但代理商都很屌,干脆不用了。当然,国产芯片原厂更屌,完全不考虑。
还是MICROCHIP,英飞凌的好搞到。STM32什么的迟早会被华强北的芯片贩子给玩死。

出0入0汤圆

 楼主| 发表于 2020-11-17 13:13:27 | 显示全部楼层
motor_control 发表于 2020-11-17 11:17
一直想用飞思卡尔的KV10系列,但代理商都很屌,干脆不用了。当然,国产芯片原厂更屌,完全不考虑。
还是M ...

飞思卡尔的代理简直屌的不行,只有芯片,没有任何支持,爱用不用

出0入79汤圆

发表于 2020-11-17 22:41:22 来自手机 | 显示全部楼层
本帖最后由 motor_control 于 2020-11-18 08:49 编辑
呐咯密密 发表于 2020-11-17 13:13
飞思卡尔的代理简直屌的不行,只有芯片,没有任何支持,爱用不用


飞思卡尔的芯片确实该他屌,但是卖芯片的国内销售就没必要吊了。在公司里,最恶心的就是那些喜欢和老外一起共用咖啡机喝咖啡的吊毛,明明昨天都是喝立顿的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 17:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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