目录
#ADC
#ADC学习相关涉及概念介绍
#ADC相关概念介绍
#软件实现
#常用结构体配置介绍
#常用函数介绍
#软件编写,完成效果。
#ADC
#ADC学习相关涉及概念介绍
数字信号(Digital Signal):数字信号用最为常见的二进制数来表示的信号,也就是 0 1 ,数字信号就是 0 和1 组成的信号,取值是有限制的变化范围也是有限制的,这种信号可以由ADC连续的采样转化得到;
模拟信号(Analog Signal):模拟信号不像数字信号,其信号可以随意变化,其取值没有受限,在一个范围内取值,是随意地,这是二者的差别,通常由传感器采样得到,这种信号。
ADC采样:对模拟信号按照相等时间进行切片,这个操作会导致丢失一些信息。ADC采样的频率越高,得到的数字信号就越接近原来的模拟信号,也就是保真度越高,但是需要更多的资源和计算功耗。
ADC量化:这个过程就是将每个切片进行,四舍五入得到一个具体的数字取值
ADC编码:编码就是将量化得到的数字取值,进行二进制转换,这个取值的结果就是数字信号,二进制编码的位宽等于ADC的位宽。(这里就是 12位ADC比8位ADC精度高的原因),具体过程见下图。
ADC相关定义:Analog-to-Digital Conversion, ADC,用于将模拟信号转化为数字信号
DAC相关定义:Digital-to-Analog Conversion, DAC,用于将数字信号转化为模拟信号,与上一条相反,这里本章介绍ADC而不是DAC,DAC转换需要经历 解码 重构。
DAC解码:将数字信号里面的值重新转化为数值
DAC重构: 将解码过后的数值进行换化为连续的模拟信号,这个过程需要使用插值或者滤波 技术
分辨率:ADC位数,通常有,8位、10位、12位等,位数越高,精度越高,这个用在编码环节将数值转化为ADC的位宽。
采样率: 表示ADC对模拟输入信号进行采样的速率,通常以每秒采样次数(samples per second,SPS)表示,也称为转换速率,表示ADC能够进行多少次模拟到数字的转换。
采样范围:指ADC可以采集到的模拟输入信号的电压范围,范围见下:
V(REF-) ≤ ADC ≤ V(REF+)
其中V(REF- )为负参考电压等于 V(SSA )等于地0V,V(REF+ )为正参考电压等于V(DDA)也就是3.3V。
#ADC相关概念介绍
ADC(Analog-to-Digital Conversion),的工作原理是将模拟信号通过采样转换为离散的数字信号,然后再通过量化、编码等处理,最终结果也就是得到数字信号。
STMF4有12位ADC,19路通道,这些通道是用来进行ADC准换或者DAC转换,每个ADC通道可以配置为 单次 连续 扫描 间接准换模式 ,具体看下图数据手册
单次转换模式:每进行一次ADC转换过后,ADC会自动停止工作,不在进行转换。
连续转换模式:当进行ADC转换过后,还会连续进行ADC转换,直到软件触发停止转换
扫描模式:对于多个ADC通道,按照顺序依次进行转换,完成后自动切换到常规通道。
#软件实现
#配置细节介绍
ADC配置时钟要求在40MHz以下,具体见下图数据手册(实验2分频),GPIO配置为模拟输入,这个模式专门用于,输入模拟电路也就是(DO)
#软件编写,完成效果。
void ADC_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//开启时钟,GPIO系列挂在在AHB总线上面
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;//这里配置为模拟输入模式功能
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
}
初始化GPIO,这里注意需要配置模拟输入,配置为模拟就自动代表为输入
void ADC_Base_Init(void)
{
ADC_CommonInitTypeDef ADC_CommonInitStruct;
ADC_DeInit();//ADC复位
ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;
ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div2;//这里设计预分频系数为2
ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStruct);
ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//禁止连续转换模式
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//数据设置为右对齐
ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//使用软件触发ADC转换
ADC_InitStruct.ADC_NbrOfConversion=1;//转换数量为1
ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;//ADC分辨率为12位
ADC_InitStruct.ADC_ScanConvMode = DISABLE;//禁止用扫描模式
ADC_Init(ADC1,&ADC_InitStruct);
//ADC1使能
ADC_Cmd(ADC1, ENABLE);
}
初始化ADC模块外设
unsigned int Get_ADC_Value(uint8_t ADC_CHANNEL_x)
{
unsigned int adc_value = 0;
//设置采集通道
ADC_RegularChannelConfig( ADC1, ADC_CHANNEL_x, 1, ADC_SampleTime_480Cycles );
//开始软件转换
ADC_SoftwareStartConv(ADC1);
// 等待转换结束
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
//读取采样值
adc_value = ADC_GetConversionValue(ADC1);
//返回采样值
return adc_value;
}
uint16_t Get_Adc_Average(uint8_t CHx,uint8_t times)//
{
uint32_t value = 0;
uint8_t t;
for(t=0;t<times;t++)
{
value += Get_ADC_Value(CHx);
delay_ms(5);
}
return value/times;
}
int main(void)
{
board_init();
uart1_init(115200U);
ADC_GPIO_Init();
ADC_Base_Init();
while(1)
{
uint16_t value = Get_Adc_Average(ADC_Channel_5,20);
printf("value = %d\r\n", value);
delay_ms(1000);
}
}
在主函数里面调用
参考文章在最后, 希望对你有所帮助!!!
【立创·天空星STM32F407VET6】入门手册 - 飞书云文档 (feishu.cn)