1、ADC介绍

  • STM32F10x系列芯片的12位ADC
  1. 是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部
    信号源。
  2. 各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右
    对齐方式存储在16位数据寄存器中。
  3. 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。

2、ADC主要特征

  • 12位分辨率
  • 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
  • 单次和连续转换模式
  • 从通道0到通道n的自动扫描模式
  • 自校准
  • 带内嵌数据一致性的数据对齐
  • 采样间隔可以按通道分别编程
  • 规则转换和注入转换均有外部触发选项
  • 间断模式
  • 双重模式(带2个或以上ADC的器件)

3、ADC模块

在这里插入图片描述
注意:这里的ADCx_IN0ADCx_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);
}
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐