一、简介
ADC(analog to digital converter)即模数转换器,它可以将模拟信号转换为数字信号。按照其转换原理主要分为逐次逼近型、双积分型、电压频率转换型三种。
STM32F1xx ADC特性:
● 12 位分辨率
● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
● 单次和连续转换模式
● 从通道 0 到通道 n 的自动扫描模式
● 自校准
● 带内嵌数据一致性的数据对齐
● 采样间隔可以按通道分别编程
● 规则转换和注入转换均有外部触发选项
● 间断模式
● 双重模式(带 2 个或以上 ADC 的器件)
● ADC 转换时间
【注意:】
STM32F1 的 ADC 是 12 位转换精度,而数据寄存器是 16 位,所以 ADC在存放数据的时候就有左对齐和右对齐区分。如果是左对齐,AD 转换完成数据存放在 ADC_DR 寄存器的[4:15]位内;如果是右对齐,则存放在 ADC_DR 寄存器的[0:11]位内。
使用PB0与PB1采集两个电位器模拟信号、此两脚分别对ADC12_IN8\ADC12_IN9。
1、通过 ADC1_2 通道 8 采样外部电压值。
2、通过 ADC1_2通道 9 采样外部电压值。
输入电压范围
ADC 输入范围为:VREF- ≤ VIN ≤ VREF+。由 VREF-、VREF+ 、VDDA 、VSSA、这四个外部
引脚决定。
一般把 VSSA 和 VREF-接地,把 VREF+和 VDDA 接 3V3
ADC时钟
ADC 输入时钟 ADC_CLK 由 PCLK2 经过分频产生,最大是 14M。
APB1:SystemClock=HCLK/4=PCLK1=18M
APB2:SystemClock=HCLK/4=PCLK2=18M
Tconv = 采样时间 + 12.5 个周期。(Tconv 为 ADC 总转换时间/采样周期为:1/ADC_CLK)
当 ADCLK = 14MHZ (最高),采样时间设置为 1.5 周期(最快),那么总的转换时间(最短)Tconv = 1.5 周期 + 12.5 周期 = 14 周期 = 1us(即ADC 最大的转换速率为 1Mhz)。
二、编码
2.1、DMA配置
// 1、DMA_Chx DMA通道 2、Dpba 外设地址 3、Dmba 存储器地址 4、Dbse DMA通道的缓冲区大小
void DMA_Config(DMA_Channel_TypeDef* DMA_Chx,uint32_t Dpba,uint32_t Dmba,uint32_t Dbs)
{
DMA_InitTypeDef DMA_InitStructure;
// 使能时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 复位DMA控制器
DMA_DeInit(DMA_Chx);
// 配置结构体
DMA_InitStructure.DMA_PeripheralBaseAddr=Dpba; // 外设地址
DMA_InitStructure.DMA_MemoryBaseAddr=Dmba; // 存储器地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;// 数据传输方向:从内存读发送到外设
DMA_InitStructure.DMA_BufferSize=Dbs; // DMA缓冲区大小=数据目的地的大小
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable; // 指定外设地址寄存器是否递增.只有一个不递增
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable; // 内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; // 外设数据宽度为半字,即两个字节
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord; // 内存数据宽度为半字
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; // DMA工作模式 循环输出模式 正常工作模式DMA_Mode_Normal
DMA_InitStructure.DMA_Priority=DMA_Priority_High; // 优先级 DMA 传输通道优先级为高,当使用一个 DMA 通道时,优先级设置不影响
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁用内存到内存的传输模式 外设->内存
DMA_Init(DMA_Chx,&DMA_InitStructure);
DMA_Cmd(DMA_Chx,ENABLE);
}
2.2、ADC配置
void ADC_IN_x_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
// 使能ADC时钟
RCC_APB2PeriphClockCmd(ADC_RCC,ENABLE);
// ADC结构体配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式 每个ADC接口独立工作
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 非扫描模式 单通道
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; // 连续转换 一次转换 多次转换
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; // 定时器一触发ADC_ExternalTrigConv_T1_CC1 禁止触发检测、使用软件触发 ADC_ExternalTrigConv_None
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right; // 右对齐
ADC_InitStructure.ADC_NbrOfChannel=2; // 2个转换在规则序列中
ADC_Init(ADC1,&ADC_InitStructure);
// 配置ADC时钟分频因子 不超过14M RCC_PCLK2_Div2: ADC clock = PCLK2/2=9M
RCC_ADCCLKConfig(RCC_PCLK2_Div2);
// 配置ADC通道的转换顺序和采样时间 第三个参数:通道的转换顺序
//
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); // 配置 ADC 通道转换顺序为 1,第一个转换,采样时间为 55.5 个时钟周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_55Cycles5);
//ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // ADC 转换结束产生中断,在中断服务程序中读取转换值
ADC_DMACmd(ADC1,ENABLE); // 使能ADC DMA请求
// 使能ADC并开始转换
ADC_Cmd(ADC1,ENABLE);
// 初始化并校准寄存器
ADC_ResetCalibration(ADC1);
// 等待校准寄存器初始化完成
while(ADC_GetResetCalibrationStatus(ADC1));
// ADC开始校准
ADC_StartCalibration(ADC1);
// 等待校准完成
while(ADC_GetCalibrationStatus(ADC1));
// 软件触发ADC转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
2.3、初始化配置
void ADC_XY_Init(void)
{
// 使能ADC时钟
//RCC_APB2PeriphClockCmd(ADC_RCC,ENABLE);
// x轴 引脚初始化 模拟输入
GPIOxInit(ADC_PORT_RCC,ADC_PORT,ADC_X_PIN|ADC_Y_PIN,GPIO_Mode_AIN);
// DMA配置 1、DMA通道 2、外设地址 3、存储器地址 4、缓冲区大小,应该等于数据目的地的大小
DMA_Config(ADC_DMA_CHANNEL,(u32)(&( ADC1->DR )),(u32)DMA_Buff,NOFCHANEL);
// ADC配置
ADC_IN_x_Config();
}