STM32F030 ADC多通道DMA方式采集配置问题
我用的是STM32F030使用多通道DMA采集,发现F0芯片使用cubemx配置跟F1一样的,但是就是读值全都不对,原来F1没有遇到过这种问题,有用过的大神看下配置上有什么需要改的吗?之前有个帖子说自己添加通道,我也添加过了读值还是不对,只配置一个通道设置跟多通道一模一样读值就正确的,应该就是多通道添加有问题。void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_2;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_4;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
这个是添加通道设置
void init_ADCRank(void)
{
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
}
:) 你也检查下DMA的配置有没有问题,比方源端、目的端数据宽带是否一致;
源端、目的端是否都是DMA可以访问到的 xmshao 发表于 2019-3-19 17:20
你也检查下DMA的配置有没有问题,比方源端、目的端数据宽带是否一致;
源端、目的端是否都是DMA可以访问到 ...
uint32_t AD_Value; //用来存放ADC转换结果,也是DMA的目标地址,每通道采N次,M为通道数
HAL_ADC_Start_DMA(&hadc, *AD_Value, N);
带宽大小都一样的啊 本帖最后由 wenyangzeng 于 2019-3-19 21:17 编辑
用CubeMX生成的ADC初始化代码是:
void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = ENABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_2;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_4;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}无需再来一个 Int_ADCRank()函数。因为:
如果所有通道转换速率相同,
则
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
于是下面紧跟的其他通道都默认上面的设置。
然后需要:
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC_Value, ADC_Number*ADC_Channel);
才能启动ADC读数据。每次DMA传输的数据是转换次数×ADC通道数,保存在ADC_Value[]数组中。
wenyangzeng 发表于 2019-3-19 21:04
用CubeMX生成的ADC初始化代码是:
无需再来一个 Int_ADCRank()函数。因为:
如果所有通道转换速率相同,
谢谢大神,原来是转换次数×ADC通道数那个地方没设置对,太感谢了 HAL_ADC_Start_DMA(&hadc, *AD_Value, N);是这里有问题吧? Kevin201707 发表于 2019-3-20 10:00
HAL_ADC_Start_DMA(&hadc, *AD_Value, N);是这里有问题吧?
是的就是这里的问题,应该是单通道采集次数*通道数 我也是这里的问题。读出来的值都不对,但是我不是用的二维数组去存放ADC的值,我是用一维数组,通过DMA连续读取,不断覆盖之前的数据,求教~!!!
页:
[1]