STM32ADC单通道与多通道-DMA学习笔记_第1页
STM32ADC单通道与多通道-DMA学习笔记_第2页
STM32ADC单通道与多通道-DMA学习笔记_第3页
STM32ADC单通道与多通道-DMA学习笔记_第4页
STM32ADC单通道与多通道-DMA学习笔记_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、卜面我们将PCO配置成AD1的通道10为例进行讲解。3.1首先我们应将PC0设置成模拟输入:includeadc.h/*为何定义ADCl_DR_Address为(u32)0 x40012400+0 x4c),因为存放AD转换结果的寄存器的地址就是0 x4001244c*/#defineADCl_DR_Address(u32)0 x40012400+0 x4c)厂定义变乗ADC_ConvertedValue,放AD1通道10转换的数据*/10uintl6_tADC_ConvertedValue;staticvoidADCl_GPIO_Config(void)GPIO_lnitTypeDefGPI

2、OJnitStructure;/*EnableADC1andGPIOCclock*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADCl|RCC_APB2Periph_GPI0C,ENABLE);GPIOnitStructure.GPIO_Pin=GPIO_Pin_0GPIOnitStructureGPIO_Mode=GPIO_Mode_AIN;GPIOnit(GPIOC,&GPIOnitStructure);3.2设置完端II后下一步当然是对AD进行初始化:这里需耍补充一个知识点DMA,DMA就相当与CPU的一个秘书,他的作用就是帮CPU减轻负担的。说的再具体

3、点就是帮CPU來转移数据的。我们都知道,AD每次转换结束后会将转换的结果放到一个固定的寄存器里,以往我们如果想将该寄存器中的值赋给某一变最时会用到赋值语句,如果不用DMA,则赋值语句便要CPU來完成,CPU本來就要忙着处理其他事情,现在还要來解决赋值语句这么简单的问题,肯到会蛋疼。所以需要DMA这个秘书來帮他解决这个问题。由T-DMA只是个秘书,所以比较笨,你只有把任务交代清楚了她才能很好的完成任务。那么怎样來给DMA吩咐任务呢,聪明的人肯定想到了,那当然是“DMAnit(DMAl_Channell,&DMA_lnitStructure)”这个函数啦。下而就来一步步的來给DMA交代任务。/*函

4、数名:ADCl_Mode_Config*描述:配置ADC1的工作模式为MDA模式*输入:无*输出:无*调用:内部调用*/staticvoidADCl_Mode_Config(void)DMAJnitTypeDefDMAJnitStructure;ADC_lnitTypeDefADCJnitStructure;/*将与DMA有关的寄存器设我初始值*/DMA_Delnit(DMAl_Channell);/*定义DMA外设基地址,这里的ADCl_DR_Address是用户自己定义的,即为存放转换结果的寄存器,他的作用就是告诉DMA取数就到ADCl_DR_Address这里来取。*/DMA_lnitS

5、tructure.DMA_PeripheralBaseAddr=ADCl_DR_Address;/*定义内存基地址,即告诉DMA要将从AD中取來的数放到ADC_ConvertedValue中*/DMA_lnitStructure.DMA_MemoryBaseAddr=(u32)&ADC_ConvertedValue;/*定义AD外设作为数据传输的來源,即告诉DMA是将AD中的数据取出放到内存中,不能反过來*/DMA_lnitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;/*指定DMA通道的DMA缓存的人小,即告诉DMA开辟几个内存空间,由我们只取通道10的AD

6、数据所以只需开辟一个内存空间*7DMA_lnitStructure.DMA_BufferSize=1;/*设定寄存器地址固定,即告诉DMA,只从固定的一个地方取数*/DMA_lnitStructure.DMA_Peripherallnc=DMA_Peripherallnc_Disable;/*设定内存地址固定,即每次DMA,只将数搬到固定的内存中*/DMAnitStructure.DMA_Memorylnc=DMA_Memorylnc_Enable;厂设定外设数据宽度,即告诉DMA要取的数的大小拿/DMA_lnitStructure.DMA_PeripheralDataSize=DMA_Per

7、ipheralDataSize_HalfWord;厂设定内存的的宽度沐/DMA_lnitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;/*设定DMA工作再循坏缓存模式,即告诉DMA要不停的搬运,不能偷懒*7DMA_lnitStructure.DMA_Mode=DMA_Mode_Circular;/*设定DMA选定的通道软件优先级*/DMA_lnitStructure.DMA_Priority=DMA_Priority_High;DMAJnitStructure.DMA_M2M=DMA_M2M_Disable;DMA_lnit(

8、DMAl_Channell,&DMAJnitStructure);/*EnableDMAchannell,CPU有好几个DMA秘书,现在只用DMAl.Channell这个秘书*/DMACmdfDMAlChannell,ENABLE);厂设置ADC工作在独立模式*/ADC_lnitStructure.ADC_Mode=ADC_Mode_lndependent;/*规定AD转换工作在单次模式,即对一个通道采样*/ADC_lnitStructure.ADC_ScanConvMode=DISABLE/*设定AD转化在连续模式/ADC_lnitStructure.ADC_ContinuousConvMo

9、de=ENABLE;/*不使用外部促发转换*/ADC_lnitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;/*采集的数据在寄存器中以右对齐的方式存放ADC_lnitStructure.ADC_DataAlign=ADC_DataAlign_Right;/*设定要转换的AD通道数目*/ADC_lnitStructure.ADC_NbrOfChannel=1;ADC_Init(ADC:L&ADC_lnitStructure);/*配置ADC时钟,为PCLK2的8分频,即9MHz/RCC_ADCCLKConfig(RCC_PCLK

10、2_Div8);/*配置ADC1的通道11为55.5个采样周期*/ADC_RegularChannelConfig(ADCl,ADC_Channel_10,1,ADC_SampleTime_55Cycles5);/*EnableADC1DMA/ADC_DMACmd(ADClzENABLE);/*EnableADC1*/ADC_Cmd(ADCl,ENABLE);/*复位校准寄存器-7ADC_ResetCalibration(ADCl);/*等待校准寄存器复位完成Twhile(ADC_GetResetCalibrationStatus(ADCl);/*ADC校准*/ADC_StartCalibra

11、tion(ADCl);/*等待校准完成*/while(ADC_GetCalibrationStatus(ADCl);/*由于没有采用外部触发,所以使用软件触发ADC转换-7ADC_SoftwareStartConvCmd(ADCl,ENABLE);配置完以上的程序,那么AD每转换一次,DMA都会将转换结果搬到变量ADCConvertedValue中,而不需用每次都用赋值语句來取值AD转换的值。第二部分:AD多路采样#includeadc.h#defineADCl_DR_Address(u32)0 x40012400+0 x4c)/*定义数组变竜ADC_ConvertedValue2,分别放AD

12、I通道10和11转换的数据*/_10uintl6_tADC_ConvertedValue2;/*函数名:ADCl_GPIO_Config*描述:使能ADC1和DMA1的时钟,设置PCO,PC1为模拟输入*输入:无*输出:无-调用:内部调用*/staticvoidADCl_GPIO_Config(void)GPIOnitTypeDefGPIOnitStructure;/*EnableDMAclock*/RCC-AHBPeriphClockCmd(RCC_AHBPeriph_DMAl/ENABLE);/*EnableADC1andGPIOCclock/RCC_APB2PeriphClockCmd(

13、RCC_APB2Periph_ADCl|RCC_APB2Periph_GPI0C,ENABLE);GPIOnitStructureGPIO_Pin二GPIO_Pin_0|GPIO_Pin_l;GPIOnitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIOnit(GPIOC,&GPIOnitStructure);/*函数名:ADCl.Mode.Config*描述:配置ADC1的工作模式为MDA模式*输入:无审输出:无审调用:内部调用*/staticvoidADCl_Mode_Config(void)DMAJnitTypeDefDMAJnitStructure;ADCJ

14、nitTypeDefADCJnitStructure;/*DMAchannellconfiguration*/DMA.DelnitfDMAl.Channell);/*定义DMA外设基地址,即为存放转换结果的寄存器*/DMAJnitStructure.DMA_PeripheralBaseAddr=ADCl_DR_Address;严定义内存基地址*/DMAJnitStructure.DMA_MemoryBaseAddr=(u32)&ADC_ConvertedValue;严定义AD外设作为数据传输的来源*/DMAJnitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;

15、严指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个*/DMAInitStructure.DMABufferSize=2:/*设定寄存器地址固定*/DMAJnitStructure.DMAPeripherallnc=DMAPeripherallncDisable;/*设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到两个内存空间中*/DMAJnitStructure.DMA_Memorylnc=DMA_Memorylnc_Enable;厂设定外设数据宽度*/DMAJnitStructure.DMA_PeripheralDataSize=DMAP

16、eripheralDataSizeHalfWord;/*设定内存的的宽度*/DMAJnitStructure.DMA_MemoryDataSize=DMAMemoryDataSizeHalfWord;/*设定DMA工作再循环缓存模式*/DMAInitStructure.DMAMode=DMAModeCircular:/*设定DMA选定的通道软件优先级*/DMAJnitStructure.DMA_Priority=DMAPriorityHigh;DMAInitStructure.DMAM2M=DMAM2MDisable;DMAJnitfDMAlChannell,&DMAJnitStructure

17、);/*EnableDMAchannell*/DMA-Cmd(DMAl_Channell,ENABLE);/*设置ADC工作在独立模式*/ADCJnitStructure.ADC_Mode=ADC_ModeJndependent;/*规定AD转换工作在扫描模式,即对多个通道采样*/ADCInitStructure.ADCScanConvMode=ENABLE;厂设定AD转化在连续模式*/ADCInitStructure.ADCContinuousConvMode=ENABLE;/*不使用外部促发转换*/ADCJnitStructure.ADC_ExternalTrigConv=ADC_Exte

18、rnalTrigConv_None;/*采集的数据在寄存器中以右对齐的方式存放*/ADCJnitStructure.ADC_DataAlign=ADC.DataAlign.Right;/*设定要转换的AD通道数目*/ADCInitStructure.ADCNbrOfChannel=2;ADC_InitfADCl,&ADCJnitStructure);/*配置ADC时钟,为PCLK2的8分频,即9MHz*/RCC_ADCCLKConfig(RCC_PCLK2_Div8);/*配置ADC1的通道10和11的转换先后顺序以及采样时间为为55.5个采样周期*/ADC_RegularChannelCon

19、fig(ADCl/ADC_Channel_10,l,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADCl,ADC_Channel_lb2,ADC_SampleTime_55Cycles5);/*EnableADC1DMA*/ADC_DMACmd(ADCl,ENABLE);/*EnableADCl*/ADC_Cmd(AD(XENABLE);/*复位校准寄存器TADC_ResetCalibration(ADCl);厂等待校准寄存器复位完成*/while(ADC_GetResetCalibrationStatus(ADCl);厂ADC校准*/

20、ADC_StartCalibration(ADCl);/*等待校准完成*/while(ADC_GetCalibrationStatus(ADCl);/*由丁没有采用外部触发,所以使用软件触发ADC转换*/ADC_SoftwareStartConvCmd(ADC1,ENABLE);!单通道采样与多通道采样的不同点都在第二段程序中用红色标出来了,注意比较。总结:DMA就是一个无私奉献的搬运工,想将外设寄存器中的值放入内存中原本需要CPU来完成,现在DMA来帮CPU完成,这在一定程度上解放了CPUSTM32ADC多通道转换描述:用ADC连续采集11路模拟信号,并由DMA传输到内存。ADC配置为扫描并

21、且连续转换模式,ADC的时钟配置为12MHZo在每次转换结束后,由DMA循环将转换的数据传输到内存中。ADC可以连续采集N次求平均值。最后通过串口传输出最后转换的结果。程序如下:include,stm32flOx.hn这个头文件包括STM32F10X所有外闱寄存器、位、内存映射的定义includeeval.h”头文件(包括串II、按键、LED的函数声明)includeSysTickDelay.hincludeUARTJNTERFACE.h#include#defineN50每通道采50次#defineM12为12个通道vul6AD_ValueNM;用来存放ADC转换他果,也是DMA的目标地址v

22、ul6After_filterM;用来存放求平均值之后的结果inti;/PPIO管脚的配置选用ADC的通道01289101112131415,分别对应的管脚为PAOPA1PA2PBOPB1PCOPCIPC2PC3PC4PC5串II使用USART1其中TX为PA9,RX为PA10*/voidGPIO_Configuration(void)GPIOnitTypeDefGPIOnitStructure;/*ConfigureUSART1Tx(PA.09)asalternatefunctionpush-pull*/GPIOnitStructure.GPIO_Pin=GPIO_Pin_9;GPIOJni

23、tStructure.GPIO_Mode=GPIO_Mode_AF_PP;因为USART1管脚是以复用的形式接到GPIO口上的,所以使用复用推挽式输出GPIOnitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_lnit(GPIOA,&GPIOnitStructure);/*ConfigureUSART1Rx(PA.10)asinputfloating*/GPIOnitStructure.GPIO_Pin=GPIO_Pin_10;GPIOnitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_lnit(GPIOA

24、,&GPIOnitStructure);/PA0/1/2作为模拟通道输入引脚GPIOnitStructureGPIO_Pin=GPIO_Pin_0|GPIO_Pin_l|GPIO_Pin_2|GPIO_Pin_3;GPIOJnitStructure.GPIO_Mode=GPIO_Mode_AIN;模拟输入引脚GPIOnit(GPIOA,&GPIOnitStructure);/PBO/l作为模拟通道输入引脚GPIOnitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_l;GPIOJnitStructure.GPIO_Mode=GPIO_Mode_AIN;模拟输入引脚

25、GPIOnit(GPIOB,&GPIOnitStructure);/PCO/l/2/3/4/5作为模拟通道输入引脚GPIOnitStructure.GPIO_PinGPIO_Pin_0|GPIO_Pin_l|GPIO_Pin_21GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIOJnitStructure.GPIO_Mode=GPIO_Mode_AIN;模拟输入引脚GPIOnit(GPIOC,&GPIOJnitStructure);厂配置系统时钟,使能各外设时钟p/voidRCC_Configuration(void)ErrorStatusHSEStartUpStatu

26、s;RCC_Delnit();/RCC系统复位RCC_HSEConfig(RCC_HSE_ON);开启HSEHSEStartUpStatus=RCCWaitForHSEStartUpO;等待HSE准备好if(HSEStartUpStatus=SUCCESS)FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/EnablePrefetchBufferFLASH_SetLatency(FLASH_Latency_2);/Set2LatencycyclesRCC_HCLKConfig(RCC_SYSCLK_Divl);/AHBclock=SYS

27、CLKRCC_PCLK2Config(RCC_HCLK_Divl);/APB2clock=HCLKRCC_PCLKlConfig(RCC_HCLK_Div2);/APB1clock=HCLK/2RCC_PLLConfig(RCC_PLLSource_HSE_Divl,RCC_PLLMul_6);/PLLCLK=12MHz*6=72MHzRCC_PLLCmd(ENABLE);/EnablePLLwhile(RCCGetFlagStatus(RCC_FLAG_PLLRDY)=RESET);/WaittillPLLisreadyRCC_SYSCLKConfig(RCC_SYSCLKSource_PL

28、LCLK);/SelectPLLassystemclocksourcewhile(RCC_GetSYSCLKSource()!=0 x08);/WaittillPLLisusedassystemclocksource厂使能各个外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPI0C|RCC_APB2Periph_ADCl|RCC_APB2Periph_AFI0|RCC_APB2Periph_USARTl,ENABLE);使能ADC1通道时钟,各个管脚时钟/*Configur

29、eADCCLKsuchasADCCLK=PCLK2/6*/RCC_ADCCLKConfig(RCC_PCLK2_Div6);/72M/6=12,ADC最大时间不能超过14MRCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAbENABLE);使能DMA传输厂配置ADC1*/voidADCl_Configuration(void)ADCJnitTypeDefADC_lnitStructure;ADC_Delnit(ADCl);将外设ADC1的全部寄存器重设为缺省值/*ADC1configuration*/ADC_lnitStructure.ADC_Mode=ADC_Mo

30、de_lndependent;/ADC丁作模式:ADC1和ADC2工作在独立模式ADC_lnitStructure.ADC_ScanConvMode=ENABLE;模数转换匸作扌1推模式ADC_lnitStructure.ADC_ContinuousConvMode=ENABLE;/模数转换L作在连续转换模式ADCJnitStructure.ADCExternalTrigConv=ADC_ExtemalTrigConv_None;/夕卜部触发转换关闭ADCJnitStructure.ADC_DataAlign=ADC_DataAlign_Right;/ADC数据右对齐ADC_lnitStruc

31、ture.ADC_NbrOfChannel=M;/I/bf进彳规则转换的ADC通道的数11ADCJnit(ADClz&ADC_InitStructure);根据ADCnitStruct中指定的参数初始化外设ADCx的寄存器/*ADC1regularchannelllconfiguration*/设置指定ADC的规则组通道,设置它们的转化顺序和采样时间/ADC1,ADC通道x,规则采样顺序值为y,釆样时间为239.5周期ADC_RegularChannelConfig(ADCl,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);ADC_RegularChann

32、elConfig(ADCl,ADC_Channel_l,2,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl,ADC_Channel_2,3,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl,ADC_Channel_3,4,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl,ADC_Channel_&5,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(

33、ADCl,ADC_Channel_9,6,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl,ADC_Channel_10,7,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl,ADC_Channel_ll,&ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl/ADC_Channel_12,9,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl/A

34、DC_Channel_13,10,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl/ADC_Channel_14,11,ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADCl/ADC_Channel_15,12,ADC_SampleTime_239Cycles5);/开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)ADCDMACmd(ADCl/ENABLE);/*EnableADC1*/ADC_Cmd(ADCl,ENABLE);使能扌旨定的ADC1/

35、*EnableADC1resetcalibarationregister*/ADC_ResetCalibration(ADCl);复位指尢的ADC1的校准寄存器/*ChecktheendofADC1resetcalibrationregister*/while(ADC_GetResetCalibrationStatus(ADCl);获取ADC1复位校准寄存器的状态,设置状态则等待/*StartADC1calibaration*/ADCStartCalibration(ADCl);开始指定ADC1的校准状态/*ChecktheendofADC1calibration*/while(ADC_Get

36、CalibrationStatus(ADCl);获取指定ADC1的校准;程序,设置状态则等待厂配置DMA*/voidDMA_Configuration(void)/*ADC1DMA1ChannelConfig*/DMAJnitTypeDefDMA_lnitStructure;DMA_Delnit(DMAl_Channell);将DMA的通道1寄存器重设为缺省值DMA_lnitStructure.DMA_PeripheralBaseAddr=(u32)&ADCl-DR;/DMA外设ADC也地址DMA_lnitStructure.DMA_MemoryBaseAddr=(u32)&AD_Value;

37、/DMA内存基地址DMA_lnitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;/内存作为数据传输的II的地DMA_lnitStructure.DMA_BufferSize=N*M;/DMA通道的DMA缓存的人小DMA_lnitStructure.DMA_Peripherallnc=DMA_Peripherallnc_Disable;外设地址寄存器不变DMA_lnitStructure.DMA_Memorylnc=DMA_Memorylnc_Enable;内存地址寄存器递增DMA_lnitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;数据宽度为16位DMAJnitStructure.DMA_MemoryDataSize

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论