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转换?
|