|
请教一下坛主:用了723片子上的ADC3采样,ADC时钟36M, 采样SamplingTime = ADC_SAMPLETIME_2CYCLES_5,周期性采样1600个数据,那不是应该36M/(6.5+2.5)=4M, 4M/1600=2500HZ,也就是400us才对吗?可实际结果是420us。请大佬解惑。
void ADC3_Init(void)
{
//DMA_HandleTypeDef DMA_Handle= {0};
ADC_ChannelConfTypeDef sConfig = {0};
// ## - 1 - 配置ADC采样的时钟 #######################################
#if defined (ADC_CLOCK_SOURCE_PLL)
// 配置PLL2时钟为的72MHz ,36M时12位ADC可以到4MHZ
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL2.PLL2M = 4;//16;
PeriphClkInitStruct.PLL2.PLL2N = 18;//72;
PeriphClkInitStruct.PLL2.PLL2P = 4;//72MHz
PeriphClkInitStruct.PLL2.PLL2Q = 4;//2;//72MHz
PeriphClkInitStruct.PLL2.PLL2R = 2;//72MHz
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(__FILE__, __LINE__);
}
#elif defined (ADC_CLOCK_SOURCE_AHB)
// 使用AHB时钟的话,无需配置,默认选择
#endif
hadc3.Instance = ADC3;//指向ADC1
ADCGIO_Init( &hadc3);//ADCx GPIO配置和初始化
__HAL_RCC_DMA2_CLK_ENABLE();
DMA_Handle3.Instance = DMA2_Stream1;//DMA1_Stream2; /* 使用的DMA1 Stream1 */
DMA_Handle3.Init.Request = DMA_REQUEST_ADC3;//DMA_REQUEST_ADC3; /* 请求类型采用DMA_REQUEST_ADC1 */
DMA_Handle3.Init.Direction = DMA_PERIPH_TO_MEMORY; /* 传输方向是从外设到存储器 */
DMA_Handle3.Init.PeriphInc = DMA_PINC_DISABLE; //DMA_PINC_ENABLE ;// /* 外设地址自增禁止 */
DMA_Handle3.Init.MemInc = DMA_MINC_ENABLE; /* 存储器地址自增使能 */
DMA_Handle3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;//DMA_PDATAALIGN_WORD; /* 外设数据传输位宽选择半字,即16bit */
DMA_Handle3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;//DMA_MDATAALIGN_HALFWORD;//DMA_MDATAALIGN_WORD; /* 存储器数据传输位宽选择半字,即16bit */
DMA_Handle3.Init.Mode = DMA_CIRCULAR; //DMA_NORMAL ;/* 循环模式 */
DMA_Handle3.Init.Priority = DMA_PRIORITY_MEDIUM ;//DMA_PRIORITY_LOW; /* 优先级中 */
DMA_Handle3.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* 禁止FIFO*/
//DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; /* 禁止FIFO此位不起作用,用于设置阀值 */
//DMA_Handle.Init.MemBurst = DMA_MBURST_SINGLE; /* 禁止FIFO此位不起作用,用于存储器突发 */
//DMA_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE; /* 禁止FIFO此位不起作用,用于外设突发 */
/* 初始化DMA */
if(HAL_DMA_Init(&DMA_Handle3) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//__HAL_DMA_ENABLE_IT(&DMA_Handle,DMA_IT_TC);
/* 关联ADC句柄和DMA句柄 */
__HAL_LINKDMA(&hadc3, DMA_Handle, DMA_Handle3);//第一个参数是外设句柄,第二个参数是外设句柄内的一个DMA句柄指针,最后一个参数是DMA句柄
DMA_NVIC_Config(&hadc3);//DMA中断优先级配置函数
//ADC3配置A****************************************************************
HAL_ADC_DeInit(&hadc3);
__HAL_RCC_ADC3_CLK_ENABLE();//开启adc时钟
#if defined (ADC_CLOCK_SOURCE_PLL)//如果选择PLL时钟
hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; //采用PLL异步时钟,2分频,即72MHz/2 = 36MHz
#elif defined (ADC_CLOCK_SOURCE_AHB)//如果选择AHB时钟
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 采用AHB同步时钟,4分频,即200MHz/4 = 50MHz
#endif
hadc3.Init.Resolution = ADC_RESOLUTION_12B;//ADC3最高分辨率是12位
hadc3.Init.DataAlign = ADC3_DATAALIGN_RIGHT;//
hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;//扫描模式;ADC_SCAN_DISABLE;//非扫描模式
hadc3.Init.EOCSelection =ADC_EOC_SINGLE_CONV;//ADC_EOC_SEQ_CONV;//关闭EOC中断 //单通道转换结束或者序列转换结束
hadc3.Init.LowPowerAutoWait = DISABLE;//自动低功耗关闭
hadc3.Init.ContinuousConvMode = ENABLE; //打开连续转换;DISABLE;//不打开连续转换//
hadc3.Init.NbrOfConversion = 5;//5个转换在规则序列中
hadc3.Init.DiscontinuousConvMode = DISABLE;//禁止不连续采样模式这个参数;
hadc3.Init.NbrOfDiscConversion=0; //不连续采样通道数为0/用于设置子组的大小。
hadc3.Init.ExternalTrigConv=ADC_EXTERNALTRIG_T6_TRGO;//选择T6用于触发
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING ;//上升沿触发FALLING//
hadc3.Init.DMAContinuousRequests = ENABLE;//指定DMA请求是否以单次模式执行(当达到转换数量时,DMA传输停止)
hadc3.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;//
hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; /* DMA循环模式接收ADC转换的数据 */
hadc3.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN;//有新的数据直接覆盖掉旧数据;//ADC_OVR_DATA_PRESERVED;超时保存数据//
hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;//配置应用于有无过度采样的最终结果的左移位。此参数的值可以为@refadcex_left_bit_shift*
//hadc1.Init.BoostMode=ENABLE; //BOOsT模式开,ADC时钟超过20MHz的话,使能boost
hadc3.Init.OversamplingMode=DISABLE;//ENABLE;////过采样打开//
//hadc1.Init.Oversampling.Ratio = 15; // 15+1倍过采样
//hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4; // 数据右移4bit,即除以16
//hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER; // 触发后连续完成每个通道的所有过采样转换
//初始化ADC3
if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
// 校准ADC1,采用线性校准 ADC_CALIB_OFFSET_LINEARITY//ADC_CALIB_OFFSET
if (HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//配置ADC通道,序列1
sConfig.Channel = ADC_CHANNEL_0;//
sConfig.Rank = ADC_REGULAR_RANK_1;//常规转换的排序
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; //C_SAMPLETIME_8CYCLES_5;////要为选定通道设置的采样时间值
sConfig.SingleDiff = ADC_SINGLE_ENDED;//选择单端输入或差分输入
sConfig.OffsetNumber = ADC_OFFSET_NONE;//选择偏移量数,
sConfig.Offset = 0;///* 无偏移的情况下,此参数忽略 */
sConfig.OffsetRightShift = DISABLE; /* 禁止右移 */
sConfig.OffsetSignedSaturation = DISABLE;// 禁止有符号饱和
//sConfig.OffsetSign = ADC3_OFFSET_SIGN_NEGATIVE;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//配置ADC3 序列2
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; //C_SAMPLETIME_8CYCLES_5;////要为选定通道设置的采样时间值
sConfig.SingleDiff = ADC_SINGLE_ENDED;//选择单端输入或差分输入
sConfig.OffsetNumber = ADC_OFFSET_NONE;//选择偏移量数,
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//配置ADC3 序列3
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_3;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; //C_SAMPLETIME_8CYCLES_5;////要为选定通道设置的采样时间值
sConfig.SingleDiff = ADC_SINGLE_ENDED;//选择单端输入或差分输入
sConfig.OffsetNumber = ADC_OFFSET_NONE;//选择偏移量数,
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//配置ADC3 序列4
sConfig.Channel = ADC_CHANNEL_3;//
sConfig.Rank = ADC_REGULAR_RANK_4;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; //C_SAMPLETIME_8CYCLES_5;////要为选定通道设置的采样时间值
sConfig.SingleDiff = ADC_SINGLE_ENDED;//选择单端输入或差分输入
sConfig.OffsetNumber = ADC_OFFSET_NONE;//选择偏移量数,
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
//配置ADC3 序列5
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_5;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; //C_SAMPLETIME_8CYCLES_5;////要为选定通道设置的采样时间值
sConfig.SingleDiff = ADC_SINGLE_ENDED;//选择单端输入或差分输入
sConfig.OffsetNumber = ADC_OFFSET_NONE;//选择偏移量数,
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
// ## - 6 - 启动ADC的DMA方式传输 #######################################
if(HAL_ADC_Start_DMA(&hadc3, (uint32_t *)ADC3Values, (sizeof(ADC3Values)/sizeof(ADC3Values[0]))) != HAL_OK)//单个模式
{
Error_Handler(__FILE__, __LINE__);
}
}
|
|