STM32F103之DMA寄存器移植笔记

一、DMA 简介
直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输,无须CPU干预。数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。

一共两个DMA控制器,DMA1 7个通道,DMA2有5个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求,
还有一个仲裁器来协调各个DMA请求的优先权。

就是有两个DMA,每个DMA有多个通道,每个通道独立,每个通道需要负责一个或多个任务,每个DMA之间有优先级。

●在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推) 。
●传输宽度(字节、半字、全字)。源和目标地址必须按数据传输宽度对齐。
●每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。
● 存储器和存储器间的传输
● 外设和存储器、存储器和外设之间的传输
● 闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标。
● 可编程的数据传输数目:最大为65535

二、通道配置过程
下面是配置DMA通道x的过程(x代表通道号):

  1. 在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
  2. 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入这个地址。
  3. 在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
  4. 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。
  5. 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
  6. 设置DMA_CCRx寄存器的ENABLE位,启动该通道。

一旦启动了DMA通道,它既可响应连到该通道上的外设的DMA请求。
当传输一半的数据后,半传输标志(HTIF)被置1,当设置了允许半传输中断位(HTIE)时,将产生
一个中断请求。在数据传输结束后,传输完成标志(TCIF)被置1,当设置了允许传输完成中断位
(TCIE)时,将产生一个中断请求。

DMA从寄存器看通道配置过程,每一步详细解答,其中第五步最麻烦。
重点搞清楚数据量、数据宽度、循环、方向、外设和存储器做为两端时的注意事项。
1、设置外设寄存器的地址
//DMA 通道x 外设地址寄存器(DMA_CPARx)(x = 1…7)
// 外设数据寄存器的基地址,作为数据传输的源或目标。
// 当PSIZE=’01’(16位),不使用PA[0]位。操作自动地与半字地址对齐。
// 当PSIZE=’10’(32位),不使用PA[1:0]位。操作自动地与字地址对齐。
2、设置数据存储器的地址
//DMA 通道x 传输数量寄存器(DMA_CNDTRx)(x = 1…7)
// 存储器地址作为数据传输的源或目标
// 当MSIZE=’01’(16位),不使用MA[0]位。操作自动地与半字地址对齐。
// 当MSIZE=’10’(32位),不使用MA[1:0]位。操作自动地与字地址对齐。
3、设置要传输的数据量。在每个数据传输后,这个数值递减
//DMA 通道x 传输数量寄存器(DMA_CNDTRx)(x = 1…7) 15:0有效
// 数据传输数量为0至65535。这个寄存器只能在通道不工作(DMA_CCRx的EN=0)时写入。通道开启后该寄存器变为只读,指示剩余的待传输字节数目。寄存器内容在每次DMA传输后递减。
// 数据传输结束后,寄存器的内容或者变为0;或者当该通道配置为自动重加载模式时,寄存器的内容将被自动重新加载为之前配置时的数值。
// 当寄存器的内容为0时,无论通道是否开启,都不会发生任何数据传输。
4、设置通道的优先级
//DMA 通道x 配置寄存器(DMA_CCRx)(x = 1…7)
//位13:12 00:低
// 01:中
// 10:高
// 11:最高
●如果2个请求有相同的软件优先级,则较低编号的通道比较高编号的通道有较高的优
先权。举个例子,通道2优先于通道4。
注意: 在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级
5、设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
//DMA 通道x 配置寄存器(DMA_CCRx)(x = 1…7)
1)数据传输方向
//位4
//该位由软件设置和清除。
//0:从外设读
//1:从存储器读
2)循环模式
//位5
//该位由软件设置和清除。
//0:不执行循环操作
//1:执行循环操作
3)外设和存储器的增量模式
//位7 存储器地址增量模式
//0:不执行存储器地址增量操作
//1:执行存储器地址增量操作
//位6 外设地址增量模式 (Peripheral increment mode)
//0:不执行外设地址增量操作
//1:执行外设地址增量操作
4)外设和存储器的数据宽度
//位11:10 存储器数据宽度
//00:8位
//01:16位
//10:32位
//11:保留
//位9:8 外设数据宽度 (Peripheral size)
//00:8位
//01:16位
//10:32位
//11:保留
5)中断,数据传输半中断或完全中断
//位3 允许传输错误中断
//0:禁止TE中断
//1:允许TE中断
//位2 允许半传输中断 (Half transfer interrupt enable)
//0:禁止HT中断
//1:允许HT中断
//位1 允许传输完成中断 (Transfer complete interrupt enable)
//0:禁止TC中断
//1:允许TC中断
6)开启ENABLE位,启动该通道
//位0
//0:通道不工作
//1:通道开启
7)关于储存器到储存器需要开启一位
//位14
//0:非存储器到存储器模式;
//1:启动存储器到存储器模式

///
调试经历
1、写零不要用A&=~(1<<8)用A|=0<<8
2、先开时钟!!!RCC->AHBENR|=1<<0;//开DMA1时钟
RCC->AHBENR|=1<<1;//开DMA2时钟
3、配置好外设工作模式后别忘了打开外设的DMA使能
USART1->CR3=1<<6; //使能串口1的DMA接收
4、外设中断貌似可以不关。
5、外设寄存器的地址不用查表,直接(u32)&外设
例:(u32)&USART1->DR
6、储存器地址也要加(32)强制类型转化。
///
关于接收,还在搞中断,一直没触发
1、别忘了分配优先级~~~~MY_NVIC_Init
2、非循环的再次开始记得关闭使能再写寄存器
DMA1_Channel5->CCR&=~(1<<0); //关闭DMA传输
DMA1_Channel5->CNDTR=20; //DMA1,传输数据量
DMA1_Channel5->CCR|=1<<0; //开启DMA传输
以上三句话加在中断中,可以起到第五位循环的作用,仅仅是作用,没有别的。
。每次接收满了清除缓存区(赋值0),就可以一组一组的接收,循环模式下从零位开始写,所以这个清除又是没啥用(放在完全接收完毕中断中)
。数据覆盖方式是覆盖式,不是推进式
3、记得清除中断!!!
void DMA1_Channel5_IRQHandler(void)
{
u8 i;
if(DMA1->ISR&1<<17)//通道5完全传输中断
{
DMA1->IFCR|=1<<17;//清除通道5完成半传输中断
}

if(DMA1->ISR&1<<18)//清除通道5完成半传输中断
{
	DMA1->IFCR|=1<<18;//清除通道5完成半传输中断		
}
if(DMA1->ISR&1<<19)//清除通道5错误传输中断
{
	DMA1->IFCR|=1<<19;//清除通道5错误传输中断		
}

}

方向有:
外设到SRAM(I2C/UART等获取数据并送入SRAM);
SRAM的两个区域之间;
外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比);
SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形);
也就是说内存和数据之间没啥差别
注意:内存到内存之间不用循环模式

地址列表:
// DMA1:7通道
1:
ADC1 ((u32)0x40012400+0x4c)
TIM2_CH3
TIM4_CH1

                 2:
                   USART3_TX                 0x40014804
                   TIM1_CH1
                   TIM2_UP
                   TIM3_CH3
                   SPI1_RX

                 3:
                   USART3_RX                 0x40014804
                   TIM1_CH2
                   TIM3_CH4
                   TIM3_UP
                   SPI1_TX
               
                 4:
                   USART1_TX                 0x40013804
                   TIM1_CH4
                   TIM1_TRIG
                   TIM1_COM
                   TIM4_CH2
                   SPI/I2S2_RX
                   I2C2_TX
                   
                 5:
                   USART1_RX                0x40013804
                   TIM1_UP
                   SPI/I2S2_TX
                   TIM2_CH1
                   TIM4_CH3
                   I2C2_RX

                 6:
                   USART2_RX                0x40014404
                   TIM1_CH3
                   TIM3_CH1
                   TIM3_TRIG
                   I2C1_TX  

                7:
                   USART2_TX                0x40014404
                   TIM2_CH2
                   TIM2_CH4
                   TIM4_UP
                   I2C1_RX
       DMA2  5路
                 1:
                   TIM5_CH4
                   TIM5_TRIG
                   TIM8_UP
                   SPI/I2S3_RX

                 2:
                   TIM8_CH4
                   TIM8_TRIG
                   TIM5_CH3
                   TIM5_UP
                   SPI/I2S3_TX   
                    
                 3:
                   TIM8_CH1
                   UART4_RX               
                   TIM6_UP/DAC_Channel1

                 4:
                   TIM5_CH2
                   SDIO
                   TIM7_UP/DAC_Channel2

/--------------------------------------------------------------------------------------------------------/

没有排版哈 多谅解

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值