stm32f4xx-ADC
文章目录
- 一、定义
- 二、模数转换过程
- 三、ADC
- 1.精度的理解
- 2.原理图:
- 3.存储对齐方式:
- 4.ADC采集时间
- 5.stm32通道组
- 6.ADC1的通道5(PA5)进行单次转化
- 四、test
一、定义
ADC,Analog-to-Digital Converter的缩写,指模/数转换器或者模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。真实世界的模拟信号,例如温度、压力、声音或者图像等,需要转换成更容易储存、处理和发射的数字形式。模/数转换器可以实现这个功能,在各种不同的产品中都可以找到它的身影。
模拟信号,数值上变化很多,数值是连续的
数字信号,以二进制为代表,数值是离散的,不连续
参考:模拟信号和数字信号的区别和特点-与非网 (eefocus.com)
二、模数转换过程
三、ADC
1.精度的理解
精度越高,数据越是准确。
12位精度:3300mv/4096=0.8mv,也就是说只要电压值有±0.8mv的变化,adc就能分辨出来。
10位精度:3300mv/1024=3.22mv,也就是说只要电压值有±3.22mv的变化,adc就能分辨出来。
8位精度:3300mv/256=12mv,也就是说只要电压值有±12mv的变化,adc就能分辨出来。
6位精度:3300mv/64=51.5625mv,也就是说只要电压值有±51.5625mv的变化,adc就能分辨出来。
2.原理图:
3.存储对齐方式:
4.ADC采集时间
最小采样时间0.42us(ADC时钟=36MHz,采样周期为3周期下得到)
5.stm32通道组
STM32F4的ADC的各通道可以单次,连续,扫描或者间断模式执行
6.ADC1的通道5(PA5)进行单次转化
四、test
void ADC1_CH5_init(void)//可变电阻
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
//打开GPIOA硬件时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//GPIOA的时钟使能
//打开ADC的硬件时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//配置PA5引脚为复用模拟信号引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//ADC常规初始化
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立工作模式,只使用一个ADC
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //ADC硬件时钟=84Mhz/2=42Mhz t = 1/42Mhz
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //不需要映射数据,直接读取寄存器就可以得到结果值
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //5*t = 1/42Mhz
ADC_CommonInit(&ADC_CommonInitStructure);
// ADC1初始化
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位精度
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单个通道,否则为多个通道
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //不断的进行转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不需要内部脉冲触发adc工作
// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐模式
ADC_InitStructure.ADC_NbrOfConversion = 1; //只有单个通道
ADC_Init(ADC1, &ADC_InitStructure);
//将通道5与ADC1关联起来,优先级为1,采样点的时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);
//使能ADCC1工作
ADC_Cmd(ADC1, ENABLE);
//启动adc1的转换
ADC_SoftwareStartConv(ADC1);
}
//PF7/ADC3_IN5
void ADC3_CH5_init(void)//光敏电阻
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
//打开GPIOF硬件时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//打开ADC的硬件时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
//配置PA5引脚为复用模拟信号引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOF, &GPIO_InitStructure);
//ADC常规初始化
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立工作模式,只使用一个ADC
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //ADC硬件时钟=84Mhz/2=42Mhz t = 1/42Mhz
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //不需要映射数据,直接读取寄存器就可以得到结果值
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //5*t = 1/42Mhz
ADC_CommonInit(&ADC_CommonInitStructure);
// ADC3初始化
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位精度
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单个通道,否则为多个通道
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //不断的进行转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不需要内部脉冲触发adc工作
// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐模式
ADC_InitStructure.ADC_NbrOfConversion = 1; //只有单个通道
ADC_Init(ADC3, &ADC_InitStructure);
//将通道5与ADC3关联起来,优先级为1,采样点的时间
//ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);
//使能ADCC3工作
ADC_Cmd(ADC3, ENABLE);
//启动adc3的转换
//ADC_SoftwareStartConv(ADC3);
}
//获得ADC值
//ch:通道值 0~16 ADC_Channel_0~ADC_Channel_16
//返回值:转换结果
uint16_t Get_Adc3(uint8_t ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_480Cycles ); //ADC3,ADC通道,480个周期,提高采样时间可以提高精确度
ADC_SoftwareStartConv(ADC3); //使能指定的ADC3的软件转换启动功能
while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC3); //返回最近一次ADC3规则组的转换结果
}
int main(void)
{
USART1_init(115200);
uint16_t adc_val,adc_vol;
ADC1_CH5_init();
ADC3_CH5_init();
while(1)
{
//等待ADC1转换完毕
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
//得到结果值
adc_val = ADC_GetConversionValue(ADC1);
//将结果值转换为电压值
adc_vol = adc_val*3300/4095;
printf("adc_val:%d\r\n", adc_val);
printf("adc_vol:%dmv\r\n", adc_vol);
delay_ms(1000);
}