【STM32】模拟/数字转换(ADC)

一、ADC概念

12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。
ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。
在这里插入图片描述
在这里插入图片描述

二、ADC将内部温度传感器采集的模拟信号转换为数字信号,并通过DMA实现外设ADC到内存的数据传输。

bsp_adc.c

#include "bsp_adc.h"

uint16_t ADC_ConvertVal;  //内存变量,用来接收12位的ADC温度转换的电压数字量

/**
  * @brief  ADC1(通道16)、DMA1(通道1)初始化,ADC采集模式:单次、连续,规则通道
	*         外设ADC1不断发送数据到内存变量ADC_ConvertVal
  * @param  None
  * @retval None
  */
void ADC1_DMA_Configuration(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	
	DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR;  //ADC_DR(数据寄存器)外设地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertVal;  //内存变量地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //外设作为数据传输的来源
	DMA_InitStructure.DMA_BufferSize = 1;  //DMA 通道的 DMA 缓存的大小,单位为数据单位
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_PeripheralInc_Disable;  //内存地址寄存器不变
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为 16 位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  //数据宽度为 16 位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //数据循环发送
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;  //通道优先级为高
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  // 没有设置为内存到内存传输
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1, ENABLE);  //使能DMA1,通道1
	//===============================================================================================
	
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //ADC1 和 ADC2 工作在独立模式
	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 数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;  //转换的 ADC 通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);
	ADC_Cmd(ADC1, ENABLE);  //使能ADC1
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div8);  //ADC的输入时钟不得超过14MHz,72MHz/8 =9MHz
	ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_55Cycles5);  //设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间
	ADC_ResetCalibration(ADC1);  //重置指定的 ADC 的校准寄存器
	
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);  //获取 ADC 重置校准寄存器的状态
	ADC_StartCalibration(ADC1);  //开始指定 ADC 的校准状态
	while(ADC_GetCalibrationStatus(ADC1) == SET);  //获取指定 ADC 的校准程序
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);  //使能 ADC 的软件转换启动功能
	ADC_TempSensorVrefintCmd(ENABLE);  //使能温度传感器和内部参考电压通道
	ADC_DMACmd(ADC1, ENABLE);  //使能 ADC1 的 DMA 请求
}

bsp_adc.h

#ifndef __BSP_ADC_H__
#define __BSP_ADC_H__

#include <stm32f10x.h>

#define ADC_DR 0x4001244C

/*因为ADC_ConvertVal是12位的电压数字量,所以将V25、AVG_SLOPE模拟量转换成12位数字量*/
#define V25	 				0x6EF  // 1.43v/3.3v = V25/0xFFF
#define AVG_SLOPE 	0x5    // 4.3mv/3.3v = AVG_SLOPE/0xFFF

extern uint16_t ADC_ConvertVal;

void ADC1_DMA_Configuration(void);

#endif

main.c

#include "bsp_systick.h"
#include "bsp_uart.h"
#include "bsp_adc.h"

int main(void)
{
	float temperature;
	SysTick_Configuration();
	UART1_Configuration();
	
	/*外设ADC1不断发送数据到内存变量ADC_ConvertVal*/
	ADC1_DMA_Configuration();
	
	while(1)
	{
		/*
		 *  温度(°C) = {(V25 - VSENSE) / Avg_Slope} + 25
		 *  V25 = VSENSE在25°C时的数值
		 *  Avg_Slope = 温度与VSENSE曲线的平均斜率(单位为mV/ °C 或 μV/ °C)
		 *
		 *  因为ADC_ConvertVal是12位的电压数字量,所以将V25、AVG_SLOPE模拟量转换成12位数字量计算
		 */
		temperature = (V25 - ADC_ConvertVal) / AVG_SLOPE + 25;
		printf("temperature = %.1f\n",temperature);
		Delay_us(1000000);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值