你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F030 ADC多通道DMA方式采集配置问题

[复制链接]
Erwinchn 提问时间:2019-3-19 16:07 /
我用的是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);



}


CUBE配置

CUBE配置
222.png
收藏 评论7 发布时间:2019-3-19 16:07

举报

7个回答
xmshao 回答时间:2019-3-19 17:20:38
你也检查下DMA的配置有没有问题,比方源端、目的端数据宽带是否一致;
源端、目的端是否都是DMA可以访问到的

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

Erwinchn 回答时间:2019-3-19 17:27:03
xmshao 发表于 2019-3-19 17:20
你也检查下DMA的配置有没有问题,比方源端、目的端数据宽带是否一致;
源端、目的端是否都是DMA可以访问到 ...

uint32_t AD_Value[N][M]; //用来存放ADC转换结果,也是DMA的目标地址,每通道采N次,M为通道数
HAL_ADC_Start_DMA(&hadc, *AD_Value, N);
带宽大小都一样的啊
wenyangzeng 回答时间:2019-3-19 21:04:52
本帖最后由 wenyangzeng 于 2019-3-19 21:17 编辑

用CubeMX生成的ADC初始化代码是:
  1. void MX_ADC_Init(void)
  2. {

  3.   ADC_ChannelConfTypeDef sConfig;

  4.     /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  5.     */
  6.   hadc.Instance = ADC1;
  7.   hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  8.   hadc.Init.Resolution = ADC_RESOLUTION_12B;
  9.   hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  10.   hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  11.   hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  12.   hadc.Init.LowPowerAutoWait = DISABLE;
  13.   hadc.Init.LowPowerAutoPowerOff = DISABLE;
  14.   hadc.Init.ContinuousConvMode = DISABLE;
  15.   hadc.Init.DiscontinuousConvMode = ENABLE;
  16.   hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  17.   hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  18.   hadc.Init.DMAContinuousRequests = ENABLE;
  19.   hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  20.   if (HAL_ADC_Init(&hadc) != HAL_OK)
  21.   {
  22.     _Error_Handler(__FILE__, __LINE__);
  23.   }

  24.     /**Configure for the selected ADC regular channel to be converted.
  25.     */
  26.   sConfig.Channel = ADC_CHANNEL_0;
  27.   sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  28.   sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  29.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  30.   {
  31.     _Error_Handler(__FILE__, __LINE__);
  32.   }

  33.     /**Configure for the selected ADC regular channel to be converted.
  34.     */
  35.   sConfig.Channel = ADC_CHANNEL_1;
  36.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  37.   {
  38.     _Error_Handler(__FILE__, __LINE__);
  39.   }

  40.     /**Configure for the selected ADC regular channel to be converted.
  41.     */
  42.   sConfig.Channel = ADC_CHANNEL_2;
  43.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  44.   {
  45.     _Error_Handler(__FILE__, __LINE__);
  46.   }

  47.     /**Configure for the selected ADC regular channel to be converted.
  48.     */
  49.   sConfig.Channel = ADC_CHANNEL_3;
  50.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  51.   {
  52.     _Error_Handler(__FILE__, __LINE__);
  53.   }

  54.     /**Configure for the selected ADC regular channel to be converted.
  55.     */
  56.   sConfig.Channel = ADC_CHANNEL_4;
  57.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  58.   {
  59.     _Error_Handler(__FILE__, __LINE__);
  60.   }

  61.     /**Configure for the selected ADC regular channel to be converted.
  62.     */
  63.   sConfig.Channel = ADC_CHANNEL_5;
  64.   if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  65.   {
  66.     _Error_Handler(__FILE__, __LINE__);
  67.   }

  68.   

  69. }
复制代码
无需再来一个 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[]数组中。





评分

参与人数 2ST金币 +2 蝴蝶豆 +3 收起 理由
STMCU + 3
Erwinchn + 2 很给力!

查看全部评分

Erwinchn 回答时间:2019-3-20 08:58:01
wenyangzeng 发表于 2019-3-19 21:04
用CubeMX生成的ADC初始化代码是:
无需再来一个 Int_ADCRank()函数。因为:
如果所有通道转换速率相同,

谢谢大神,原来是转换次数×ADC通道数那个地方没设置对,太感谢了
Kevin_G 回答时间:2019-3-20 10:00:31
HAL_ADC_Start_DMA(&hadc, *AD_Value, N);  是这里有问题吧?
Erwinchn 回答时间:2019-3-21 14:25:47
Kevin201707 发表于 2019-3-20 10:00
HAL_ADC_Start_DMA(&hadc, *AD_Value, N);  是这里有问题吧?

是的就是这里的问题,应该是单通道采集次数*通道数
speciallyyj 回答时间:2019-4-23 15:37:17
我也是这里的问题。读出来的值都不对,但是我不是用的二维数组去存放ADC的值,我是用一维数组,通过DMA连续读取,不断覆盖之前的数据,求教~!!!
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版