ADC模块
模数转换器,ADC可以将引脚变换的模拟电压转换成内存中对应的数字变量,建立模拟量和数字量的桥梁。STM32C8芯片挂载12位逐次逼近型ADC,12表示ADC范围为0~2^12=4095.
ADC有18个输入通道,16个外部输入,两个内部输入信号源(温度传感器:检测内部CPU温度和参考电压)
ADC参考手册电路
ADC转换模式
扫描/非扫描,连续/非连续
ADC配置库函数
void AD_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择内部时钟6分频,ADC只能选择6或者8,不然会超出频率
//配置GPIO参数
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//规则组配置
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//可以理解点菜菜单的选择,通道1对应引脚就是我们想要读取外部模拟数据的引脚,规则组序列次序设置为1,总共有16个序列,16个通道
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//触发源选择,这边选择软件触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//连续模式不开启
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描模式不开启
ADC_InitStructure.ADC_NbrOfChannel = 1;//扫描模式下,会使用几个通道
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);//开启ADC
//ADC模块的校验
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
}
//AD单通道
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//判断转换是否完成
return ADC_GetConversionValue(ADC1);//规则组只有一个数据寄存器,所以只能返回一路数据
}
//AD多通道
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);//规则组配置哪个通道就读取哪个通道的数据
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
return ADC_GetConversionValue(ADC1);
}
//在main函数中调用,这样就可以读取4路通道的数据了
AD0 = AD_GetValue(ADC_Channel_0);
AD1 = AD_GetValue(ADC_Channel_1);
AD2 = AD_GetValue(ADC_Channel_2);
AD3 = AD_GetValue(ADC_Channel_3);
上述代码的实现均是采用规则组配置。而且配置都是非连续的非扫描的模式,因为是规则组只有一个数据寄存器,所以无法一次读出多组数据,想要一次性读多组数据,就要配合DMA进行数据转运,或者使用注入组,可以读取最多四路数据。