STM32 ADC转换器、串口输出

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:
在工程应用中,除了对数字信号进行处理,常常还要处理模拟信号,这个时候就要用到模拟转换器,也就是模拟信号转换成数字信号的器件。
比如,设置一个比较器,电压低于1v,就输出3.3v,电压高于1v,就输出0v。这个就是我们常见到的一位模数转换器

什么是比较器

快速上手双电压比较器LM393,并制作巡线小车和传感器模块无需单片机【IC原来如此】

https://www.bilibili.com/video/BV1q54y1Z7uU/?spm_id_from=333.337.search-card.all.click


提示:以下是本篇文章正文内容,下面案例可供参考

一、ADC是什么?

ADC 是 Analog-to-Digital Converter 的缩写,意思是模/数转换器或者模数转换器。它是将连续变化的模拟信号转换为离散的数位讯号的器件。这种转换器可以将真实世界的模拟信号,如温度、压力、声音或者图像等,转换成更容易储存、处理和发射的数字形式。

将引用B站大神的作品进行介绍

ADC——模数转换器的基础知识和几个常见类型

https://www.bilibili.com/video/BV1rL411U77J/?spm_id_from=333.337.search-card.all.click

模数转换框图
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、STM32的ADC

STM32中的ADC是12位逐次逼近型ADC,最快转换速度大约1us。

2.1 认识STM32 ADC

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.2转换方式

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.3 为什么要校准?

在这里插入图片描述

2.4 采样时间计算

在这里插入图片描述

2.5 触发方式

在这里插入图片描述

2.6 多通道采集解决方案

在这里插入图片描述

2.7 提高ADC采样时间的方法

在这里插入图片描述

三、如何使用STM32的ADC

3.1. 使用哪个ADC

3.2. 电压基准

3. 3使用什么通道

3.4. 用什么规则

3.5. 时钟来源,配置最大吗?14Mhz

3.6. 如何触发,软件还是硬件

3.7.是否中断 ,读取数据

四、编程步骤

4.1大概步骤

4.1.1 开时钟

4.1.2 配置gpio

4.1.3 初始化ADC_init()

4.1.4 开启转换

4.1.5 等待转换完成

4.1.6 读取转换数据

4.1.7 串口输出显示电压,模拟电压和数字电压

4.2 具体举例:

4.2.1 选用ADC1,

4.2.2 找到ADC1时钟

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启ADC 时钟 
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);// 分频给ADC实际时钟

4.2.3 选定通道及配置

选定通道0
在这里插入图片描述
在这里插入图片描述
引脚配置模式
在这里插入图片描述

通道和引脚对应关系
在这里插入图片描述

	//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
	//2.配置引脚   PA0为模拟输入
	
	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_0;          //TX
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	
	GPIO_Init(GPIOA, &GPIO_InitStruct);   //&x

4.2.4初始化adc

ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);

在这里插入图片描述

在这里插入图片描述

	ADC_InitStruct.ADC_ContinuousConvMode= DISABLE;
	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStruct.ADC_ExternalTrigConv=  ADC_ExternalTrigConv_None;
	ADC_InitStruct.ADC_Mode= ADC_Mode_Independent;
	ADC_InitStruct.ADC_NbrOfChannel= 1;
	ADC_InitStruct.ADC_ScanConvMode= DISABLE;
	ADC_Init(ADC1,  &ADC_InitStruct);

4.2.5.通道参数配置

在这里插入图片描述
在这里插入图片描述

	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5);

4.2.6开启ADC

ADC_Cmd(ADC1, ENABLE);

4.2.7 校准ADC

在这里插入图片描述
在这里插入图片描述

// 复位和校准ADC	
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1));  //为0说明复位完成
	ADC_StartCalibration(ADC1);
	while( ADC_GetCalibrationStatus( ADC1)) ; //为0说明校准完成

4.2.8触发转换和等待转换完成

在这里插入图片描述

在这里插入图片描述

// 软件触发转换  等待转换完成	
	 ADC_SoftwareStartConvCmd( ADC1, ENABLE);

4.2.9 读取数据

4.2.9.1 查询方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

     while(!ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC) );//等待转换完成
	 adc_temp=ADC_GetConversionValue(ADC1);//读取数据
	 printf("ADC的电压为 %d \r\n",adc_temp);

完整的初始化

void adc1_init()
{
	u16 adc_temp;
	ADC_InitTypeDef ADC_InitStruct;
	//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);// 72/6=12
	//2.配置引脚   PA0为模拟输入
			
	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_0;          //TX
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
	
	GPIO_Init(GPIOA, &GPIO_InitStruct);   //&x
	
	ADC_InitStruct.ADC_ContinuousConvMode= DISABLE;
	ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStruct.ADC_ExternalTrigConv=  ADC_ExternalTrigConv_None;
	ADC_InitStruct.ADC_Mode= ADC_Mode_Independent;
	ADC_InitStruct.ADC_NbrOfChannel= 1;
	ADC_InitStruct.ADC_ScanConvMode= DISABLE;
	ADC_Init(ADC1,  &ADC_InitStruct);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5);
	
	ADC_Cmd(ADC1, ENABLE);
	
// 复位和校准ADC	
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1));  //为0说明复位完成
	ADC_StartCalibration(ADC1);
	while( ADC_GetCalibrationStatus( ADC1)) ; //为0说明校准完成
	
// 软件触发转换  等待转换完成	
	 ADC_SoftwareStartConvCmd( ADC1, ENABLE);


     while(!ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC) );
	 adc_temp=ADC_GetConversionValue(ADC1);
	  
	  printf("ADC的电压为 %d \r\n",adc_temp);
					
}
 

程序框架

void main()
{
	...
	//初始化串口
	adc1_init();//复位一次读取一次电压
	while(1)
	{
	}
}

在这里插入图片描述
在这里插入图片描述
问题1: 怎么不断的读取电压

4.2.10 不断读取ADC通道0电压

单独读取通道函数

u16 ADC_channel0()
{
     u16 temp;
	// 软件触发转换  等待转换完成	
	 ADC_SoftwareStartConvCmd( ADC1, ENABLE);
     while(!ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC) );
	 temp=ADC_GetConversionValue(ADC1);
	return temp;

}

整体程序框架

void main()
{
	...
	//初始化串口
	adc1_init();//复位一次读取一次电压
	while(1)
	{
				printf("ADC的电压为 %d \r\n",ADC_channel0());
	}
}

结果
在这里插入图片描述
转换成模拟电压

整体程序框架

void main()
{
	...
	//初始化串口
	adc1_init();//复位一次读取一次电压
	while(1)
	{
				printf("ADC的电压为 %d \r\n",ADC_channel0());
				printf("ADC的电压为 %f \r\n",ADC_channel0()*3.3/4095.0);
	}
}

结果

在这里插入图片描述

五、中断读取ADC电压

5.1 基本步骤

1.配置ADC转换完成中断
2.配置中断优先级
3.写中断服务函数
4.判断中断是否,清楚中断,读取ADC的数值

5.2使能转换完成中断

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStruct.NVIC_IRQChannel=ADC1_2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd= ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=  1;
	NVIC_Init(&NVIC_InitStruct);
	

5.3中断服务函数

在这里插入图片描述

5.4 获取标志位,清楚标志位

在这里插入图片描述

void   ADC1_2_IRQHandler()
{
        if(ADC_GetITStatus(ADC1, ADC_IT_EOC)) // 查标志位
		{
		
		    ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); //清楚标志位
			
			 adc_data=ADC_GetConversionValue(ADC1); //读取数据
			
	     	flag_adc_cm=1;                       //标志位为1 ,主函数判断,然后显示数据
			
			
		}


}

整体程序框架

void main()
{
	...
	//初始化串口
	adc1_init();//复位一次读取一次电压,加入中断配置
	while(1)
	{
		 if(flag_adc_cm==1)
		 {
			printf("ADC的电压为 %d \r\n",adc_data);
			printf("ADC的电压为 %f \r\n",adc_data*3.3/4095.0);
			flag_adc_cm=0;
			 
			 ADC_SoftwareStartConvCmd( ADC1, ENABLE);
			 
		 }
	}
}

5.5 测试结果

在这里插入图片描述

六、思考

  1. 如何实现多通道转换
  2. 如果实现定时器触发转换

总结

讲解了什么是ADC,ADC的工作原理是什么,重点讲解了STM32ADC的框架,举例讲解了ADC电压采集过程,并在串口上显示

  • 19
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Proteus仿真软件是一款广泛应用于电子电路设计和嵌入式系统开发的工具。在使用Proteus进行仿真时,可以使用STM32微控制器进行信号采集和处理。 STM32微控制器是一系列基于ARM Cortex-M处理器核心的嵌入式系统开发平台。其中,ADC(模数转换器)是STM32微控制器的一项重要功能,可以用于采集外部设备输入的模拟信号并转换为数字信号。 在Proteus中,可以通过建立电路原理图并添加STM32微控制器以及其他外部设备,来模拟ADC电压采集的过程。可以根据具体的需要设置ADC的引脚连接和采样率等参数。然后,在仿真过程中,可以向ADC输入一个模拟的电压信号,并通过仿真引擎模拟ADC的转换过程。 虚拟串口输出是指将虚拟信息通过串口进行输出。在STM32微控制器中,可以使用串口通信模块来与外部设备进行数据传输。在Proteus中,可以创建一个虚拟串口,并将其连接到STM32串口引脚上。在仿真过程中,可以通过读取STM32串口输出数据,来获取模拟电压采集结果。通过配置虚拟串口的波特率和其他通信参数,可以模拟实际串口通信的过程。 总之,Proteus仿真基于STM32 ADC电压采集的过程可以通过建立电路原理图、设置ADC参数、模拟输入电压信号、以及配置虚拟串口进行输出数据的方式来实现。这样可以方便地进行电路设计和嵌入式系统开发的测试和验证。 ### 回答2: Protues是一款常用的电子电路仿真软件,可以帮助工程师进行原理图绘制、仿真以及PCB设计等工作。在使用Protues进行基于STM32ADC电压采集仿真时,我们可以通过配置模拟信号源来模拟外部电压输入。首先,我们需要在原理图中将STM32的引脚与ADC模块进行连接,确保正确接入。然后,我们可以选择一个适当的电压源,将其连接到要采集的ADC引脚上,模拟外部电压输入。 在设置完电路连接后,我们需要对STM32ADC模块进行配置。通过设置寄存器的值,我们可以确定ADC的工作模式、采样位数、采样率等参数。在仿真时,我们可以通过逐个改变输入电压的值,来模拟实际环境下的电压变化情况。这样,我们可以通过仿真结果来验证ADC的正确性和准确性。 而关于虚拟串口输出,我们可以通过在原理图中添加虚拟串口模块来模拟串口通讯。虚拟串口模块可以实现从STM32芯片读取数据或向STM32芯片发送数据的功能。在仿真时,我们可以通过设置虚拟串口模块的参数,模拟串口的波特率、数据位、停止位等设置。通过虚拟串口输出模块,我们可以将ADC采集到的数据输出到虚拟串口,并观察输出结果,以验证ADC采集功能的正确性。 总之,通过在Protues中进行基于STM32ADC电压采集仿真,并通过虚拟串口输出模块实现数据输出,我们可以模拟出真实环境中的电路行为,并验证ADC采集功能的正确性。这种仿真方式可以帮助工程师快速调试和验证电路设计,提高工作效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值