硬汉嵌入式论坛

 找回密码
 立即注册
查看: 310|回复: 5
收起左侧

[ADC] STM32H7的输入捕获不能触发ADC转换

[复制链接]

3

主题

28

回帖

37

积分

新手上路

积分
37
发表于 2024-1-27 17:34:02 | 显示全部楼层 |阅读模式
1、问题描述

    想使用定时TIM3的通道4捕获信号,然后触发ADC转换,但是ADC没看到一次转换,然后定时器捕获的计数器值是有在更新的,说明捕获已经发生了
2、代码如下
   
[C] 纯文本查看 复制代码
void Timer3_Init(void)
{
  TIM_IC_InitTypeDef sICConfig = {0};
  // 打开定时器时钟
  __HAL_RCC_TIM3_CLK_ENABLE();
 
  // 恢复到未初始化状态
  
  
  // 配置定时器
  hTrigTimer.Instance = S13131_TRIG_USE_TIMER;
  hTrigTimer.Init.Prescaler         = 0; // Fck_cnt = Fck_psc / (PSC[15:0] +1) = 32MHz 其中Fck_psc = 128MHz
  hTrigTimer.Init.Period            = 0xFFFF; // 用Timer3定时器的ADC_EXTERNALTRIG_T3_TRGO触发时改为1
  hTrigTimer.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1; // 确定DTS时钟=定时器时钟CK_INT(128MHz)
  hTrigTimer.Init.CounterMode       = TIM_COUNTERMODE_UP;
  hTrigTimer.Init.RepetitionCounter = 0;
  
  if(HAL_TIM_IC_Init(&hTrigTimer) != HAL_OK)
  {
    Error_Handler();
  }

  // 配置输入通道
  sICConfig.ICPolarity  = TIM_ICPOLARITY_RISING; // 捕获Trig信号下降沿
  sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sICConfig.ICPrescaler = TIM_ICPSC_DIV1; // 一个下降沿捕获一次
  sICConfig.ICFilter    = 0x0;   // 配置采样时钟和滤波参数 0x4--采样时钟=fdts/2, N=6 下降沿之后有大概100ns的电平才触发输入捕获
  if(HAL_TIM_IC_ConfigChannel(&hTrigTimer, &sICConfig, S13131_TRIG_USE_TIMER_CHANNEL) != HAL_OK)
  {
    Error_Handler();
  }
}


[C] 纯文本查看 复制代码
void ADC_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  ADC_ChannelConfTypeDef sConfig = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  // ADC外设时钟配置为72MHz 规格书中ADC3(12bit)最大时钟为75MHz
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInitStruct.PLL2.PLL2M = 1;
  PeriphClkInitStruct.PLL2.PLL2N = 36;
  PeriphClkInitStruct.PLL2.PLL2P = 4;
  PeriphClkInitStruct.PLL2.PLL2Q = 2;
  PeriphClkInitStruct.PLL2.PLL2R = 2;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
  PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  // ADC 引脚配置
  CMOS_ADC_GPIO_CLK_ENABLE; // 时钟使能
  CMOS_ADC_CLK_ENABLE;
  CMOS_ADC_DMA_CLK_ENABLE;    // DMA时钟使能
  HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_OPEN); // PC3_C为Direct输入 采样率最快
  
  GPIO_InitStruct.Pin = CMOS_ADC_PIN;   // 
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(CMOS_ADC_PORT, &GPIO_InitStruct);
  
  GPIO_InitStruct.Pin = GPIO_PIN_2;   // 
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(CMOS_ADC_PORT, &GPIO_InitStruct);

  // DMA配置
  hDMA_CmosADC.Instance = DMA1_Stream0;
  hDMA_CmosADC.Init.Request = DMA_REQUEST_ADC3;   // DMAMUX选择adc3_dma作为DMA1的请求
  hDMA_CmosADC.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hDMA_CmosADC.Init.PeriphInc = DMA_PINC_DISABLE;
  hDMA_CmosADC.Init.MemInc = DMA_MINC_ENABLE;
  hDMA_CmosADC.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;    // ADC设置10位
  hDMA_CmosADC.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;       // 
  hDMA_CmosADC.Init.Mode = DMA_CIRCULAR;    // 双缓存模式
  hDMA_CmosADC.Init.Priority = DMA_PRIORITY_HIGH;
  hDMA_CmosADC.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  
  if (HAL_DMA_Init(&hDMA_CmosADC) != HAL_OK)    // 初始化DMA,里面有关于DMAMUX的初始化
  {
    Error_Handler();
  }

  __HAL_LINKDMA(&hCmosADC,DMA_Handle,hDMA_CmosADC);   // 关联 ADC 句柄和 DMA 句柄
  
  // DMA中断配置
  HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 2, 0);      // 设置DMA中断优先级
  HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);              // 使能中断
  
  // ADC配置
  hCmosADC.Instance = CMOS_USE_ADC;
  hCmosADC.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hCmosADC.Init.Resolution = ADC_RESOLUTION_10B;    // 为了满足精度、速率要求,ADC位数暂定为10位
  hCmosADC.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hCmosADC.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hCmosADC.Init.LowPowerAutoWait = DISABLE;
  hCmosADC.Init.ContinuousConvMode = DISABLE;  // 禁止自动转换,采用的定时器触发转换
  hCmosADC.Init.NbrOfConversion = 1;  
  hCmosADC.Init.DiscontinuousConvMode = DISABLE;
  hCmosADC.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_CC4;    // ADC_EXTERNALTRIG_T3_CC4定时器Timer3的捕获事件触发ADC 
  hCmosADC.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
//  hCmosADC.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;    // 定时器Timer2的OC3REF触发TRGO
//  hCmosADC.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hCmosADC.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hCmosADC.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hCmosADC.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;  // 
  hCmosADC.Init.OversamplingMode = DISABLE;
  hCmosADC.Init.Oversampling.Ratio = 2; // 相当于两次采样的数据做累加 
  hCmosADC.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_1;
  hCmosADC.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hCmosADC.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
  if (HAL_ADC_Init(&hCmosADC) != HAL_OK)
  {
    Error_Handler();
  }

  // 执行自动ADC校准
  HAL_ADCEx_Calibration_Start(&hCmosADC, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
  
  // ADC通道配置
  sConfig.Channel = LL_ADC_CHANNEL_1;    // 接到PC3-ADC3_INP1 direct输入,采样率最快
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;  // ADC3采样时间最小2.5个Clock
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hCmosADC, &sConfig) != HAL_OK)     
  {
    Error_Handler();
  }
  
//  __HAL_ADC_ENABLE_IT(&hCmosADC, ADC_IT_EOS);
//  /* ADC3 interrupt Init */
//  HAL_NVIC_SetPriority(ADC3_IRQn, 1, 0);
//  HAL_NVIC_EnableIRQ(ADC3_IRQn);
}


主函数调用了初始化、开始函数
[C] 纯文本查看 复制代码
void S13131_Init(void)
{
  S13131_GPIO_Init();   // 初始化与S13131相关的GPIO
  
  ADC_Init();           // ADC3_INP1采集输出的模拟电压 
  Timer3_Init();        // Timer3 CH4引脚输入Trig触发信号
  //Timer5_Init();
  //Timer23_Init();       // Timer23 ETR引脚输入Trig触发信号
  Timer1_Init();        // Timer1通道1输出ST波形
  Timer2_Init();        // Timer2通道3输出CLK波形

}


void S13131_StartWork(void)
{
  // 使能DMA双缓冲
//  if(HAL_DMAEx_MultiBufferStart(&hDMA_CmosADC, hCmosADC.Instance->DR, (uint32_t)S13131_DataBuff0, (uint32_t)S13131_DataBuff1, S13131_DATA_BUFF_SIZE) != HAL_OK)  //   
//  {
//    Error_Handler();
//  }
  //HAL_ADC_Start_DMA_Modify(&hCmosADC, (uint32_t*)S13131_DataBuff0, (uint32_t*)S13131_DataBuff1, S13131_DATA_BUFF_SIZE);     // 开始ADC
    HAL_ADC_Start_DMA(&hCmosADC, (uint32_t*)S13131_DataBuff0, S13131_DATA_BUFF_SIZE);

//  if(HAL_TIM_OC_Start(&hTrigTimer, S13131_TRIG_USE_TIMER_CHANNEL) != HAL_OK)
//  {
//    Error_Handler();
//  }

  if(HAL_TIM_IC_Start(&hTrigTimer, S13131_TRIG_USE_TIMER_CHANNEL) != HAL_OK)
  {
    Error_Handler();
  }


3、要问的问题
    为何TIM_CH4的输入捕获不能触发ADC转换?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2024-1-28 09:03:14 | 显示全部楼层
使用有误,这个不是输入捕获,是CC捕获比较来触发,定时器配置周期控制的

需要外部触发,要使用EXTI触发。
回复

使用道具 举报

3

主题

28

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2024-1-28 10:42:35 | 显示全部楼层
eric2013 发表于 2024-1-28 09:03
使用有误,这个不是输入捕获,是CC捕获比较来触发,定时器配置周期控制的

需要外部触发,要使用EXTI触发 ...

ADC配置的hCmosADC.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_CC4,是这个定时器3通道4的CC触发,而定时器配置成了输入捕获模式,这样难道是错的?
回复

使用道具 举报

3

主题

28

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2024-1-28 10:46:42 | 显示全部楼层
eric2013 发表于 2024-1-28 09:03
使用有误,这个不是输入捕获,是CC捕获比较来触发,定时器配置周期控制的

需要外部触发,要使用EXTI触发 ...

这个CC触发是输出比较触发?不能输入捕获触发?看ADC_EXTERNALTRIG_T3_CC4的宏定义,描述为:
#define ADC_EXTERNALTRIG_T3_CC4       (LL_ADC_REG_TRIG_EXT_TIM3_CH4)             /*!< ADC group regular conversion trigger from external peripheral: TIM3 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */
描述里面提到输入捕获或者输出比较
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2024-1-28 11:33:39 | 显示全部楼层
AiK 发表于 2024-1-28 10:46
这个CC触发是输出比较触发?不能输入捕获触发?看ADC_EXTERNALTRIG_T3_CC4的宏定义,描述为:
#define A ...

是的,准确的说是OC,不是CC。所以我认为不行。
当然,你也可以试试,也许确实支持呢,我也没测试过捕获触发。

12.png
回复

使用道具 举报

3

主题

28

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2024-1-29 08:50:22 | 显示全部楼层
eric2013 发表于 2024-1-28 11:33
是的,准确的说是OC,不是CC。所以我认为不行。
当然,你也可以试试,也许确实支持呢,我也没测试过捕获 ...

试了不行 换成EXTI触发是可以的 应该是OC
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 13:13 , Processed in 0.176332 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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