4839|4

1411

帖子

3

TA的资源

版主

楼主
 

【基于NUCLEO-F746ZG电机开发应用】11.参数配置-ADC配置 [复制链接]

    伺服开发驱动中,ADC的采集是重点中的重点。本开发板中的模拟量是:三相电流、1个总线电压、1个温度(板载传感器)。三相电流经过ADC采集转化后,经过矢量变换(Clarke变换和Park变换),转化为励磁电流Id和转矩电流Iq,再经过速度控制器的控制,对电机转速进行调速。

总线电压和温度主要是对电路进行安全保护。

 

1.硬件电路设计

    (1)三相电流经过1W,0.33Ω采样后,经比例放大1.53倍后输入到单片机模拟通道,单片机经逐次逼近采样运算得到结果。

其中A相电流连接的是PA0,ADC通道为ADC1_IN0;B相电流连接的是PC1,ADC通道为ADC1_IN11和ADC2_IN11;C相电流连接的是PC0,ADC通道为ADC2_IN10;

 

(2)VBUS电压连接的是PA1,ADC通道为ADC1_IN1;
温度连接的是PC2,ADC通道为ADC1_IN12;

 

2.软件设计

(1)ADC简介

        12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道,可测量来自 16 个外部源、 两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续采样 模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。 ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限。

(2)ADC结构框图

        ADC拥有非常多功能,是由ADC内部结构所决定。要更好的理 解STM32F7的ADC,就需要了解它内部的结构。如下图所示:(查看《STM32F10x中文参考手册》-15模数转换器(ADC)章-ADC功 能说明)。

图中1号:参考电压输入引脚

  ADC输入电压范围为: VREF- ≤ VIN ≤ VREF+。由 VREF-、 VREF+ 、 VDDA 、 VSSA这四个外部引脚决定。通常我们把 VSSA和 VREF-接地 ,把 VREF+和 VDDA 接 3.3V,因此ADC的输入电压范围为:0~3.3V。我 们使用的开发板ADC输入电压范围为0~3.3V。

 

图中2号:输入通道

  STM32 的 ADC的输入通道多达 19个,其中外部的 16 个通道就是框 图中的 ADCx_IN0、ADCx_IN1...ADCx_IN5(x=1/2/3,表示ADC数),通 过这16个外部通道可以采集模拟信号。这 16 个通道对应着不同的 IO 口, 具体是哪一个 IO 口可以从数据手册查询到。其中 ADC1 还有2 个内部通道:ADC1 的通道16连接到了芯片内部的温度传感器,通道17连 接到了内部参考电压 VREFINT。

 

图中3号:通道转换顺序和触发源(外部触发和软件触发)

  外部的 16 个通道在转换的时候可分为2组通道:规则通道组和注入 通道组,其中规则通道组最多有16路,注入通道组最多有 4 路。 规则通道组:从名字来理解,规则通道就是一种规规矩矩的通道,类 似于正常执行的程序,通常我们使用的都是这个通道。 注入通道组:从名字来理解,注入即为插入,是一种不安分的通道, 类似于中断。当程序正常往下执行时,中断可以打断程序的执行。同样 如果在规则通道转换过程中,有注入通道插入,那么就要先转换完注入 通道,等注入通道转换完成后再回到规则通道的转换流程。 每个组包含一个转换序列,该序列可按任意顺序在任意通道上完成。 例如,可按以下顺序对序列进行转换: ADC_IN3、ADC_IN8、 ADC_IN2、 ADC_IN2、 ADC_IN0、 ADC_IN2、 ADC_IN2、 ADC_IN15。

  选择好输入通道,设置好转换顺序,接下来就可以开始转换。要开启 ADC转换,可以直接设置ADC 控制寄存器ADC_CR2 的 ADON位为1,即使能 ADC。当然ADC还支持外部事件触发转换,触发源有很多,具体选择哪一 种触发源,由 ADC 控制寄存器2:ADC_CR2 的 EXTSEL[3:0]和 JEXTSEL[3:0]位来控制。EXTSEL[3:0]用于选择规则通道的触发源, JEXTSEL[3:0]用于选择注入通道的触发源。选定好触发源之后,可以通过设置 ADC 控制寄存器 2:ADC_CR2 的EXTEN[1:0]和 JEXTEN[1:0]来控制触发极性和使能,可以有 4 种 状态,分别是:禁止触发检测、上升沿检测、下降沿检测以及上升沿和 下降沿均检测。

 

图中4号:中断标志

 当发生如下事件且使能相应中断标志位时,ADC能产生中断。

   1.转换结束(规则转换)与注入转换结束

   2.模拟看门狗事件

   3.DMA请求

 

图中5号:数据寄存器

  ADC 转换后的数据根据转换组的不同,规则组的数据放在ADC_DR 寄 存器内,注入组的数据放在 JDRx内。 因为STM32F7的ADC是12位转换精度,而数据寄存器是16位,所以ADC 在存放数据的时候就有左对齐和右对齐区分。如果是左对齐,AD转换完 成数据存放在 ADC_DR 寄存器的[4:15]位内;如果是右对齐,则存放在 ADC_DR 寄存器的[0:11]位内。具体选择何种存放方式,需通过ADC_CR2 的 11 位 ALIGN 设置。

 

图中6号:ADC时钟

  ADC 输入时钟 ADC_CLK 由 APB2经过分频产生,最大值是54MHz,分 频因子由 RCC 时钟配置寄存器 RCC_CCR 的位 17:16 ADCPRE[1:0]设置 ,可以是 2/4/6/8 分频。

 

(3)软件编写

根据硬件和ADC的框图,配置ADC1和ADC2:

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] ADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */
  //PA0:A相电流,ADC1_IN0;
  //PC1:B相电流,ADC1_IN11;ADC2_IN11
  //PA1:VBUS电压,ADC1_IN1;
  //PC2:温度,ADC1_IN12;
  /* USER CODE END ADC1_Init 0 */

  ADC_InjectionConfTypeDef sConfigInjected = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;//ADC1
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //ADC1时钟4分频
  hadc1.Init.Resolution = ADC_RESOLUTION_12B; //分辨率为12位
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; //扫描模式开启
  hadc1.Init.ContinuousConvMode = DISABLE; //连续采样模式关闭
  hadc1.Init.DiscontinuousConvMode = DISABLE;//非连续采样模式关闭
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //禁止触发检测,使用软件触发
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发
  hadc1.Init.DataAlign = ADC_DATAALIGN_LEFT; //数据左对齐
  hadc1.Init.NbrOfConversion = 2; //配置为2通道
  hadc1.Init.DMAContinuousRequests = DISABLE; //关闭DMA传输数据
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;//使能EOC标志位
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
  */
  //为选定的 ADC 注入通道配置其在定序器中的相应等级及其采样时间
  sConfigInjected.InjectedChannel = ADC_CHANNEL_0; //ADC1通道0
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;//注入组排序器中的排名为1
  sConfigInjected.InjectedNbrOfConversion = 2;//指定将在注入的组序列器中转换的等级数为2
  sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_15CYCLES;//通道的采样时间为15
  sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_RISING;//选择注入组的外部触发沿为上升沿
  sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T1_CC4;//选择用于触发注入组转换开始的外部事件。
  sConfigInjected.AutoInjectedConv = DISABLE;//禁用选定的 ADC 自动注入组转换后定期转换
  sConfigInjected.InjectedDiscontinuousConvMode = ENABLE;//指定注入组的转换序列是以完整序列(主序列细分为连续部分)进行。
  sConfigInjected.InjectedOffset = 0;//要从原始转换数据中减去的偏移量为0
  if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)//初始化ADC1
  {
    Error_Handler();
  }
  /** Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
  */
  sConfigInjected.InjectedChannel = ADC_CHANNEL_11;//ADC1通道11
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;//注入组排序器中的排名为2
  if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK)//初始化
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_1;//常规ADC通道1
  sConfig.Rank = ADC_REGULAR_RANK_1;//指定常规组排序器中的排名为1
  sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES;//采样周期为28
  sConfig.Offset = 0;//偏移量为0

  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)//初始化
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_12;//常规ADC通道12
  sConfig.Rank = ADC_REGULAR_RANK_2;//指定常规组排序器中的排名为2
  sConfig.Offset = 0;//偏移量为0

  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)//初始化
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

/**
  * @brief ADC2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC2_Init(void)
{

  /* USER CODE BEGIN ADC2_Init 0 */
  //PC0:C相电流,ADC2_IN10;
  //PC1:B相电流,ADC1_IN11;ADC2_IN11
  /* USER CODE END ADC2_Init 0 */

  ADC_InjectionConfTypeDef sConfigInjected = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc2.Instance = ADC2;//ADC2
  hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;//ADC2时钟4分频
  hadc2.Init.Resolution = ADC_RESOLUTION_12B;//分辨率为12位
  hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;//扫描模式开启
  hadc2.Init.ContinuousConvMode = DISABLE;//连续采样模式关闭
  hadc2.Init.DiscontinuousConvMode = DISABLE;//非连续采样模式关闭
  hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//禁止触发检测,使用软件触发
  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;//软件触发
  hadc2.Init.DataAlign = ADC_DATAALIGN_LEFT;//数据左对齐
  hadc2.Init.NbrOfConversion = 1;//配置为1通道
  hadc2.Init.DMAContinuousRequests = DISABLE;//关闭DMA传输数据
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;//使能EOC标志位
  if (HAL_ADC_Init(&hadc2) != HAL_OK)//初始化ADC2
  {
    Error_Handler();
  }
  /** Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
  */
    //为选定的 ADC 注入通道配置其在定序器中的相应等级及其采样时间
  sConfigInjected.InjectedChannel = ADC_CHANNEL_11;//ADC2通道11
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;//注入组排序器中的排名为1
  sConfigInjected.InjectedNbrOfConversion = 2;//指定将在注入的组序列器中转换的等级数为2
  sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_15CYCLES;//通道的采样时间为15
  sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_RISING;//选择注入组的外部触发沿为上升沿
  sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T1_CC4;//选择用于触发注入组转换开始的外部事件。
  sConfigInjected.AutoInjectedConv = DISABLE;//禁用选定的 ADC 自动注入组转换后定期转换
  sConfigInjected.InjectedDiscontinuousConvMode = ENABLE;//指定注入组的转换序列是以完整序列(主序列细分为连续部分)进行。
  sConfigInjected.InjectedOffset = 0;//要从原始转换数据中减去的偏移量为0
  if (HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected) != HAL_OK)//初始化注入模式
  {
    Error_Handler();
  }
  /** Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
  */
  sConfigInjected.InjectedChannel = ADC_CHANNEL_10;//ADC2通道10
  sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;//注入组排序器中的排名为2
  if (HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected) != HAL_OK)//初始化注入模式
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_10;//常规ADC通道10
  sConfig.Rank = ADC_REGULAR_RANK_1;//指定常规组排序器中的排名为2
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;//采样周期为3
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)//初始化常规ADC
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC2_Init 2 */

  /* USER CODE END ADC2_Init 2 */

}

 

此帖出自电机控制论坛

最新回复

学习了 感谢楼主 THXTHXTHXTHX THXTHXTHXTHXTHXTHXTHXTHX   详情 回复 发表于 2021-11-25 22:45
点赞(1) 关注(1)
个人签名

没有什么不可以,我就是我,不一样的烟火! 

 
 

回复
举报

7608

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

图片和文字标号没对应上。

此帖出自电机控制论坛

点评

6号忘记标了  详情 回复 发表于 2021-10-9 22:00
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

1411

帖子

3

TA的资源

版主

板凳
 
freebsder 发表于 2021-10-9 18:12 图片和文字标号没对应上。

6号忘记标了

此帖出自电机控制论坛
个人签名

没有什么不可以,我就是我,不一样的烟火! 

 
 
 

回复

8

帖子

0

TA的资源

一粒金砂(中级)

4
 

学习了 感谢楼主 THXTHXTHXTHX

THXTHXTHXTHXTHXTHXTHXTHX

此帖出自电机控制论坛

点评

谢谢支持  详情 回复 发表于 2021-11-27 08:41
 
 
 

回复

1411

帖子

3

TA的资源

版主

5
 
pokmnjikm 发表于 2021-11-25 22:45 学习了 感谢楼主 THXTHXTHXTHX THXTHXTHXTHXTHXTHXTHXTHX

谢谢支持

此帖出自电机控制论坛
个人签名

没有什么不可以,我就是我,不一样的烟火! 

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表