完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
研究了两天的SPI通过DMA操作. 过程:怎样启用DMA?首先,众所周知的是初始化,任何设备启用前都要对其进行初始化,要对模块初始化,还要先了解该模块相应的结构及其函数,以便正确的设置;由于DMA较为复杂,我就只谈谈DMA的基本结构和和常用函数,这些都是ST公司提供在库函数中的。 1、 下面代码是一个标准DMA设置,当然实际应用中可根据实际情况进行裁减: DMA_DeInit(DMA_Channel1); 上面这句是给DMA配置通道,根据ST提供的资料,STM3210Fx中DMA包含7个通道(CH1~CH7),也就是说可以为外设或memory提供7座“桥梁”(请允许我使用桥梁一词,我觉得更容易理解,哈哈,别“拍砖”呀!); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; 上面语句中的DMA_InitStructure是一个DMA结构体,在库中有声明了,当然使用时就要先定义了;DMA_PeripheralBaseAddr是该结构体中一个数据成员,给DMA一个起始地址,好比是一个buffer起始地址,数据流程是:外设寄存器à DMA_PeripheralBaseAddàmemory中变量空间(或flash中数据空间等),ADC1_DR_Address是我定义的一个地址变量; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; 上面这句很显然是DMA要连接在Memory中变量的地址,ADC_ConvertedValue是我自己在memory中定义的一个变量; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 上面的这句是设置DMA的传输方向,就如前面我所说的,DMA可以双向传输,也可以单向传输,这里设置的是单向传输,如果需要双向传输:把DMA_DIR_PeripheralSRC改成DMA_DIR_PeripheralDST即可。 DMA_InitStructure.DMA_BufferSize = 2; 上面的这句是设置DMA在传输时缓冲区的长度,前面有定义过了buffer的起始地址:ADC1_DR_Address ,为了安全性和可靠性,一般需要给buffer定义一个储存片区,这个参数的单位有三种类型:Byte、HalfWord、word,我设置的2个half-word(见下面的设置);32位的MCU中1个half-word占16 bits。 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 上面的这句是设置DMA的外设递增模式,如果DMA选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_Enable;我的例子里DMA只与ADC1建立了联系,所以选用DMA_PeripheralInc_Disable DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 上面的这句是设置DMA的内存递增模式,DMA访问多个内存参数时,需要使用DMA_MemoryInc_Enable,当DMA只访问一个内存参数时,可设置成:DMA_MemoryInc_Disable。 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 上面的这句是设置DMA在访问时每次操作的数据长度。有三种数据长度类型,前面已经讲过了,这里不在叙述。 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 与上面雷同。在此不再说明。 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 上面的这句是设置DMA的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal DMA_InitStructure.DMA_Priority = DMA_Priority_High; 上面的这句是设置DMA的优先级别:可以分为4级:VeryHigh,High,Medium,Low. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 上面的这句是设置DMA的2个memory中的变量互相访问的 DMA_Init(DMA_Channel1,&DMA_InitStructure); 前面那些都是对DMA结构体成员的设置,在次再统一对DMA整个模块做一次初始化,使得DMA各成员与上面的参数一致。 /*DMA Enable*/ DMA_Cmd(DMA_Channel1,ENABLE); 哈哈哈!这一句我想我就不罗嗦了,大家一看就明白。 至此,整个DMA总算设置好了,但是,DMA通道又是怎样与外设联系在一起的呢?哈哈,这也是我当初最想知道的一个事情,别急!容我想喝口茶~~~~~~哈哈哈!稍后整理。 |
|
相关推荐
|
|
|
|
|
|
大彭 发表于 2015-1-22 09:38 感觉你之前说的DMA_BufferSize解释有误,这个应该是DMA传输的计数值,如果采用循环传输内存地址自增的话,用这个计数值来确定循环传输的数据个数,而不是缓冲区的大小。我从其他地方查到的 |
|
|
|
|
|
1085 浏览 0 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1041 浏览 2 评论
2145 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1240 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1660 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 20:30 , Processed in 0.469957 second(s), Total 45, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号