ADC介绍
STM32f103 系列有3个ADC,精度为12位,每个ADC最多有16个外部通道。其中ADC1和ADC2都有16个外部通道, ADC3根据CPU引脚的不同通道数也不同,一般都有8个外部通道。ADC的模式非常多,功能非常强大,具体的我们在功能框图中分析每个部分的功能。
程序介绍
1.bsp_adc.c
/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp/adc/bsp_adc.h"
/**
* 函数功能: ADC GPIO 初始化
*/
static void ADCx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 打开 ADC IO端口时钟 */
ADC_APBxClock_FUN(ADC_GPIO_CLK, ENABLE );
/* 配置 ADC IO 引脚模式 */
GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
/* 初始化 ADC IO */
GPIO_Init(ADC_PORT, &GPIO_InitStructure);
}
/**
* 函数功能: 配置ADC工作模式
*/
static void ADCx_Mode_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
/* 打开ADC时钟 */
ADC_APBxClock_FUN(ADC_CLK,ENABLE );
/* ADC 模式配置 */
/* 只使用一个ADC,属于单模式 */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
/* 禁止扫描模式,多通道才要,单通道不需要 */
ADC_InitStructure.ADC_ScanConvMode = DISABLE ;
/* 连续转换模式 */
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/* 不用外部触发转换,软件开启即可 */
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
/* 转换结果右对齐 */
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/* 转换通道1个 */
ADC_InitStructure.ADC_NbrOfChannel = 1;
/* 初始化ADC */
ADC_Init(ADCx, &ADC_InitStructure);
/* 配置ADC时钟为PCLK2的8分频,即9MHz */
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/* 配置 ADC 通道转换顺序为1,第一个转换,采样时间为55.5个时钟周期 */
ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);
/* ADC 转换结束产生中断,在中断服务程序中读取转换值 */
ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
/* 开启ADC ,并开始转换 */
ADC_Cmd(ADCx, ENABLE);
/* 初始化ADC 校准寄存器 */
ADC_ResetCalibration(ADCx);
/*等待校准寄存器初始化完成 */
while(ADC_GetResetCalibrationStatus(ADCx));
/* ADC开始校准*/
ADC_StartCalibration(ADCx);
/*等待校准完成 */
while(ADC_GetCalibrationStatus(ADCx));
/* 由于没有采用外部触发,所以使用软件触发ADC转换 */
ADC_SoftwareStartConvCmd(ADCx, ENABLE);
}
/**
* 函数功能: NVIC配置:ADC中断优先级配置
*/
static void ADC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置中断优先级 */
NVIC_InitStructure.NVIC_IRQChannel = ADCx_IRQ;
/* 设置抢占式优先级为0 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
/* 设置子优先级为0 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
/* 使能外部中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置嵌套向量中断控制器 */
NVIC_Init(&NVIC_InitStructure);
}
/**
* 函数功能: ADC初始化
*/
void ADCx_Init(void)
{
ADCx_GPIO_Config();
ADC_NVIC_Config();
ADCx_Mode_Config();
}
2.bsp_adc.h
#ifndef __ADC_H__
#define __ADC_H__
/* 包含头文件 ----------------------------------------------------------------*/
#include <stm32f10x.h>
// 注意:用作ADC采集的IO必须没有复用,否则采集电压会有影响
/********************ADC输入通道(引脚)配置**************************/
#define ADC_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADCx ADC3
#define ADC_CLK RCC_APB2Periph_ADC3
#define ADCx_IRQ ADC3_IRQn
#define ADC_IRQHandler_FUN ADC3_IRQHandler
#define ADC_GPIO_CLK RCC_APB2Periph_GPIOC
#define ADC_PORT GPIOC
#define ADC_PIN GPIO_Pin_0 // 连接至板载精密可调电阻(需加跳帽)
#define ADC_CHANNEL ADC_Channel_10 // 连接至板载精密可调电阻(需加跳帽)
//#define ADC_PIN GPIO_Pin_1 // 连接至板载光敏电阻(需加跳帽)
//#define ADC_CHANNEL ADC_Channel_11 // 连接至板载光敏电阻(需加跳帽)
/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
void ADCx_Init(void);
#endif /* __ADC_H__ */
3.main.c
/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x.h"
#include "bsp/led/bsp_led.h"
#include "bsp/key/bsp_key.h"
#include "bsp/delay/delay.h"
#include "bsp/systick/bsp_SysTick.h"
#include "bsp/GeneralTIM/bsp_GeneralTIM.h"
#include "bsp/adc/bsp_adc.h"
/* 用于保存转换计算后的电压值 */
float ADC_ConvertedValueLocal;
/* 扩展变量 ------------------------------------------------------------------*/
extern __IO uint16_t ADC_ConvertedValue;
/* 私有函数原形 --------------------------------------------------------------*/
static void Delay(uint32_t time);
/**
* 函数功能: 主函数.
*/
int main(void)
{
/* 调试串口初始化配置,115200-N-8-1.使能串口发送和接受 */
USARTx_Init();
/* ADC 初始化 */
ADCx_Init();
/* 调用格式化输出函数打印输出数据 */
printf("----这是一个ADC单通道电压采集实验-----\n");
/* 无限循环 */
while (1)
{
ADC_ConvertedValueLocal =(float)ADC_ConvertedValue*3.3/4096;
printf("AD转换原始值 = 0x%04X \r\n", ADC_ConvertedValue);
printf("计算得出电压值 = %f V \r\n",ADC_ConvertedValueLocal);
Delay(1000);
}
}