五、STM32入门学习 之 ADC
STM32F10x系列芯片的12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
·
1、ADC介绍
- STM32F10x系列芯片的12位ADC
- 是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部
信号源。 - 各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右
对齐方式存储在16位数据寄存器中。 - 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
2、ADC主要特征
- 12位分辨率
- 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
- 单次和连续转换模式
- 从通道0到通道n的自动扫描模式
- 自校准
- 带内嵌数据一致性的数据对齐
- 采样间隔可以按通道分别编程
- 规则转换和注入转换均有外部触发选项
- 间断模式
- 双重模式(带2个或以上ADC的器件)
3、ADC模块

注意:这里的ADCx_IN0到ADCx_IN15不一定和GPIO引脚顺序对应。
4、代码
#include "stm32f10x.h" // Device header
#include <stdio.h>
/*功能:通过按下按钮来触发ADC对可变电阻的电阻值采集转换,并显示到串口调试工具上。
要求:利用(ADC模块+USART模块+EXTI模块)
通过触发外部中断信号来实现信号采集时刻
可变电阻的模拟量采集转换 ——> 数字量 ——> 串口调试工具显示 (USART实现)
*/
void USART1_Configuration(void);
void UART_SendChar(uint8_t ch);
void ADC_Configuration(void);
void GPIO_EXTI_Configuration(void);
#define BufferSize 2
uint8_t ADCINMEM[BufferSize]={};
int main(void)
{
USART1_Configuration();
printf("USART1_Configuration finished!\n");
GPIO_EXTI_Configuration();
printf("GPIO_EXTI_Configuration finished!\n");
ADC_Configuration();
printf("ADC_Configuration finished!\n");
while (1);
}
void GPIO_EXTI_Configuration(void){
//使用外部
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOF,&GPIO_InitStruct);
GPIO_SetBits(GPIOF,GPIO_Pin_8);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOF,GPIO_PinSource8);
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line8;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd= ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct);
}
void EXTI9_5_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line8)==SET){
// 开启采集ADC
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
printf("BTN EXTI succuced\n");
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
int fputc(int ch, FILE* file){
UART_SendChar(ch);
return ch;
}
void ADC_Configuration(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStruct);
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //这里的外部触发只得是内部的定时器的触发信号,而不是EXTI_LINEx的中断源触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, DISABLE);
//校准设置
ADC_ResetCalibration(ADC1);
uint32_t cout= 20000;
while (ADC_GetResetCalibrationStatus(ADC1) != SET){
cout--;
if(cout ==0)
break;
};
cout= 20000;
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) != SET){
cout--;
if(cout==0)
break;
};
// 配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
ADC_Cmd(ADC1,ENABLE);
//ADC_DMACmd(ADC1,ENABLE);
}
void ADC1_2_IRQHandler(void){
if(ADC_GetITStatus(ADC1,ADC_IT_EOC)==SET){
printf("ADC Convert finished!\n");
float a=(ADC1->DR * 3.3 / 4095);
printf("a=%f\n",a);
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}
}
void USART1_Configuration(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStruct);
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
}
void UART_SendChar(uint8_t ch) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, ch);
}
更多推荐



所有评论(0)