STM32利用DMA实现多通道ADC转换程序实例

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

网上很多类似资料,总结就是要么给出不完整的一部分,要么就是没有标注说明之类的,鞋面我给大家贴出实用型的,包括如何配置DMA和ADC,如何采集数据,如何处理数据//系统时钟使用72MHZunsignedshortAD_Value[5]={0};//定义成半字节数组voidRCC_Config(void){ErrorStatusHSEStartUpStatus;//定义枚举型变量RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);HSEStartUpStatus=RCC_WaitForHSEStartUp();if(HSEStartUpStatus==SUCCESS){RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);FLASH_SetLatency(FLASH_Latency_2);FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource()!=0x08);}//---打开设备时钟---//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOF,ENABLE);//RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//开串口1和ADC1的时钟}voidADC_Start(void){DMA_Cmd(DMA1_Channel1,ENABLE);//启动DMA通道ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件启动转换}voidDMA_ADC_Config(void){ADC_InitTypeDefADC_InitStructure;DMA_InitTypeDefDMA_InitStructure;GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=(GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//设置成模拟输入GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=(GPIO_Pin_0);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//设置成模拟输入GPIO_Init(GPIOB,&GPIO_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开ADC1的时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//开DMA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟,为PCLK2的8分频,即9MHzDMA_DeInit(DMA1_Channel1);//ADC挂接在DMA的通道1上DMA_InitStructure.DMA_PeripheralBaseAddr=ADC_DR_ADDRESS;//DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&AD_Value;DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//内存作为数据传输的目的地DMA_InitStructure.DMA_BufferSize=5;//DMA通道的DMA缓存的大小系统用5个通道DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址寄存器不变即地址ADC1-DR不变DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//内存地址寄存器递增即数组AD_Value地址增加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通道x拥有高优先级DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//DMA通道x设置为非内存到内存传输DMA_Init(DMA1_Channel1,&DMA_InitStructure);//DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);ADC_DeInit(ADC1);ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在独立模式ADC_InitStructure.ADC_ScanConvMode=ENABLE;//模数转换工作在扫描模式ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//连续转换//ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//注意不要使用持续转换模式,否则只要触发一次后续的转换就会永不停歇(除非CONT清0),这样第一次以后的ADC,就不是由TIM1_CC1来触发了ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel=5;//顺序进行规则转换的ADC通道的数目ADC_Init(ADC1,&ADC_InitStructure);//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_5,2,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_6,3,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_7,4,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_8,5,ADC_SampleTime_239Cycles5);ADC_ExternalTrigInjectedConvCmd(ADC1,DISABLE);ADC_DMACmd(ADC1,ENABLE);//开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)ADC_Cmd(ADC1,ENABLE);//使能指定的ADC1ADC_ResetCalibration(ADC1);//复位校准寄存器while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC1复位校准寄存器的状态,设置状态则等待ADC_StartCalibration(ADC1);//开始指定ADC1的校准状态while(ADC_GetCalibrationStatus(ADC1));//获取指定ADC1的校准程序,设置状态则等待ADC_Start();}//数据采集处理voidADC_DateProcess(void){unsignedchari,k,h;unsignedintBuf=0;//递推先进先出原理ADCCollect.PVVoltageBuf[9]=get_ChannelVale(ADC_Channel_4)&0xfff;ADCCollect.BatteryVoltageBuf[9]=get_ChannelVale(ADC_Channel_5)&0xfff;ADCCollect.CirTem1Buf[9]=get_ChannelVale(ADC_Channel_6)&0xfff;ADCCollect.BatteryChargeCurrentBuf[9]=get_ChannelVale(ADC_Channel_7)&0xfff;ADCCollect.BatteryDisChargeCurrentBuf[9]=get_ChannelVale(ADC_Channel_8)&0xfff;for(i=0;i9;i++){ADCCollect.PVVoltageBuf[i]=ADCCollect.PVVoltageBuf[1+i];ADCCollect.BatteryVoltageBuf[i]=ADCCollect.BatteryVoltageBuf[1+i];ADCCollect.CirTem1Buf[i]=ADCCollect.CirTem1Buf[1+i];ADCCollect.BatteryChargeCurrentBuf[i]=ADCCollect.BatteryChargeCurrentBuf[1+i];ADCCollect.BatteryDisChargeCurrentBuf[i]=ADCCollect.BatteryDisChargeCurrentBuf[1+i];}//排序for(k=0;k9;k++)//{for(h=0;h9-k;h++)//{Buf=0;if(ADCCollect.PVVoltageBuf[h]ADCCollect.PVVoltageBuf[h+1]){Buf=ADCCollect.PVVoltageBuf[h+1];ADCCollect.PVVoltageBuf[h+1]=ADCCollect.PVVoltageBuf[h];ADCCollect.PVVoltageBuf[h]=Buf;}Buf=0;if(ADCCollect.BatteryVoltageBuf[h]ADCCollect.BatteryVoltageBuf[h+1]){Buf=ADCCollect.BatteryVoltageBuf[h+1];ADCCollect.BatteryVoltageBuf[h+1]

1 / 5
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功