ARM嵌入基础应用 3_第1页
ARM嵌入基础应用 3_第2页
ARM嵌入基础应用 3_第3页
ARM嵌入基础应用 3_第4页
ARM嵌入基础应用 3_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

第13章

直接存储器访问作者:黄克亚2025年5月本章概要CONTENTS直接存储器访问的基本概念STM32F103的DMA相关库函数STM32F103的DMA工作原理ADC+DMA+USART项目实施13.1DMA的基本概念直接存储器访问(DirectMemoryAccess,DMA)是计算机系统中用于快速、大量数据交换的重要技术。13.1DMA的基本概念13.1.1DMA由来一个完整的微控制器就像一台集成在一块芯片上的计算机系统,通常包括CPU、存储器和外部设备等部件。这些相互独立的各个部件在CPU的协调和交互下协同工作。作为微控制器的大脑,CPU的相当一部分工作被数据传输占据了。所以我们希望,CPU能从简单频繁的“数据搬运”工作中摆脱出来,去处理那些更重要(运算控制)、更紧急(实时响应)的事情,而把“数据搬运”交给专门的部件去完成,就像第9章中讲述的,CPU把“计数”操作交给定时器完成一样,于是DMA和DMA控制器就应运而生了。单片机CPU存储器外设13.1DMA的基本概念13.1.2DMA定义DMA是一种完全由硬件执行数据交换的工作方式。它由DMA控制器而不是CPU控制在存储器和存储器、存储器和外设之间的批量数据传输。一般来说,一个DMA控制器有若干条数据传输链路,称为DMA流,每条链路连接多个外设。这些连接在同一DMA流上的多个外设可以分时复用这条DMA传输链路。但同一时刻,一条DMA传输链路上只能有一个外设进行DMA数据传输。外设CPU存储器DMA13.1DMA的基本概念13.1.3DMA传输过程CPU对DMA控制器初始化,并向外设发出操作命令,外设提出DMA请求。(1)DMA请求DMA控制器对DMA请求判别优先级及屏蔽,向总线裁决逻辑提出总线请求。(2)DMA响应DMA控制器获得总线控制权后,CPU即刻挂起或只执行内部操作,由DMA控制器输出读写命令,直接控制存储器与外设进行DMA传输。(3)DMA传输当完成规定的成批数据传送后,DMA控制器即释放总线控制权,并向外设发出结束信号。(4)DMA结束13.1DMA的基本概念13.1.4DMA优点降低了CPU的负担,释放了CPU的资源,使得CPU的使用效率大大提高。显著地提高了数据传输的效率,能满足高速I/O设备的要求。因为不需要中间变量减少用户软件开发的代码量,程序变得更加简洁,编程效率得以提高由硬件直接实现因为不需要CPU干预13.2STM32F103的

DMA工作原理STM32F103微控制器有两个DMA控制器,其共有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。13.2STM32F103的DMA工作原理13.2.1STM32F103的DMA主要特性

12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推)。独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。支持循环的缓冲器管理每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。支持存储器和存储器、外设和存储器、存储器和外设之间的传输闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标。可编程的数据传输数目:最大为6553513.2STM32F103的DMA工作原理13.2.2STM32F103的DMA内部结构DMA控制器和Cortex-M3核心共享系统数据总线,执行直接存储器数据传输。当CPU和DMA同时访问相同的目标(RAM或外设)时,DMA请求会暂停CPU访问系统总线达若干个周期,总线仲裁器执行循环调度,以保证CPU至少可以得到一半的系统总线(存储器或外设)带宽13.2STM32F103的DMA工作原理13.2.3STM32F103的DMA通道DMA1通道:01外设通道1通道2通道3通道4通道5通道6通道7ADC1ADC1SPI/I2S

SPI1_RXSPI1_TXSPI/I2S2_RXSPI/I2S2_TX

USART

USART3_TXUSART3_RXUSART1_TXUSART1_RXUSART2_RXUSART2_TXI2C

I2C2_TXI2C2_RXI2C1_TXI2C1_RXTIM1

TIM1_CH1TIM1_CH2TIM1_TX4TIM1_TRIGTIM1_COMTIM1_UPTIM1_CH3

TIM2TIM2_CH3TIM2_UP

TIM2_CH1

TIM2_CH2TIM2_CH4TIM3

TIM3_CH3TIM3_CH4TIM3_UP

TIM3_CH1TIM3_TRIG

TIM4TIM4_CH4

TIM4_CH2TIM4_CH3

TIM4_UPSTM32F103的DMA1有7个触发通道,可以分别从外设(TIMx[x=1、2、3、4]、ADC1、SPI1、SPI/I2S2、I2Cx[x=1、2]和USARTx[x=1、2、3])产生的7个访问请求,通过逻辑或输入到DMA1控制器,这意味着同时只能有一个请求有效。13.2STM32F103的DMA工作原理13.2.3STM32F103的DMA通道DMA2通道:02外设通道1通道2通道3通道4通道5ADC3ADC3SPI/I2S3SPI/I2S3_RXSPI/I2S3_TXUART4UART4_RXUART4_TXSDIO(1)SDIOTIM5TIM5_CH4TIM5_TRIGTIM5_CH3TIM5_UPTIM5_CH2TIM5_CH1TIM6/DAC通道1TIM6_UP/DAC通道1TIM7/DAC通道2TIM7_UP/DAC通道2TIM8(1)TIM8_CH3TIM8_UPTIM8_CH4TIM8_TRIGTIM8_COMTIM8_CH1TIM8_CH2DMA2控制器及相关请求仅存在于大容量STM32F103和互联型的STM32F105、STM32F107系列产品中。它有5个触发通道,可以分别从外设(TIMx[5、6、7、8]、ADC3、SPI/I2S3、UART4、DAC通道1、2和SDIO)产生的5个请求,经逻辑或输入到DMA2控制器,这意味着同时只能有一个请求有效。13.2STM32F103的DMA工作原理13.2.4STM32F103的DMA优先级优先权管理软件优先级每个通道的优先权可以在DMA_CCRx寄存器中设置最高优先级高优先级中等优先级低优先级硬件优先级如果2个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高的优先权13.2STM32F103的DMA工作原理13.2.5STM32F103的DMA传输模式01普通模式是指在DMA传输结束时,DMA通道被自动关闭,进一步的DMA请求将不被响应。普通模式02循环模式用于处理一个环形的缓冲区,每轮传输结束时数据传输的配置会自动地更新为初始状态,DMA传输会连续不断地进行。循环模式13.2STM32F103的DMA工作原理13.2.6STM32F103的DMA中断每个DMA通道都可以在DMA传输过半、传输完成和传输错误时产生中断。为应用的灵活性考虑,通过设置寄存器的不同位来打开这些中断。中断事件事件标志位使能控制位传输过半HTIFHTIE传输完成TCIFTCIE传输错误TEIFTEIE13.3DMA相关库函数本节重点介绍DMA相关库函数名称和功能,应用方法会结合项目实例详细讲解。13.3DMA相关库函数13.3.1函数DMA_DeInit函数名DMA_DeInit函数原形voidDMA_DeInit(DMA_Channel_TypeDef*DMAy_Channelx)功能描述DMAy_Channelx寄存器重设为缺省值输入参数DMAy_Channelx:DMAy的通道x其中y可以是1或2对于DMA1,x可以是1~7,对于DMA2,x可以是1~5输出参数无返回值无例:/*DeinitializetheDMA1Channel2*/DMA_DeInit(DMA1_Channel2);13.3DMA相关库函数13.3.2函数DMA_Init函数名DMA_Init函数原形voidDMA_Init(DMA_Channel_TypeDef*DMAy_Channelx,DMA_InitTypeDef*DMA_InitStruct)功能描述根据DMA_InitStruct中指定的参数初始化DMAy的通道x寄存器输入参数1DMAy_Channelx:DMAy的通道x其中y可以是1或2对于DMA1,x可以是1~7,对于DMA2,x可以是1~5输入参数2DMA_InitStruct:指向结构DMA_InitTypeDef的指针,包含了DMAy通道x的配置信息输出参数无返回值无DMA_PeripheralBaseAddr:该参数用以定义DMA外设基地址DMA_MemoryBaseAddr:该参数用以定义DMA内存基地址DMA_InitTypeDefstructureDMA_InitTypeDef定义于文件“stm32f10x_dma.h”:typedefstruct{u32DMA_PeripheralBaseAddr;u32DMA_MemoryBaseAddr;u32DMA_DIR;u32DMA_BufferSize;u32DMA_PeripheralInc;u32DMA_MemoryInc;u32DMA_PeripheralDataSize;u32DMA_MemoryDataSize;u32DMA_Mode;u32DMA_Priority;u32DMA_M2M;}DMA_InitTypeDef;13.3DMA相关库函数13.3.2函数DMA_InitDMA_DIR:DMA_DIR规定了外设是作为数据传输的目的地还是来源DMA_DIR描述DMA_DIR_PeripheralDST外设作为数据传输的目的地DMA_DIR_PeripheralSRC外设作为数据传输的来源DMA_BufferSize:

用以定义指定DMA通道的DMA缓存的大小,单位为数据单位。根据传输方向,数据单位等于结构中参数DMA_PeripheralDataSize或者参数DMA_MemoryDataSize的值。DMA_PeripheralInc:用来设定外设地址寄存器递增与否DMA_PeripheralDataSize:设定了外设数据宽度DMA_PeripheralInc描述DMA_PeripheralInc_Enable外设地址寄存器递增DMA_PeripheralInc_Disable外设地址寄存器不变DMA_PeripheralDataSize描述DMA_PeripheralDataSize_Byte数据宽度为8位DMA_PeripheralDataSize_HalfWord数据宽度为16位DMA_PeripheralDataSize_Word数据宽度为32位13.3DMA相关库函数13.3.2函数DMA_InitDMA_MemoryDataSize:设定了外设数据宽度。DMA_MemoryDataSize描述DMA_MemoryDataSize_Byte数据宽度为8位DMA_MemoryDataSize_HalfWord数据宽度为16位DMA_MemoryDataSize_Word数据宽度为32位DMA_Mode:设置了CAN的工作模式DMA_Priority:设定DMA通道x的软件优先级DMA_Mode描述DMA_Mode_Circular工作在循环缓存模式DMA_Mode_Normal工作在正常缓存模式DMA_Mode描述DMA_Priority_VeryHighDMA通道x拥有非常高优先级DMA_Priority_HighDMA通道x拥有高优先级DMA_Priority_MediumDMA通道x拥有中优先级DMA_Priority_LowDMA通道x拥有低优先级注意:当指定DMA通道数据传输配置为内存到内存时,不能使用循环缓存模式。13.3DMA相关库函数13.3.2函数DMA_InitDMA_M2M:使能DMA通道的内存到内存传输DMA_M2M描述DMA_M2M_EnableDMA通道x设置为内存到内存传输DMA_M2M_DisableDMA通道x没有设置为内存到内存传输例:/*InitializetheDMA1Channel1accordingtotheDMA_InitStructuremembers*/DMA_InitTypeDefDMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr=0x40005400;DMA_InitStructure.DMA_MemoryBaseAddr=0x20000100;DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize=256;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_Normal;DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;DMA_Init(DMA1_Channel1,&DMA_InitStructure);13.3DMA相关库函数13.3.3函数DMA_GetCurrDataCounter函数名DMA_GetCurrDataCounter函数原形u16DMA_GetCurrDataCounter(DMA_Channel_TypeDef*DMAy_Channelx)功能描述返回当前DMAy通道x剩余的待传输数据数目输入参数DMAy_Channelx:选择DMAy通道x输出参数无返回值当前DMA通道x剩余的待传输数据数目例:/*GetthenumberofremainingdataunitsinthecurrentDMA1Channel2transfer*/u16CurrDataCount;CurrDataCount=DMA_GetCurrDataCounter(DMA1_Channel2);13.3DMA相关库函数13.3.4函数DMA_Cmd函数名DMA_Cmd函数原形voidDMA_Cmd(DMA_Channel_TypeDef*DMAy_Channelx,FunctionalStateNewState)功能描述使能或者失能指定的通道x输入参数1DMAy_Channelx:选择DMAy通道x输入参数2NewState:DMA通道x的新状态

这个参数可以取:ENABLE或者DISABLE输出参数无返回值无例:/*EnableDMA1Channel7*/DMA_Cmd(DMA1_Channel7,ENABLE);13.3DMA相关库函数13.3.5函数DMA_GetFlagStatus函数名

DMA_GetFlagStatus函数原形

FlagStatusDMA_GetFlagStatus(uint32_tDMAy_FLAG)功能描述

检查指定的DMAy通道x标志位设置与否输入参数

DMAy_FLAG:待检查的DMAy通道x标志位参阅Section:DMA_FLAG查阅更多该参数允许取值范围输出参数

无返回值

DMA_FLAG的新状态(SET或者RESET)DMA_M2M:使能DMA通道的内存到内存传输DMA_FLAG描述DMA_FLAG描述DMA1_FLAG_GL1DMA1通道1全局标志位DMA1_FLAG_TC2DMA1通道2传输完成标志位DMA1_FLAG_TC1DMA1通道1传输完成标志位DMA1_FLAG_HT2DMA1通道2传输过半标志位DMA1_FLAG_HT1DMA1通道1传输过半标志位DMA1_FLAG_TE2DMA1通道2传输错误标志位DMA1_FLAG_TE1DMA1通道1传输错误标志位……依次类推……依次类推DMA1_FLAG_GL2DMA1通道2全局标志位例:/*TestiftheDMA1Channel6halftransferinterruptflagissetornot*/FlagStatusStatus;Status=DMA_GetFlagStatus(DMA1_FLAG_HT6);13.3DMA相关库函数13.3.6函数DMA_ClearFlag函数名

DMA_ClearFlag函数原形

voidDMA_ClearFlag(u32DMAy_FLAG)功能描述

清除DMAy通道x待处理标志位输入参数

DMAy_FLAG:待清除的DMA标志位,使用操作符“|”可以同时选中多个DMA标志位输出参数

无返回值

无例:/*CleartheDMA1Channel3transfererrorinterruptpendingbit*/DMA_ClearFlag(DMA1_FLAG_TE3);13.3DMA相关库函数13.3.7函数DMA_ITConfig函数名

DMA_ITConfig函数原形

voidDMA_ITConfig(DMA_Channel_TypeDef*DMAy_Channelx,u32DMA_IT,FunctionalStateNewState)功能描述

使能或者失能指定的DMAy通道x中断输入参数1DMAy_Channelx:选择DMAy通道x输入参数2DMA_IT:待使能或者失能的DMA中断源,使用操作符“|”可以同时选中多个DMA中断源输入参数3NewState:DMA通道x中断的新状态

这个参数可以取:ENABLE或者DISABLEDMA_IT:输入参数DMA_IT使能或者失能DMAy通道x的中断。可以取下表的一个或者多个取值的组合作为该参数的值。DMA_IT描述DMA_IT_TC传输完成中断屏蔽DMA_IT_HT传输过半中断屏蔽DMA_IT_TE传输错误中断屏蔽例:/*EnableDMA1Channel5completetransferinterrupt*/DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);13.3DMA相关库函数13.3.8函数DMA_GetITStatus函数名

DMA_GetITStatus函数原形

ITStatusDMA_GetITStatus(uint32_tDMAy_IT)功能描述

检查指定的DMAy通道x中断发生与否输入参数

DMAy_IT:待检查的DMAy的通道x中断源输出参数

无返回值

DMA_IT的新状态(SET或者RESET)DMAy_IT:参数DMA_IT定义了待检察的DMA中断DMAy_IT描述DMAy_IT描述DMA1_IT_GL1通道1全局中断DMA1_IT_TC2通道2传输完成中断DMA1_IT_TC1通道1传输完成中断DMA1_IT_HT2通道2传输过半中断DMA1_IT_HT1通道1传输过半中断DMA1_IT_TE2通道2传输错误中断DMA1_IT_TE1通道1传输错误中断……依次类推……依次类推DMA1_IT_GL2通道2全局中断例:/*TestiftheDMAChannel7transfercompleteinterrupthasoccurredornot*/ITStatusStatus;Status=DMA_GetITStatus(DMA_IT_TC7);13.4项目实例本例实现ADC采集、DMA传输、USART显示综合应用项目。13.4项目实例13.4.1项目分析本项目需要实现的功能为在4个输入通道采集模拟电压信号,送ADC1进行模数转换,将转换结果利用DMA1控制器传送到内存数组当中,并进行均值滤波,将滤波后的结果通过USART1串口发送至PC机,PC机利用串口调试助手接收并显示AD转换结果。所以本项目是“ADC+DMA+USART”,项目综合性较强。其中ADC部分内容同第12章,没有大的改变,只要打开ADC1的DMA功能即可,在此不作过多介绍。USART部分内容也基本同第10章,但是为了工程通用性,需要重新新建“printf.c”和“printf.h”两个文件,并重写C语言当中的printf函数。DMA传输是本章新讲授的内容,要使用DMA控制器需要打开DMA时钟,对DMA进行初始化,并启动DMA控制器。13.4项目实例第一步:复制第12章创建工程模板文件夹到桌面,并将文件夹改名为“12ADC+DMA+Printf”,将原工程模板编译一下,直到没有错误和警告为止。11ADC12ADC+DMA+Printf第二步:为工程模板的“ST_Driver”项目组添加DMA库函数源文件“stm32f10x_dma.c”,该文件位于“..\Libraries\STM32F10x_StdPeriph_Driver\src”目录下。13.4.2项目实施13.4项目实例项目实施第三步:由于本项目需要将AD转换结果打印到PC机的串口,由于大家都十分熟悉C语言中的printf函数,所以我们这里将标准C的printf重写一下,利用微控制器的串口将数据发送至PC机,数据发送方法和我们在标准C语言中使用printf函数向显示屏打印信息是一样的。具体方法是如下:1.点击“File/New”新建两个文件,将其改名为printf.c和printf.h并保存到工程模板下的APP文件夹中。并将printf.c文件添加到APP项目组下。2、在printf.c文件中输入如下源程序,在程序中首先包含printf.h头文件,然后重写fputc函数,并对串口USART1进行初始化,初始化代码和第10章是一样的。参考代码如下:#include"printf.h"intfputc(intch,FILE*p)//函数默认的在使用printf函数时自动调用{USART_SendData(USART1,(u8)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);returnch;}voidprintf_init()//串口初始化{GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure;/*打开端口时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);/*配置GPIO的模式和IO口*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX//串口输出PA9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化串口输入IO*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX//串口输入PA10GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//模拟输入GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化GPIO*//*USART串口初始化*/USART_InitStructure.USART_BaudRate=9600;//波特率设置为9600//波特率USART_InitStructure.USART_WordLength=USART_WordLength_8b;//数据长8位USART_InitStructure.USART_StopBits=USART_StopBits_1;//1位停止位USART_InitStructure.USART_Parity=USART_Parity_No;//无效验USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//失能硬件流USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//开启发送和接受模式USART_Init(USART1,&USART_InitStructure);/*初始化USART1*/USART_Cmd(USART1,ENABLE);/*使能USART1*/USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能或者失能指定的USART中断接收中断USART_ClearFlag(USART1,USART_FLAG_TC);//清除USARTx的待处理标志位}参考程序代码13.4项目实例项目实施3.在printf.h文件中输入如下源程序,其中条件编译格式不变,只要更改一下预定义变量名称即可,需要将我们刚定义函数的声明加到头文件当中。4.在main.h文件的中间部分添加“#include"printf.h"”语句,即包含printf.h头文件。参考代码如下:#ifndef_PRINTF_H#define_PRINTF_H#include"stm32f10x.h"#include"stdio.h"intfputc(intch,FILE*p);voidprintf_init(void);#endif13.4项目实例项目实施5.打开工程属性对话框“OptionsforTarget‘Target1’”,在“Target”选项中选中“UseMicroLIB”复选框,此步非常重要,否则编译不能通过。6、此时已经可以像标准C语言一样,使用printf函数向串口输出数据呢!大家可以在main函数中,使用语句“printf(“HelloWorld!\n”)”,输出一个字符串,并在串口调试助手中查看输出结果,串口调试助手使用方法同第10章。以后如果需要向串口输出信息时,只要先包含文件“printf.h”,再调用printf函数即可,十分方便。13.4项目实例项目实施第四步:点击“File/New”新建两个文件,将其改名为DMA-ADC.C和DMA-ADC.H并保存到工程模板下的APP文件夹中。并将DMA-ADC.C文件添加到APP项目组下。第五步:在DMA-ADC.C文件中输入如下源程序,在程序中首先包含DMA-ADC.H头文件,分别创建3个函数ADC_Use_DMA_Init()、DMA_For_ADC_Init()和filter()函数。#include"DMA-ADC.H"externu16AD_Value[20][4];//AD转换结果4个通道每个通道20次externu16After_filter[4];//滤波后的数值共4个通道//使用DMA传输的ADC初始化程序voidADC_Use_DMA_Init(){GPIO_InitTypeDefGPIO_InitStructure;ADC_InitTypeDefADC_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_Init(GPIOA,&GPIO_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_ADC1,ENABLE);参考程序代码13.4项目实例RCC_ADCCLKConfig(RCC_PCLK2_Div6);ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode=ENABLE;ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel=4;//此次转换共六个通道PA0~PA3ADC_Init(ADC1,&ADC_InitStructure);ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);ADC_DMACmd(ADC1,ENABLE);//开启ADC的DMA支持具体数据读取还需要进一步配置DMAADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));ADC_SoftwareStartConvCmd(ADC1,ENABLE);}参考程序代码13.4项目实例//DMA控制器初始化程序voidDMA_For_ADC_Init(){DMA_InitTypeDefDMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//开启DMA时钟DMA_DeInit(DMA1_Channel1);//初始化为缺省值DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&ADC1->DR;//DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&AD_Value;//DMA内存基地址DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//内存作为DMA目的地址DMA_InitStructure.DMA_BufferSize=4*20;//缓冲区的大小DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设基地址不变DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//内存基址递增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高优先级DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//DMA没有设置为内存到内存模式DMA_Init(DMA1_Channel1,&DMA_InitStructure);//初始化}//ADC转换结果中值滤波函数voidfilter(){u32sum=0;u8i,j;for(i=0;i<4;i++)//4个通道20次{sum=0;for(j=0;j<20;j++)sum+=AD_Value[j][i];After_filter[i]=sum/20;}}参考程序代码13.4项目实例第六步:在DMA-ADC.H文件中输入如下源程序,其中条件编译格式不变,只要更改一下预定义变量名称即可,需要将我们刚定义函数的声明加到头文件当中。项目实施第六步参考代码如下:#ifndef_DMA_H#define_DMA_H#include"stm32f10x.h"voidADC_Use_DMA_Init(void);voidDMA_For_ADC_Init(void);voidfilter(void);#endif第七步:在main.h文件的中间部分添加“#include"DMA-ADC.H"”语句,即包含DMA-ADC.H头文件,main.h文件的源代码如下所示

温馨提示

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

评论

0/150

提交评论