ADC.c
#include "stm32f10x.h"
#include "adc.h"
#define ADC1_DR_Address ((uint32_t)0x4001244C) //ADC_DR(ADC规则数据寄存器),偏移量=0x4c ADC1(0x40012400-0x400127ff)
uint16_t ADC_Buf[16];
void ADC_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
/* DMA1 channel1 configuration */
DMA_DeInit(DMA1_Channel1);//选择DMA的通道1
//设定从ADC外设的数据寄存器(ADC1_DR_Address)转移到内存(ADCConcertedValue)
//每次传输大小16位,使用DMA循环传输模式
/* 用以定义指定 DMA 通道的 DMA 缓存的大小,单位为数据单位 */
DMA_InitStructure.DMA_BufferSize = 16;
/* 规定了外设是作为数据传输的目的地还是来源 */
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设作为数据传输的来源
/* 使能 DMA 通道的内存到内存传输 */
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA 通道 x 没有设置为内存到内存传输
/* 该参数用以定义 DMA 内存基地址 */
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_Buf;//目标地址
/* 设定了外设数据宽度 */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据宽度为 16 位
/* 用来设定内存地址寄存器递增与否 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址增加,多组adc时,使能,数据传输时,内存增加
/* 设置了 DMA 的工作模式 */
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//工作在循环缓存模式
/* 该参数用以定义 DMA 外设基地址 */
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
/* 设定了外设数据宽度 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为 16 位
/* 用来设定外设地址寄存器递增与否 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
/* 设定 DMA 通道 x 的软件优先级 */
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA 通道 x 拥有高优先级
/* 初始化 DMA 的通道 x */
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
/* 使能或者失能指定的通道 */
DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA
/* ADC1 初始化*/
/* 指定是否在中执行转换连续模式或单一模式 */
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
/* 指定是否在中执行转换扫描(多通道)或单通道(单通道)模式 */
ADC_InitStructure.ADC_ScanConvMode = ENABLE;//多通道
/* 将ADC配置为在独立或双模 */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立
/* 规定了 ADC 数据向左边对齐还是向右边对齐 */
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
/* 定义了使用外部触发来启动规则通道的模数转换 */
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//无外部触发
/* 规定了顺序进行规则转换的 ADC 通道的数目。这个数目的取值范围是 1 到 16 */
ADC_InitStructure.ADC_NbrOfChannel = 16;
/* 根据 ADC_InitStruct 中指定的参数初始化外设 ADCx 的寄存器 */
ADC_Init(ADC1,&ADC_InitStructure);
/* 设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间 */
ADC_RegularChannelConfig(ADC1,ADC_Channel_0 ,1,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_1 ,2,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2 ,3,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_3 ,4,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_4 ,5,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5 ,6,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6 ,7,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7 ,8,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_8 ,9,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_9 ,10,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_10,11,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,12,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_12,13,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_13,14,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_14,15,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_15,16,ADC_SampleTime_239Cycles5);
/* 使能ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能ADC */
ADC_Cmd(ADC1, ENABLE);
/* 使能ADC1的复位校准寄存器 */
ADC_ResetCalibration(ADC1);
/* 等待校准完成 */
/* ADC_GetResetCalibrationStatus//获取 ADC 重置校准寄存器的状态 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* 使能ADC1的开始校准寄存器 */
ADC_StartCalibration(ADC1);
/* 等待完成 */
/* ADC_GetCalibrationStatus//获取指定 ADC 的校准状态 */
while(ADC_GetCalibrationStatus(ADC1));
/* 使用软件触发,由于没有采用外部触发 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/* 采样平均值 */
uint32_t Read_ADC_DMA_number(uint16_t buf,uint8_t count)
{
uint16_t MIN_AD = 0x0fff,MAX_AD = 0;
uint16_t num;
uint8_t t;
uint32_t number;
for(t=0;t<count;t++)
{
num = buf;
MIN_AD = ADC_MIN(MIN_AD,num);
MAX_AD = ADC_MAX(MAX_AD,num);
number+=num;
}
number = (number-MIN_AD-MAX_AD)/(count-2);
return number;
}
//最大最小值
void Read_ADC_DMA_number_MAX_MIN(uint16_t buf,uint32_t number_count)
{
uint16_t MinAD = 0x0fff,MaxAd = 0;
uint16_t num =0;
uint32_t t;
for(t = 0; t < number_count; t++)
{
num = system_t.adc.buf_t.buf[buf];
MaxAd = ADC_MAX(MaxAd,num);
MinAD = ADC_MIN(MinAD,num);
}
system_t.adc.numerical_value_max = MaxAd;//自定义全局变量,请自行添加
system_t.adc.numerical_value_min = MinAD;//自定义全局变量,请自行添加
}
ADC.h
#ifndef _ADC_H_
#define _ADC_H_
#include "stm32f10x.h"
void ADC_DMA_Init(void);
#define ADC_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ADC_MIN(x, y) ((x) < (y) ? (x) : (y))
uint32_t Read_ADC_DMA_number(uint16_t buf,uint8_t count);
uint32_t Read_ADC_DMA_number_MAX_MIN(uint16_t buf,uint32_t number_count);
#endif