目录
配置ADC采集引脚
ADC采集引脚必须配置为模拟输入功能。
注意:需要使用哪个引脚,必须得先查看数据手册,只有含有“ADCx_INx”的引脚才能用作ADC数据采集,并且对应引脚对应固定,不可变。(重点!!!重点!!!重点!!!)
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
GPIO_InitTypeDef ADC_PC1;
//PC1 -> ADC123_IN11 -> ADC1、ADC2、ADC3都可用,通道是通道11
ADC_PC1.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
ADC_PC1.GPIO_Pin=GPIO_Pin_1;
ADC_PC1.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&ADC_PC1);//初始化PC1引脚
复位ADC
配置ADC频率,不能超过14MHz
初始化对应的ADC,引脚上有哪个ADC就初始化哪个。有多ADC时,用哪个就初始化哪个。
#define RCC_PCLK2_Div2 ((uint32_t)0x00000000)
#define RCC_PCLK2_Div4 ((uint32_t)0x00004000)
#define RCC_PCLK2_Div6 ((uint32_t)0x00008000)
#define RCC_PCLK2_Div8 ((uint32_t)0x0000C000)
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择6分频,频率要低于14M
void ADC_DeInit(ADC_TypeDef* ADCx);
ADC_DeInit(ADC1);
配置ADC采集时间
#define ADC_SampleTime_1Cycles5 ((uint8_t)0x00)
#define ADC_SampleTime_7Cycles5 ((uint8_t)0x01)
#define ADC_SampleTime_13Cycles5 ((uint8_t)0x02)
#define ADC_SampleTime_28Cycles5 ((uint8_t)0x03)
#define ADC_SampleTime_41Cycles5 ((uint8_t)0x04)
#define ADC_SampleTime_55Cycles5 ((uint8_t)0x05)
#define ADC_SampleTime_71Cycles5 ((uint8_t)0x06)
#define ADC_SampleTime_239Cycles5 ((uint8_t)0x07)
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_239Cycles5);//ADC1,通道11,采集1个通道,239.5个周期采集一次
配置ADC
配置转换模式
配置对齐方式
配置触发条件
配置采集模式
配置ADC转换数目
配置工作模式
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
ADC_InitTypeDef ADC_1;
//配置ADC
ADC_1.ADC_ContinuousConvMode=DISABLE;//单次转换模式
ADC_1.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_1.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//触发软件
ADC_1.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_1.ADC_NbrOfChannel=1;//ADC转换数目
ADC_1.ADC_ScanConvMode=DISABLE;//单通道工作模式
ADC_Init(ADC1,&ADC_1);//初始化ADC1
使能ADC
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
ADC_Cmd(ADC1,ENABLE);//ADC1使能
使能ADC1、引脚时钟
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);//开启ADC1通道时钟,PC组引脚时钟
校准ADC
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
获取ADC转换结果
u16 ADC_GetDate(){
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能ADC1软件转换
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换结束,规则组转换完成标志位
return ADC_GetConversionValue(ADC1);//获取转换结果
}
例程
例程说明
利用PC1引脚,通过光敏电阻采集电压。
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
#include "stm32f10x.h" // Device header
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_tim.h" // Keil::Device:StdPeriph Drivers:TIM
#include <stm32f10x_rcc.h>
#include <stm32f10x_usart.h>
#include <stm32f10x_sdio.h>
#include <misc.h>
#include <stdio.h>
#include "timch.h"
#include "bsp_SysTick.h"
#include "delay.h"
#include "ADC.h"
#include "usart.h"
#endif
main.c
#include "main.h"
int main() {
u16 date;
ADC1_Init();
delay_init();
uart_init(115200);
while(1){
date=ADC_GetDate();
printf("date:%d 电压:%.2f\n",date,(date*1.0*3.3/4095.0));
delay_ms(100);
}
}
ADC.h
#ifndef __ADC_H_
#define __ADC_H_
#include "stdio.h"
#include "sys.h"
void ADC1_Init();
u16 ADC_GetDate();
#endif
ADC.c
#include "ADC.h"
void ADC1_Init(){
//通道11,ADC1,PC1
GPIO_InitTypeDef ADC_PC1;
ADC_InitTypeDef ADC_1;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1,ENABLE);//开启ADC1通道时钟,PC组引脚时钟
//PC1
ADC_PC1.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
ADC_PC1.GPIO_Pin=GPIO_Pin_1;
ADC_PC1.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&ADC_PC1);//初始化PC1引脚
//复位ADC1
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择6分频,频率要低于14M
ADC_DeInit(ADC1);
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_239Cycles5);//通道11,ADC1,239.5采集一次
//配置ADC
ADC_1.ADC_ContinuousConvMode=DISABLE;//单次转换模式
ADC_1.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_1.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//触发软件
ADC_1.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_1.ADC_NbrOfChannel=1;//ADC转换数目
ADC_1.ADC_ScanConvMode=DISABLE;//单通道工作模式
ADC_Init(ADC1,&ADC_1);//初始化ADC1
ADC_Cmd(ADC1,ENABLE);//ADC1使能
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
}
u16 ADC_GetDate(){
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能ADC1软件转换
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待转换结束,规则组转换完成标志位
return ADC_GetConversionValue(ADC1);//获取转换结果
}