STM32——ADC

目录

1、ADC的介绍

2、ADC主要特征

3、ADC结构与引脚

4、ADC配置流程

5、示例(光敏电阻的ADC采样)

6、提示

7、结语:


1、ADC的介绍

12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部 信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右 对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。 ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。

2、ADC主要特征

● 12位分辨率

● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断

● 单次和连续转换模式

● 从通道0到通道n的自动扫描模式

● 自校准

● 带内嵌数据一致性的数据对齐

● 采样间隔可以按通道分别编程

● 规则转换和注入转换均有外部触发选项

● 间断模式

● 双重模式(带2个或以上ADC的器件)

● ADC转换时间: ─ STM32F103xx增强型产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs) ─ STM32F101xx基本型产品:时钟为28MHz时为1μs(时钟为36MHz为1.55μs) ─ STM32F102xxUSB型产品:时钟为48MHz时为1.2μs ─ STM32F105xx和STM32F107xx产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)

● ADC供电要求:2.4V到3.6V

● ADC输入范围:VREF- ≤ VIN ≤ VREF+

● 规则通道转换期间有DMA请求产生。

3、ADC结构与引脚

4、ADC配置流程

  1. 时钟使能: 首先需要使能ADC的时钟。这通常涉及到修改RCC寄存器,具体操作取决于你的芯片型号。例如,RCC_APB2Periph_ADC1 (假设ADC1)。 你需要查阅你的芯片数据手册确定正确的寄存器和位。

  2. ADC复位: 通常需要复位ADC,这可以通过设置相应的寄存器位来实现。

  3. ADC配置: 这一步是最关键的,你需要配置ADC的各个参数,这主要通过操作ADC的寄存器来完成。 重要的寄存器包括:

    • ADC_CR1 (控制寄存器1): 配置ADC的模式(单次转换、连续转换)、扫描模式、数据对齐等。
    • ADC_CR2 (控制寄存器2): 配置ADC的触发方式、转换完成中断等。
    • ADC_SMPR1/SMPR2 (采样时间寄存器): 配置ADC的采样时间。
    • ADC_SQR1/SQR3 (正则顺序寄存器): 配置ADC的转换顺序,如果进行多通道转换。
    • ADC_DR (数据寄存器): 读取转换结果。
    • ADC_CSR (校准状态寄存器): 进行ADC校准。
  4. 通道选择: 选择要使用的ADC通道。这通常涉及到设置ADC_SQR1ADC_SQR3寄存器。

  5. ADC校准 (可选): 为了提高精度,可以进行ADC校准。 这通常涉及到设置ADC_CR2寄存器中的CAL位。

  6. ADC使能: 使能ADC,这通常涉及到设置ADC_CR2寄存器中的ADON位。

  7. 启动转换: 启动ADC转换,这通常涉及到设置ADC_CR2寄存器中的SWSTART位,或者通过触发方式启动转换。

  8. 读取数据:ADC_DR寄存器读取转换结果。

  9. ADC关闭 (可选): 转换完成后,可以关闭ADC以节省功耗。

5、示例(光敏电阻的ADC采样)

ADC.h

cpp 复制代码
#ifndef _ADC_H_
#define _ADC_H_


void Light_Init(void);
int Light_Getval(void);

#endif

ADC.c

cpp 复制代码
#include "ADC.h"
#include "stm32f10x.h"

//PB0--ADC1_IN8
void Light_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	
	GPIO_InitTypeDef GPIOB_Struct;
	GPIOB_Struct.GPIO_Mode = GPIO_Mode_AIN;
	GPIOB_Struct.GPIO_Pin = GPIO_Pin_0;
	//GPIOB_Struct.GPIO_Speed
	GPIO_Init(GPIOB,&GPIOB_Struct);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频 clock=12mhz
	
	ADC_InitTypeDef ADC_Struct;
	ADC_Struct.ADC_ContinuousConvMode = DISABLE;
	ADC_Struct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_Struct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_Struct.ADC_Mode = ADC_Mode_Independent;
	ADC_Struct.ADC_NbrOfChannel = 1;
	ADC_Struct.ADC_ScanConvMode = DISABLE;
	ADC_Init(ADC1,&ADC_Struct);
	
	//校准
	ADC_Cmd(ADC1,ENABLE);
	
	//复位校准
	ADC_ResetCalibration(ADC1);
	
	//等待复位结束
	while(RESET != ADC_GetResetCalibrationStatus(ADC1))
	{
		static int count = 0;
		count++;
		if(count > 10000)
		{
			break;
		}
	}
	
	//开启校准
	ADC_StartCalibration(ADC1);
	
	//等待校准结束
	while(RESET != ADC_GetCalibrationStatus(ADC1))
	{
		static int count = 0;
		count++;
		if(count > 10000)
		{
			break;
		}
	}
}

int Light_Getval(void)
{
	//转换顺序,通道选择,采样时间
	ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_55Cycles5);
	//软件触发
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	//等待转换结束
	while(SET != ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC))
	{
		static int count = 0;
		count++;
		if(count > 10000)
		{
			return -1;
		}
	}
	//获取转换结果
	uint16_t ret = ADC_GetConversionValue(ADC1);
	//ret 0~4096
	return 100 - (ret/41);
}

6、提示

keil经常会报警告

ADC.h(8): warning: #1-D: last line of file ends without a newline

解决办法:在最后一行多敲一行空行

原理:

在Keil MDK中,最后一行添加空行并非强制要求,也不是Keil编译器本身的规定。 它更多的是一种编程风格和习惯,并没有实际的功能影响。 一些人认为这样做可以提高代码的可读性和整洁性,方便阅读和维护。

虽然没有强制要求,但这种习惯在嵌入式开发中比较常见,原因如下:

  • 避免潜在的编译器警告或错误: 虽然极少见,但某些编译器在处理文件结尾时可能会有特殊的处理方式,添加空行可以避免一些不必要的警告或错误,特别是对于一些比较老旧的编译器。

  • 版本控制系统: 在使用版本控制系统(如Git)时,在文件末尾添加空行可以避免不必要的冲突,因为不同的编辑器可能会在文件末尾添加不同的换行符。

  • 代码美观和可读性: 这可能是最主要的原因。一个干净整洁的代码文件,在结尾处留一个空行,视觉上会更舒服,也更易于阅读和理解。 这是一种良好的编程习惯,有利于团队合作和代码维护。

  • 习惯: 很多程序员都习惯在文件末尾添加空行,这已经成为一种约定俗成的习惯。

总而言之,在Keil中最后一行加空行主要是一种代码风格和习惯问题,对编译和运行没有任何实际影响,但有助于提高代码的可读性和可维护性。 是否添加完全取决于个人或团队的代码规范。

我的个人意见:好像与团队项目中,代码移植之类的有关系,如果是个人项目,完全可以忽略,如果是团队项目,好像是最后一行会有一些缓存之类的操作,可能团队项目时,整合会发生别人的代码的第一行和你的最后一行在一行里;所以团队项目可以加上空行

7、结语:

还有很多东西没有讲解:比如双adc,比如注入与规则通道等;

本文的目的在于辅助上手;具体的原理在芯片手册中有完整的讲解;有兴趣的同学可以自行查阅

相关推荐
银科院-计算机与人工智能2 小时前
单片机原理及应用笔记:C51数组与项目实践
单片机
WIZnet2 小时前
W55RP20-EVB-Pico评估板介绍
单片机·嵌入式硬件·wiznet·w55rp20·以太网开发板
极客小张3 小时前
基于STM32的实时监测环境系统设计:Flask、SQLite、Vue.js、HTTP/TCP技术
c语言·stm32·单片机·物联网·毕业设计·课程设计·python后端
Wx120不知道取啥名4 小时前
微控制器(MCU)如何运行存储在Flash的程序???
单片机·嵌入式硬件·mcu
云卓科技5 小时前
无人机之中继通信技术篇
科技·嵌入式硬件·安全·机器人·无人机
潇洒的电磁波6 小时前
半波正弦信号的FFT变换
嵌入式硬件
Lin2012306 小时前
STM32 + CubeMX + 硬件SPI + W5500 +TcpClient
stm32·单片机·嵌入式硬件
极客小张6 小时前
基于STM32的智能温室环境监测与控制系统设计(代码示例)
c语言·arm开发·stm32·单片机·嵌入式硬件·物联网·毕业设计
玉树临风江流儿6 小时前
STM32标准库-待机模式
stm32·单片机·嵌入式硬件
北京迅为9 小时前
【北京迅为】《STM32MP157开发板嵌入式开发指南》-第七十六章 C++入门
stm32·单片机·嵌入式硬件