一、编程要点
1、初始化ADC相关GPIO
2、设置ADC工作参数
1)配置ADC工作时钟
2)转换通道顺序和采样时间
3)使能转换完成通道
4)使能软件触发
3、配置中断分组
4、编写中断服务函数
二、结构体&库函数
1、ADC 初始化结构体
typedef struct
{
uint32_t ADC_Mode; /*!< ADC工作模式 单独工作模式 */
FunctionalState ADC_ScanConvMode; /*!< 是否使用扫描 */
FunctionalState ADC_ContinuousConvMode; /*!< 是否使用连续转换 */
uint32_t ADC_ExternalTrigConv; /*!< 外部触发选择 */
uint32_t ADC_DataAlign; /*!< 数据对齐模式 左右对齐 */
uint8_t ADC_NbrOfChannel; /*!< ADC转换通道 */
}ADC_InitTypeDef;
2、ADC时钟配置函数
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
@brief 配置ADC工作时钟 2/4/6/8分频(最快12M)
@param1:ADC分频系数
3、ADC转换配置函数
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
//转换规则 ADC号 通道号 转换顺序 取样时间
ADC_RegularChannelConfig(ADC_x , ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
@brief ADC转换配置
4、中断使能函数
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState)
ADC_ITConfig( ADC_x, ADC_IT_EOC, ENABLE); //ADC中断使能
@brief :ADC中断使能
@param1:ADC号
@param2:中断方式
@param3:使能或使能
5、ADC校准函数
// ADC开始校准
ADC_StartCalibration(ADC_x);
// 等待校准完成
while(ADC_GetCalibrationStatus(ADC_x));
三、中断服务函数
void ADC1_2_IRQHandler(void)
{
if(ADC_GetITStatus( ADC_x, ADC_IT_EOC)==1) //确定中断到来
{
ADC_Value=ADC_GetConversionValue(ADC_x ); //获取转换值
}
ADC_ClearITPendingBit( ADC_x, ADC_IT_EOC); //清除中断标志位
四、程序源码
1、bsp_adc.h
#ifndef __BSP_ADC_H
#define __BSP_ADC_H
#include "stm32f10x.h"
//ADC相关GPIO 时钟 外设
#define RCC_GPIO_CLOCK RCC_APB2PeriphClockCmd
#define RCC_GPIO_PERIPH RCC_APB2Periph_GPIOC
#define GPIO_PORT GPIOC
#define GPIO_PIN GPIO_Pin_1
#define RCC_ADC_CLOCK RCC_APB2PeriphClockCmd
#define RCC_ADC_PERIPH RCC_APB2Periph_ADC1
#define ADC_x ADC1
#define ADC_IRQn ADC1_2_IRQn
void ADC_Init_Config(void);
#endif /* __BSP_ADC_H */
2、bsp_adc.c
#include "bsp_adc.h"
static void ADC_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_GPIO_CLOCK(RCC_GPIO_PERIPH,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //模拟输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIO_PORT,&GPIO_InitStructure);
}
static void ADC_Mpde_Config(void)
{
ADC_InitTypeDef ADC_InitStructure; //ADC初始化结构体
RCC_ADC_CLOCK(RCC_ADC_PERIPH,ENABLE); //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; //数据对齐 左对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //通道数 1通道
ADC_Init(ADC_x, &ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //ADC时钟分频 72/8=9M
//转换规则 ADC号 通道号 转换顺序 取样时间
ADC_RegularChannelConfig(ADC_x , ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
ADC_ITConfig( ADC_x, ADC_IT_EOC, ENABLE); //ADC中断使能
ADC_Cmd(ADC_x, ENABLE );
// ADC开始校准
ADC_StartCalibration(ADC_x);
// 等待校准完成
while(ADC_GetCalibrationStatus(ADC_x));
ADC_SoftwareStartConvCmd( ADC_x, ENABLE); //软件触发使能
}
static void NVIC_Configuration(void) //配置中断向量控制器
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //选择中断控制器组
NVIC_InitStructure.NVIC_IRQChannel =ADC_IRQn; //选择中断源
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; //使能中段
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //子优先级
NVIC_Init(&NVIC_InitStructure); //初始化结构体将值写入
}
void ADC_Init_Config(void)
{
NVIC_Configuration(); //中断配置
ADC_GPIO_Config(); //GPIO配置
ADC_Mpde_Config(); //模式配置
}
3、main.c
#include "stm32f10x.h" // 相当于51单片机中的 #include <reg51.h>
#include "bsp_led.h"
#include "usart.h"
#include "bsp_adc.h"
uint16_t ADC_Value;
float Value;
void delay(u32 i)
{
while(i--);
}
int main(void)
{
USART_config();
ADC_Init_Config();
printf("串口初始化成功\n");
while(1)
{
Value=(float)ADC_Value/4096*3.3;
printf("\n实时电压CH11= %f V\n",Value);
delay(0X8FFFFF); //延时一段时间打印
}
}