问题陈述:K32L2B ADC 无法在一次转换中扫描所有连接的通道。输入通道被复用到 ADC 中,因此您需要将 ADCx_Rn 寄存器设置为要转换的通道号,运行转换,读取结果,然后将该 ADC 中的另一个 ADCx_Rn 设置为下一个要转换的通道。然后可以触发下一次转换。您必须告诉每个转换要转换的输入通道。每次设置新频道并读取先前频道的数据都会消耗大量的CPU核心带宽。
本示例的目标是连续读取 Kinetis K32L2B 的所有 ADC 输入,而无需使用 CPU 内核切换通道和读取单个结果值。
本例中的DMA用于控制所有通道的切换,将一系列测量的结果读入内存缓冲区。
直接内存访问 (DMA) 通道配置为按以下方式写入和读取 ADC 寄存器:
DMA 通道 1 的数据在g_adc16ChannelDataArray中准备 在记忆中准备, DMA 的工作周期如下:
步骤 1首先,使用软件触发启动 DMA 通道 1 传输。这将配置通道并开始转换。
步骤2转换完成后,通过DMA通道0读取结果并存储到结果数组中。通道链接执行通道 1 传输并继续循环。
测量完所有需要的通道(DMA 字节计数器达到 0)后,将调用 DMA 中断,以便通知用户代码。
参见下图描述该过程:
Capture1.PNG
代码:
static void ADC16_Configuration(void)
{
// adc16_config_t adcUserConfig;
ADC16_获取默认配置(&adcUserConfig);
adcUserConfig.分辨率=kADC16_分辨率16位;
adcUserConfig.enableContinuousConversion=假;
adcUserConfig.clockSource = kADC16_ClockSourceAlt0;
adcUserConfig.enableAsynchronousClock = false;
adcUserConfig.clockDivider=kADC16_ClockDivider2;
adcUserConfig.长采样模式 = kADC16_LongSampleCycle24;
adcUserConfig.enableLowPower=假;
#if ((定义BOARD_ADC_USE_ALT_VREF) && BOARD_ADC_USE_ALT_VREF)
adcUserConfig.参考电压源= kADC16_ReferenceVoltageSourceValt;
#结束
ADC16_Init(DEMO_ADC16_BASEADDR, &adcUserConfig);
ADC16_设置硬件平均值(DEMO_ADC16_BASEADDR,kADC16_HardwareAverageCount4);
/* 配置 SIM 以选择 ADC 硬件触发源 */
// SIM->SOPT7 |= 0x8EU;
#如果定义(FSL_FEATURE_ADC16_HAS_CALIBRATION)&& FSL_FEATURE_ADC16_HAS_CALIBRATION
/* 自动校准 */
如果(kStatus_Success == ADC16_DoAutoCalibration(DEMO_ADC16_BASEADDR))
{
PRINTF("ADC16_DoAutoCalibration() 完成.\r\n");
}
别的
{
PRINTF("ADC16_DoAutoCalibration()失败.\r\n");
}
#结束
/* 启用软件触发。*/
ADC16_启用硬件触发器(DEMO_ADC16_BASEADDR,false);
/* 启用 DMA。*/
ADC16_EnableDMA(DEMO_ADC16_BASEADDR,真);
}
代码:
void get_DMA_Channel_link(dma_channel_link_config_t *config)
{
配置->链接类型 = 2;
配置->通道1 = 1;
}
静态无效DMA_config_ch_0()
{
DMA_CreateHandle(&g_DMA_Handle,DEMO_DMA_BASEADDR,DEMO_DMA_CHANNEL);
DMA_SetCallback(&g_DMA_Handle,DMA_Callback,NULL);
DMA_PrepareTransfer(&g_transferConfig,(void *)ADC16_RESULT_REG_ADDR,sizeof(uint32_t),
&g_adc16SampleDataArray[0],sizeof(uint32_t),20,
kDMA_外设到内存);
DMA_SubmitTransfer(&g_DMA_Handle,&g_transferConfig,kDMA_EnableInterrupt);
获取DMA通道链接(&通道链接);
DMA_SetChannelLinkConfig(g_DMA_Handle.base,0,&channel_link);
}
静态void DMA_config_ch_1()
{
DMA_CreateHandle(&g_DMA_Handle_channel_1,DEMO_DMA_BASEADDR,1);
// DMA_SetCallback(&g_DMA_Handle_channel_1,DMA_Callback_channel_1,NULL);
DMA_PrepareTransfer(&g_transferConfig_channel_1,&g_adc16ChannelDataArray[0],sizeof(uint8_t),
(void *)通道地址,sizeof(uint8_t),5,
kDMA_内存到外设);
DMA_SubmitTransfer(&g_DMA_Handle_channel_1,&g_transferConfig_channel_1,kDMA_NoOptions);
DMA_TriggerChannelStart(g_DMA_Handle_channel_1.base,1);
}
Capture.PNG
附件是供参考的项目。
如果需要任何其他信息,请告诉我。
谢谢!!