您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > STM32-ADC单通道与多通道_DMA学习笔记
下面我们将PC0配置成AD1的通道10为例进行讲解。3.1首先我们应将PC0设置成模拟输入:#includeadc.h/*为何定义ADC1_DR_Address为((u32)0x40012400+0x4c),因为存放AD转换结果的寄存器的地址就是0x4001244c*/#defineADC1_DR_Address((u32)0x40012400+0x4c)/*定义变量ADC_ConvertedValue,放AD1通道10转换的数据*/__IOuint16_tADC_ConvertedValue;staticvoidADC1_GPIO_Config(void){GPIO_InitTypeDefGPIO_InitStructure;/*EnableADC1andGPIOCclock*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_Init(GPIOC,&GPIO_InitStructure);}3.2设置完端口后下一步当然是对AD进行初始化:这里需要补充一个知识点DMA,DMA就相当与CPU的一个秘书,他的作用就是帮CPU减轻负担的。说的再具体点就是帮CPU来转移数据的。我们都知道,AD每次转换结束后会将转换的结果放到一个固定的寄存器里,以往我们如果想将该寄存器中的值赋给某一变量时会用到赋值语句,如果不用DMA,则赋值语句便要CPU来完成,CPU本来就要忙着处理其他事情,现在还要来解决赋值语句这么简单的问题,肯到会蛋疼。所以需要DMA这个秘书来帮他解决这个问题。由于DMA只是个秘书,所以比较笨,你只有把任务交代清楚了她才能很好的完成任务。那么怎样来给DMA吩咐任务呢,聪明的人肯定想到了,那当然是“DMA_Init(DMA1_Channel1,&DMA_InitStructure)”这个函数啦。下面就来一步步的来给DMA交代任务。/*函数名:ADC1_Mode_Config*描述:配置ADC1的工作模式为MDA模式*输入:无*输出:无*调用:内部调用*/staticvoidADC1_Mode_Config(void){DMA_InitTypeDefDMA_InitStructure;ADC_InitTypeDefADC_InitStructure;/*将与DMA有关的寄存器设我初始值*/DMA_DeInit(DMA1_Channel1);/*定义DMA外设基地址,这里的ADC1_DR_Address是用户自己定义的,即为存放转换结果的寄存器,他的作用就是告诉DMA取数就到ADC1_DR_Address这里来取。*/DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;/*定义内存基地址,即告诉DMA要将从AD中取来的数放到ADC_ConvertedValue中*/DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&ADC_ConvertedValue;/*定义AD外设作为数据传输的来源,即告诉DMA是将AD中的数据取出放到内存中,不能反过来*/DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;/*指定DMA通道的DMA缓存的大小,即告诉DMA开辟几个内存空间,由于我们只取通道10的AD数据所以只需开辟一个内存空间*/DMA_InitStructure.DMA_BufferSize=1;/*设定寄存器地址固定,即告诉DMA,只从固定的一个地方取数*/DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;/*设定内存地址固定,即每次DMA,,只将数搬到固定的内存中*/DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;/*设定外设数据宽度,即告诉DMA要取的数的大小*/DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;/*设定内存的的宽度*/DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;/*设定DMA工作再循环缓存模式,即告诉DMA要不停的搬运,不能偷懒*/DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;/*设定DMA选定的通道软件优先级*/DMA_InitStructure.DMA_Priority=DMA_Priority_High;DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;DMA_Init(DMA1_Channel1,&DMA_InitStructure);/*EnableDMAchannel1,CPU有好几个DMA秘书,现在只用DMA1_Channel1这个秘书*/DMA_Cmd(DMA1_Channel1,ENABLE);/*设置ADC工作在独立模式*/ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;/*规定AD转换工作在单次模式,即对一个通道采样*/ADC_InitStructure.ADC_ScanConvMode=DISABLE/*设定AD转化在连续模式*/ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;/*不使用外部促发转换*/ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;/*采集的数据在寄存器中以右对齐的方式存放*/ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;/*设定要转换的AD通道数目*/ADC_InitStructure.ADC_NbrOfChannel=1;ADC_Init(ADC1,&ADC_InitStructure);/*配置ADC时钟,为PCLK2的8分频,即9MHz*/RCC_ADCCLKConfig(RCC_PCLK2_Div8);/*配置ADC1的通道11为55.5个采样周期*/ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_55Cycles5);/*EnableADC1DMA*/ADC_DMACmd(ADC1,ENABLE);/*EnableADC1*/ADC_Cmd(ADC1,ENABLE);/*复位校准寄存器*/ADC_ResetCalibration(ADC1);/*等待校准寄存器复位完成*/while(ADC_GetResetCalibrationStatus(ADC1));/*ADC校准*/ADC_StartCalibration(ADC1);/*等待校准完成*/while(ADC_GetCalibrationStatus(ADC1));/*由于没有采用外部触发,所以使用软件触发ADC转换*/ADC_SoftwareStartConvCmd(ADC1,ENABLE);}配置完以上的程序,那么AD每转换一次,DMA都会将转换结果搬到变量ADC_ConvertedValue中,而不需用每次都用赋值语句来取值AD转换的值。第二部分:AD多路采样#includeadc.h#defineADC1_DR_Address((u32)0x40012400+0x4c)/*定义数组变量ADC_ConvertedValue[2],分别放AD1通道10和11转换的数据*/__IOuint16_tADC_ConvertedValue[2];/**函数名:ADC1_GPIO_Config*描述:使能ADC1和DMA1的时钟,设置PC0,PC1为模拟输入*输入:无*输出:无*调用:内部调用*/staticvoidADC1_GPIO_Config(void){GPIO_InitTypeDefGPIO_InitStructure;/*EnableDMAclock*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);/*EnableADC1andGPIOCclock*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_Init(GPIOC,&GPIO_InitStructure);}/*函数名:ADC1_Mode_Config*描述:配置ADC1的工作模式为MDA模式*输入:无*输出:无*调用:内部调用*/staticvoidADC1_Mode_Config(void){DMA_InitTypeDefDMA_InitStructure;ADC_InitTypeDefADC_InitStructure;/*DMAchannel1configuration*/DMA_DeInit(DMA1_Channel1);/*定义DMA外设基地址,即为存放转换结果的寄存器*/DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;/*定义内存基地址*/DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&ADC_ConvertedValue;/*定义AD外设作为数据传输的来源*/DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;/*指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个*/DMA_InitStructure.DMA_BufferSize=2;/*设定寄存器地址固定*/DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;/*设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到两个内存空间中*/DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;/*设定外设数据宽度*/DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;/*设定内存的的宽度*/DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;/*设定DMA工作再循环缓存模式*/DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;/*设定DMA选定的通道软件优先级*/DMA_InitStructure.DMA_Priority=DMA_Priority_High;DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;DMA_Init(DMA1_Channel1,&DMA_InitStructure);/*EnableDMAchannel1*/DMA_Cmd(DMA1_Channel1,ENABLE);/*设置ADC工作在独立模式*/ADC_InitStructure.ADC_Mode=ADC_Mo
本文标题:STM32-ADC单通道与多通道_DMA学习笔记
链接地址:https://www.777doc.com/doc-4877299 .html