1.基本概念 : Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件 。典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。
2.STM32F4x ADC特点
1. 可配置12位、10位、8位或6位分辨率
2. 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断单次和连续转换模式
3. 用于自动将通道О转换为通道“n”的扫描模式数据对齐以保持内置数据一致性
4. 可独立设置各通道采样时间
5. 外部触发器选项,可为规则转换和注入转换配置极性不连续采样模式。
6. 双重/三重模式(具有2个或更多ADC的器件提供)
7. 双重/三重ADC模式下可配置的 DMA数据存储双重/三重交替模式下可配置的转换间延迟
8. ADC转换类型(参见数据手册)
9. ADC电源要求:全速运行时为2.4V到3.6 V,慢速运行时为1.8 VADC
10.输入范围:VREF-≤VIN ≤VREF+
11. 规则通道转换期间可产生DMA请求。
3. STM32F40x系列ADC外部通道和引脚对应关系
4.ADC引脚
5.STM32通道组
理解图:
6. ADC 通道执行的模式
STM32F4的ADC的各通道可以单次,连续,扫描或者间断模式执行。
7. 单次转化VS连续转换
8.ADC中断
10 . ADC 的实验步骤
11. 中文手册 (原理图)
12. 光敏电阻
光照越大, 电阻越小, 电压越小
光照越小, 电阻越大, 电阻越大
13. 代码:
头文件:
#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
void myAdcInit(void); //ADC通道初始化
u16 getAdc(u8 ch); //获得某个通道值
u16 getAdcAverage(u8 ch,u8 times);//得到某个通道给定次数采样的平均值
#endif
.cpp 文件
#include "myadc.h"
#include "delay.h"
/*
使用ADC1
ADC_IN0 --->光照--->PA0
ADC_IN10 --->可变电压输入--->PC0
ADC_IN8--->J15-->PB0---烟雾传感器
ADC_IN9--->J14-->PB1 --->酒精传感器
*/
//初始化ADC
void myAdcInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
//1.A组时钟配置
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOC时钟
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
//2.配置adc1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
//3先初始化ADC1通道0 IO口 PA0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0 通道0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 PA0
//4.重新启动时钟命令函数
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
//独立模式
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
//两个采样阶段之间的延迟5个时钟
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
//DMA失能
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
//5.adc 341行
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
//12位模式
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
//非扫描模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
//关闭连续转换
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
//禁止触发检测,使用软件触发
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
//右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//1个转换在规则序列中 也就是只转换规则序列1
ADC_InitStructure.ADC_NbrOfConversion = 1;
//6.adc初始化
ADC_Init(ADC1, &ADC_InitStructure);
//7开启AD转换器
ADC_Cmd(ADC1, ENABLE);
// //初始化ADC1 通道10 IO口 PC0
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PC0 通道10
// GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 PC0
// //初始化ADC1 通道8(PB0),通道9(PB1) GPIO口
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//PB0 通道8
// GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 PB1 通道9
}
//获得ADC值
//ch: @ref ADC_channels
//通道值 0~16取值范围为:ADC_Channel_0~ADC_Channel_16
//返回值:转换结果
u16 getAdc(u8 ch)
{
//ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
//使能指定的ADC1的软件转换启动功能
ADC_SoftwareStartConv(ADC1);
//等待转换结束
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
//返回最近一次ADC1规则组的转换结果
return ADC_GetConversionValue(ADC1);
}
//获取通道ch的转换值,取times次,然后平均
//ch:通道编号
//times:获取次数
//返回值:通道ch的times次转换结果平均值
u16 getAdcAverage(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t
main.cpp (可能你用不了)
#include "stm32f4xx.h"
#include "oled.h"
#include "beep.h"
#include "led.h"
#include "iic.h"
#include "delay.h"
#include "mydht11.h"
#include "myadc.h"
#include "stdio.h"
//主程序:新数组存储数据 你采集到的数据
//字符数组
char guangzhao[30];
int main(void)
{
//各种初始化
delay_init(168);
IIC_Init();
InitOLed();
myAdcInit();
//usartinit();
while(1)
{
//显示光照汉字
OLed_ShowLight();
//显示光照数值
sprintf(guangzhao,"%d",getAdcAverage(0,4));
// if(key1 == 0 )
// {
// reslight = getAdcAverage(0,4);
// }
//串口传递字符数组
OLed_ShowASCII(56,4,guangzhao);
}
}