STM32f103程序模块8------ADC&DMA

#define ADC1_DR_Address ((u32)0x4001244C)
__IO u16 ADC_ConvertedValue[1];

//
u16 addata1[64],adindex1=0,advalue=0;//64个空间循环存储ad值
u32 adsum1=0; //计算环节用,用来统计采样值和
u16 sensecutf,sensecutcnt; //传感器断开或偏离标志位,传感器断开或偏离计数器
u16 ad1,x1,ad2,x2;
float BatteryCapacity=0;//电池电量
u8 adctimeflag;
u8 mark_BatteryIndicator=0;//电池电量显示标志
u16 BatteryIndicator_Count=0;//电池电量显示计数器
void ADC1_Init(void)/*初始化ADC1 */
{
ADC1_GPIO_Config();
ADC1_Mode_Config();
adctimeflag=1;
BatteryIndicator_Count=0;
mark_BatteryIndicator=0;
}

void ADC1_GPIO_Config(void)//模拟量采集端口配置
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PC.0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //GPIO设置为模拟输入
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

 

void ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA1时钟
/* DMA channel1 configuration */
DMA_DeInit(DMA1_Channel1); //指定DMA通道
// DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//设置DMA外设地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&(ADC1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //设置DMA内存地址,ADC转换结果直接放入该地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设设置为数据传输的来源
DMA_InitStructure.DMA_BufferSize = 1; //DMA缓冲区设置为1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
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);

/* Enable DMA channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA通道

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟

/* ADC1 configuration */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //使用独立模式,扫描模式
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_InitStructure.ADC_NbrOfChannel = 1; // 只有1个转换通道
ADC_Init(ADC1, &ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟,为PCLK2的8分频,即9Hz
/* ADC1 regular channel11 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5); //通道1采样周期239个时钟周期

/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE); //使能ADC的DMA

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE); //使能ADC1

/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));

/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));

/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //开始转换
}

void adcpro(void)
{
addata1[adindex1]=ADC_ConvertedValue[0];
adindex1++;
if(adindex1>64) //这里是对64个数据进行从小到大的排序
{
u16 ip,j,k;
for(ip=0;ip<63;ip++)
{
for(j=ip+1;j<64;j++)
{
if(addata1[ip]>addata1[j])
{
k=addata1[ip];
addata1[ip]=addata1[j];
addata1[j]=k;
}
}
}
adsum1=0;
for(ip=32;ip<64;ip++)//从中间截取32个数据来处理
adsum1+=addata1[ip];
advalue=adsum1/32; //取平均值
adindex1=0;adsum1=0;
BatteryCapacity=(float)(advalue*(3.3/4096)*11); //计算出实际电压值*ADC_ConvertedValueLocal*
……
}
}
}

posted on 2020-08-26 08:33  寒星日光  阅读(679)  评论(0编辑  收藏  举报

导航