一、編程要點
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); //延時一段時間打印
}
}