一、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);
}
}