搜索
bottom↓
回复: 8

用cube实现stm32f103双通道ADC+dma传输的经验,及cube可能的bug

[复制链接]

出0入0汤圆

发表于 2016-9-19 18:11:07 | 显示全部楼层 |阅读模式
本帖最后由 ilawp 于 2016-9-19 18:11 编辑

学习cube中,的确很方便,但好久不写程序恢复起来好痛苦。
目的是用stm32同步采集两路正弦波信号,频率72k,单片机是f103c8。计划用规则同步模式+dma传输,下面是一些经验与大家分享。另外发现了一个cube可能的bug


把adc1设置成dual regularsimu、、、模式之后adc2也会改成相同模式。ADC1设置为timer1的比较输出1触发。timer1的cc1最好设置成pwm模式,其它模式貌似不好用,我也没仔细试。
adc2的触发不要设置,cube生成的代码里会自动设置为软件触发。
生成的代码如下:
void MX_ADC1_Init(void)
{
  ADC_MultiModeTypeDef multimode;
  ADC_ChannelConfTypeDef sConfig;

    /**Common config
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

    /**Configure the ADC multi-mode
    */
  multimode.Mode = ADC_DUALMODE_REGSIMULT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }

    /**Configure Regular Channel
    */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}
/* ADC2 init function */
void MX_ADC2_Init(void)
{
  ADC_MultiModeTypeDef multimode;
  ADC_ChannelConfTypeDef sConfig;

    /**Common config
    */
  hadc2.Instance = ADC2;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.ContinuousConvMode = DISABLE;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc2.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }

    /**Configure the ADC multi-mode
    */
//  multimode.Mode = ADC_DUALMODE_REGSIMULT;
//  if (HAL_ADCEx_MultiModeConfigChannel(&hadc2, &multimode) != HAL_OK)
//  {
//    Error_Handler();
//  }

    /**Configure Regular Channel
    */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}


在开始转换前,要先吧adc1和2再配置和启动一下(要先启动adc2)
HAL_ADC_MspInit(&hadc1);
HAL_ADC_MspInit(&hadc2);
HAL_ADC_Start(&hadc2);
然后就可以开始启动adc1和dma了
HAL_ADCEx_MultiModeStart_DMA(&hadc1,adcDataBuff,64);

这里我发现cube自动生成的代码里有问题

这一部分被我注释掉在了,在adc2的初始化里,这一步必定返回失败,然后程序就sb了。
在下面函数里面
HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)
{
  。


  if ((ADC_IS_ENABLE(hadc) == RESET)                     &&
      (ADC_IS_ENABLE(&tmphadcSlave) == RESET)            &&
      (IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance))   )
  {
    MODIFY_REG(hadc->Instance->CR1,
               ADC_CR1_DUALMOD    ,
               multimode->Mode     );
  }
  /* If one of the ADC sharing the same common group is enabled, no update    */
  /* could be done on neither of the multimode structure parameters.          */
  else
  {
    /* Update ADC state machine to error */
    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
   
    tmp_hal_status = HAL_ERROR;
  }
   
   
  /* Process unlocked */
  __HAL_UNLOCK(hadc);
  
  /* Return function status */
  return tmp_hal_status;
}
#############
这里面的
      (IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance))   )这句肯定返回false

因为

#define IS_ADC_MULTIMODE_MASTER_INSTANCE(INSTANCE) ((INSTANCE) == ADC1)

这里就变成了判断ADC2 == ADC1.肯定是false

另外在同步模式下,adc2的数据会自动发到adc1-dr的高16位,但这个是有前提的,那就是ADC1->CR2->DMA这一位必须置位,不然adc1-dr的高16位还是0。一开始单独调试adc同步模式的时候因为这个问题蛋疼了好久。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

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

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2016-9-23 06:51:47 | 显示全部楼层
学习了,最近也在用stm32的cube软件

出0入0汤圆

发表于 2016-9-23 09:36:46 | 显示全部楼层
不想在ST注册,有没有最新的共享一下

出0入0汤圆

 楼主| 发表于 2016-9-23 10:05:47 | 显示全部楼层
four_zhg 发表于 2016-9-23 09:36
不想在ST注册,有没有最新的共享一下

http://pan.baidu.com/s/1kVwISD5
想要最新版可以装上之后再更新

出0入0汤圆

发表于 2016-9-23 10:19:56 | 显示全部楼层
多谢,兄弟,我安装上玩玩

出0入4汤圆

发表于 2016-9-23 10:38:33 | 显示全部楼层
ADC1和ADC2没必要初始化两次吧,你再sConfig.channel那部分后边在加一个通道。至于你说的那个bug,他就是个初始化,貌似没问题吧。

出0入0汤圆

 楼主| 发表于 2016-9-26 09:19:19 | 显示全部楼层
clesun 发表于 2016-9-23 10:38
ADC1和ADC2没必要初始化两次吧,你再sConfig.channel那部分后边在加一个通道。至于你说的那个bug,他就是个 ...

1、两个adc都需要初始化, 而且还需要调用启动的命令。这个在调试的时候看寄存器很清楚。
2、两个初始化函数里的内容都是cube生成的,做任何的改动下次再用cube生成工程都会被覆盖。
3、你仔细看一下我的描述。它的确是初始化,但是每次必定初始化失败,然后进到error_handle里

出0入0汤圆

发表于 2016-9-26 21:09:17 | 显示全部楼层
学习下,谢谢分享

出0入0汤圆

发表于 2016-12-26 00:32:15 | 显示全部楼层
cube 是什么? 有空查一下看看....
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-9-28 10:23

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

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