代码部分如下:采用了双重ADC模式。 ADC_HandleTypeDef ADC1_Handle,ADC2_Handle; DMA_HandleTypeDef hdma_adc; ADC_MultiModeTypeDef ADC_multimode; __attribute__ ((at(0x30000000))) __IO uint32_t ADC_ConvertedValue=0; __IO uint16_t ADC_ConvertedValueLocal[2];
一、//ADC引脚配置
static void ADC_GPIO_Mode_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
/* 配置为模拟输入,不需要上拉电阻 */
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
二、//时钟+DMA配置
static void ADC_Mode_Config(void)
{
ADC_ChannelConfTypeDef ADC_Config;
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
/* 配置ADC3时钟源 */
/* HSE Frequency(Hz) = 25000000 */
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
RCC_PeriphClkInit.PLL2.PLL2FRACN = 0;
RCC_PeriphClkInit.PLL2.PLL2M = 5;
RCC_PeriphClkInit.PLL2.PLL2N = 160;
RCC_PeriphClkInit.PLL2.PLL2P = 25;
RCC_PeriphClkInit.PLL2.PLL2Q = 2;
RCC_PeriphClkInit.PLL2.PLL2R = 2;
RCC_PeriphClkInit.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
RCC_PeriphClkInit.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
RCC_PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* 使能ADC1、2时钟 */
__HAL_RCC_ADC12_CLK_ENABLE();
//使能DMA时钟
__HAL_RCC_DMA1_CLK_ENABLE();
//指向DMA数据流基地址的指针,指定用数据流1
hdma_adc.Instance = DMA1_Stream1;
//DMA请求选择
hdma_adc.Init.Request = DMA_REQUEST_ADC1;
//传输方向,外设至存储器
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
//如果配置为PeriphInc_Enable,使能外设地址自动递增。ADC1数据寄存器地址固定,无需递增使能
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
//如果配置为MemInc_Enable,使能存储器地址自动递增功能
hdma_adc.Init.MemInc = DMA_MINC_DISABLE;
//外设数据宽度,可选字节(8位)、半字(16位)、字(32位)
//双重模式时,ADC 的通用规则数据寄存器是32 位有效
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
//存储器字节宽度,可选字节(8位)、半字(16位)、字(32位)
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
//DMA传输模式选择,可选一次传输或者循环传输
hdma_adc.Init.Mode = DMA_CIRCULAR;
//软件设置数据流的优先级
hdma_adc.Init.Priority = DMA_PRIORITY_LOW;
//FIFO 模式使能
hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_adc);
HAL_DMA_Init(&hdma_adc);
//hdma_adc和ADC_Handle.DMA_Handle链接
__HAL_LINKDMA(&ADC1_Handle,DMA_Handle,hdma_adc);
ADC1_Handle.Instance = ADC1;
HAL_ADC_DeInit(&ADC1_Handle);
//使能Boost模式
ADC1_Handle.Init.BoostMode = ENABLE;
//ADC时钟1分频
ADC1_Handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
//关闭连续转换模式
ADC1_Handle.Init.ContinuousConvMode = DISABLE;
//扫描1个通道
ADC1_Handle.Init.NbrOfConversion = 1;
//数据存放在数据寄存器中
ADC1_Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
//关闭不连续转换模式
ADC1_Handle.Init.DiscontinuousConvMode = DISABLE;
ADC1_Handle.Init.NbrOfDiscConversion = 0;
//使能EOC标志位
ADC1_Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
//T4定时器TRGO事件触发
ADC1_Handle.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T4_TRGO;
ADC1_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
//关闭低功耗自动等待
ADC1_Handle.Init.LowPowerAutoWait = DISABLE;
//数据溢出时,覆盖写入
ADC1_Handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
//不使能过采样模式
ADC1_Handle.Init.OversamplingMode = DISABLE;
//分辨率为:16bit
ADC1_Handle.Init.Resolution = ADC_RESOLUTION_12B;
//不使能多通道扫描
ADC1_Handle.Init.ScanConvMode = DISABLE;
//扫描0个通道
ADC1_Handle.Init.NbrOfConversion = 0;
//初始化 主ADC1
HAL_ADC_Init(&ADC1_Handle) ;
HAL_ADCEx_Calibration_Start(&ADC1_Handle,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);
//初始化 从ADC2
ADC2_Handle.Instance = ADC2;
HAL_ADC_DeInit(&ADC2_Handle);
ADC2_Handle.Init = ADC1_Handle.Init;
HAL_ADC_Init(&ADC2_Handle);
iHAL_ADCEx_Calibration_Start(&ADC2_Handle,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);
//使用通道7
ADC_Config.Channel = ADC_CHANNEL_7;
//转换顺序为1
ADC_Config.Rank = ADC_REGULAR_RANK_1 ;
//采样周期
ADC_Config.SamplingTime = ADC_SAMPLETIME_16CYCLES_5;
//不使用差分输入的功能
ADC_Config.SingleDiff = ADC_SINGLE_ENDED ;
ADC_Config.OffsetNumber = ADC_OFFSET_NONE;
ADC_Config.Offset = 0;
//配置ADC1通道
HAL_ADC_ConfigChannel(&ADC1_Handle, &ADC_Config);
// 使用通道3
ADC_Config.Channel = ADC_CHANNEL_3;
// 转换顺序为2
ADC_Config.Rank = ADC_REGULAR_RANK_1;
//配置ADC2通道
HAL_ADC_ConfigChannel(&ADC2_Handle, &ADC_Config);
//使能ADC1、2
ADC_Enable(&ADC1_Handle);
ADC_Enable(&ADC2_Handle);
//数据格式
ADC_multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
//双重ADC交替模式
ADC_multimode.Mode = ADC_DUALMODE_INTERL;
//主ADC和从ADC采样间隔3个ADC时钟
ADC_multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_3CYCLES;
//ADC双重模式配置初始化
//控制是否使能ADC的DMA请求
HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handle, &ADC_multimode);
//使能DMA
HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handle, (uint32_t*)&ADC_ConvertedValue, 1);
}
三、//DMA中断配置
static void DMA_NVIC_Config(void)
{
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
四、//DMA中断服务函数
void DMA1_Stream1_IRQHandler(void)
{
HAL_DMA_IRQHandler(ADC1_Handle.DMA_Handle);
}
五、//PWM触发源配置
void TIM4_PWM_Init(void)
{
TIM_MasterConfigTypeDef master_timer_config;
TIM4_Handler.Instance = TIM4;//定时器4
TIM4_Handler.Init.Period = 50-1;//自动重装载值
TIM4_Handler.Init.Prescaler = 4-1;//定时器分频
TIM4_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIM4_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
TIM4_Handler.Init.RepetitionCounter = 0x0;
HAL_TIM_Base_Init(&TIM4_Handler);
/* Timer TRGO selection */
master_timer_config.MasterOutputTrigger = TIM_TRGO_UPDATE;
master_timer_config.MasterOutputTrigger2 = TIM_TRGO2_RESET;
master_timer_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&TIM4_Handler, &master_timer_config);
HAL_TIM_Base_Start(&TIM4_Handler); //使能定时器4和定时器4更新中断:TIM_IT_UPDATE
}
六、//最终初始化
void ADC_Init(void)
{
ADC_GPIO_Mode_Config();
ADC_Mode_Config();
DMA_NVIC_Config();
HAL_ADC_Start(&ADC1_Handle);
HAL_ADC_Start(&ADC2_Handle);
}
七、//ADC回调函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
/* 获取结果 */
ADC_ConvertedValue=HAL_ADCEx_MultiModeGetValue(AdcHandle);
ADC_ConvertedValueLocal[0] = (uint16_t)ADC_ConvertedValue;
ADC_ConvertedValueLocal[1] = (uint16_t)((ADC_ConvertedValue&0xFFFF0000)>>16);
TEST_PIN_Toggle;
//需要增加的中断处理函数
}
现在的问题是,在第七段中,我不添加那段需要中断处理的函数,用示波器观察TSET_PIN的翻转,是500KHz;
但是我添加了中断处理函数(测量过这段函数执行大约820ns),TSET_PIN的翻转频率就变成了300KHz多一点。
即使我把这段中断处理函数缩减到400ns,TEST_PIN的翻转频率也只提高到425KHz。
想知道问题出在哪里?怎么解决?
|