呐咯密密 发表于 2020-11-16 16:16:57

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

在使用MKV30的时候遇到问题,现在需要使用MKV30的ADC的差分输入功能,到使用DMA来获取数据。在一番折腾之后有问题,

结合SDK以及论坛的帖子写了一个MKV30的ADC的DMA差分输入,debug时候发现可以采集到电压,但是DMA的接收缓存数组g_adc16SampleDataArray只有第一个有数据,后面都是空的。我在主函数循环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;
/***********************************************************************************************************************
* 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 = {
{
    .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);
/* Enable DMA. */
ADC16_EnableDMA(ADC0_PERIPHERAL, true);
}

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

void DifferentialSample_DC(void)
{
       ADC_Differential_DC_Channel_Config();
      ADC16_SetChannelConfig(ADC0_PERIPHERAL, 0U, &ADC0_channelsConfig);
//      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();
}

motor_control 发表于 2020-11-17 08:00:35

飞思卡尔的好是好,就是对小客户不太友好。

呐咯密密 发表于 2020-11-17 09:57:23

motor_control 发表于 2020-11-17 08:00
飞思卡尔的好是好,就是对小客户不太友好。

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

motor_control 发表于 2020-11-17 11:17:20

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

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

呐咯密密 发表于 2020-11-17 13:13:27

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

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

motor_control 发表于 2020-11-17 22:41:22

本帖最后由 motor_control 于 2020-11-18 08:49 编辑

呐咯密密 发表于 2020-11-17 13:13
飞思卡尔的代理简直屌的不行,只有芯片,没有任何支持,爱用不用

飞思卡尔的芯片确实该他屌,但是卖芯片的国内销售就没必要吊了。在公司里,最恶心的就是那些喜欢和老外一起共用咖啡机喝咖啡的吊毛,明明昨天都是喝立顿的。
页: [1]
查看完整版本: 飞思卡尔的MKV30的ADC差分输入,使用DMA。