时钟来自于APB2
Clock Prescaler:ADC时钟;时钟不超过36M(从ABP2时钟分出)。
Resolution:分辨率;例如我们选12bits,即使把采集数据分成2^12。
Data Alignment:数据对齐方式
因为ADC得到的数据是12位精度的,但是数据存储在 16 位数据寄存器中,所以ADC的存储结果可以分为左对齐或右对齐方式(12位)
举例,下方为右对齐,最左侧为0,无效数据
Scan Conversion Mode:连续扫描模式;用于多通道,单通道不选。用于多通道时,会按照Rank设置的顺序扫描。
扫描模式简单的说就是对所选中的所有通道进行转换,比如开了ch0,ch1,ch4,ch5。 ch0转换完以后就会自动转换通道1,4,5直到转换完这个过程不能被打断。如果开启了连续转换模式,则会在转换完ch5之后开始新一轮的转换。
Continuous Conversion Mode和Discontinuous Conversion Mode:连续转化还是单次转换,二选一
End Of Conversion Selection:转换结束选择
每个通道转换结束后EOC置1,即转换完成
所有通道转换结束后EOC置1,即转换完成
DMA Continuous Requests:DMA接收转换数据
Number Of Conversion:转换规则通道数
External Trigger Conversion Source: 外部触发转换事件
External Trigger Conversion Edge:外部触发转换极性,
Rank:转化顺序;数据排列与其一致
Channel:通道。
Sampling Time:采集时间。
注入通道和规则通道一样
中断触发条件有三个,规则通道转换结束,注入通道转换结束,或者模拟看门狗状态位被设置时都能产生中断
模拟看门狗中断当被ADC转换的模拟电压值低于低阈值或高于高阈值时,便会产生中断。阈值的高低值由ADC_LTR和ADC_HTR配置
模拟看门狗,听他的名字就知道,在ADC的应用中是为了防止读取到的电压值超量程或者低于量程
代码如下(示例):
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; //12位分辨率
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_LEFT;//左对齐方式
ADC_InitStruct.SequencersScanMode = LL_ADC_SEQ_SCAN_ENABLE;//扫描方式使能
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;//软件触发
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS;//规则组长度5
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;//非连续转换
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;//连续转换
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;//DMA传输
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
LL_ADC_REG_SetFlagEndOfConversion(ADC1, LL_ADC_REG_FLAG_EOC_UNITARY_CONV);//
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV8;//分频
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_10);//
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_15CYCLES);//
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_11);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SAMPLINGTIME_15CYCLES);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_12);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_15CYCLES);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_13);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_13, LL_ADC_SAMPLINGTIME_15CYCLES);
/** Configure Regular Channel
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_14);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_14, LL_ADC_SAMPLINGTIME_15CYCLES);
/* 添加代码, */
LL_ADC_Enable(ADC1);//使能ADC
LL_ADC_REG_StartConversionSWStart(ADC1);//开启转换
ADC采集3.3V电压
代码如下(示例):
uint16_t Get_Val(uint16_t times)
{
uint16_t temp=0;
uint16_t i=0;
LL_ADC_REG_StartConversionSWStart(ADC1);
for(i=0;i<times;i++)
{
temp+=LL_ADC_REG_ReadConversionData12(ADC1);
}
return temp/times;
}
主函数程序如下:
int main(void)
{
/* USER CODE BEGIN 1 */
uint16_t val=0;
float temp=0;
/* USER CODE END 1 */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
val=Get_Val(5);
LL_mDelay(10);
temp=val*(3.3/4096);//电压转换
printf("%f\n\r",temp);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
ADC采集0V电压的寄存器值
ADC采集3.3V电压的寄存器值