STM32-微项目08-ADC单通道/多通道模式采集

huo

一、微项目实现目标:

1,利用STM32内置的ADC模块,将外部模拟量信号(0-3.3v)转化成12位有效(16位数据)的数字量(0-4095),在将采集的数字除4095,就会得到对应采集的模拟量信号;

二、微项目硬件配置需求:

 stm32F103C8T6核心板一块;

0.96寸OLED显示,用于显示计数;

模拟量输入(滑动电阻、光线传感器、温度传感器等),接线时刻,需要接AO输出口;

 

三、前置知识:

1,逐次逼近型ADC的处理逻辑

在外部有模拟量输入时,DAC设置参数并输出模拟量,对比模拟量数据和输入的模拟量相近或相等时刻,则配置输出的DAC的数字量参数,就是输入模拟量的对应转化后的数字量;

 2,ADC整体控制逻辑框图

 ①数据流:外部GPIO模拟量-----AD转换器(注入组和规则组)-----触发转化 ----转化数值存放到AD数据寄存器中

②ADC关键模块解析

 图中2:表示外部模拟量的输入端口,有18个通道入口其中0-15是外部接口

图中1:表示启动ADC启动

图中3:表示ADC的时钟,ADC1最大接受时钟14MHZ的,外部接入72MHZ,需要配置分频处理;

图中4:具体转化执行模块

图中5:注入通道和规则通道寄存器,转化后数据存放在这。其中规则通道只有一个,所有转化后,需要立即取走,否则后续转化数据会覆盖掉;

图中6:DMA请求,ADC转化后,配合DMA模式进行数据转移;

③输入通道及转化模式

1-ADC1通道情况

1)单次模式和连续模式:数据转化时,是否连续转化。单次模式,仅转化一次;连续模式时,转换一次 后再从头开始重新转化;

2)扫描模式和非扫描模式:扫描模式,就是将序列中数据从头到尾全部转化;非扫描模式,仅转化序列中的第一个;

3)几种数据转化模式:

单次转换,非扫描模式

 连续转换,非扫描模式

单次转换,扫描模式

 

 连续转换,扫描模式

 

④触发转化,一般选用软件触发

 ⑤转化后,寄存器数据对齐方式,一般选用靠右侧对齐

 ⑥转化校准,具体代码中执行

四、代码逻辑分析:

①开启GPIO和ADC的时钟,并且对输入ADC通道进行分频处理;

②配置GPIO模式,模拟输入

③配置AD输入通道,即配置输入通道和所在处理序列;

④初始化AD模块,并配置AD模式\数据对齐\扫描模式\连续模式等

⑤打开ADC使能开关(并非开启后ADC就会工作,需要软件触发源触发执行)

⑥执行AD校准模块

⑦开启软件触发ADC执行工作

五、代码示例:

①开启GPIO和ADC的时钟,并且对输入ADC通道进行分频处理;

	//打开ADC1时钟 和GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//配置ADC1的分频,ADC最高支持14mhz
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);

②配置GPIO模式,模拟输入

	//初始化GPIO模块,模拟输入模式
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStruct);

③配置AD输入通道,即配置输入通道和所在处理序列;

第二个参数:通道接入的端口

第三个参数:规则序列的位置

第四个参数:采样时间

//配置ad输入通道
	ADC_RegularChannelConfig( ADC1,  ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

④初始化AD模块,并配置AD模式\数据对齐\扫描模式\连续模式等

	//初始化AD模块
	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);

⑤打开ADC使能开关(并非开启后ADC就会工作,需要软件触发源触发执行)

//开启adc电源
	ADC_Cmd(ADC1,ENABLE);

⑥执行AD校准模块

//ADC校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);//完成后会被硬件置为reset
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);

⑦获取转化后的寄存器数值

注意是先进行软件触发,之后等待标志位E0C,再返回数据

uint16_t AD_getvalue(void)
{
	ADC_SoftwareStartConvCmd( ADC1, ENABLE);//软件触发转换
	
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	//转化完成后,返回的是reset.读完后,对应寄存器会自动变为reset
	return  ADC_GetConversionValue(ADC1);
}

最后在主函数中,简答配置

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "OLED.H"
#include "ad.H"

uint16_t advalue=0;
float voltage=0.0;
int main()
{
	OLED_Init();
	ADC_init();
	OLED_ShowString(1,1,"ADvalue:");
	OLED_ShowString(2,1,"voltage:0.00v");
	while(1)
	{
		advalue= AD_getvalue();
		voltage=(float)advalue/4095*3.3;//输出电压
		OLED_ShowNum(1,9,advalue,4);
		OLED_ShowNum(2,9,voltage,1);
		OLED_ShowNum(2,11,(uint16_t)(voltage*100)%100,2);
		Delay_ms(1000);
	}
}

  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值