网站建设it,安平县护栏网站建设,深圳专业网站建设免费送域名空间,做文案策划需要知道些什么网站我用的是正点的STM32F103来进行学习#xff0c;板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话#xff0c;用的也是这个板子和教程。 DMA的基础知识与用法 二、DMA传输设置1、数据来源与数据去向外设到存储器存储器到外设存储器到存储器 2、每次传输大小3、传… 我用的是正点的STM32F103来进行学习板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话用的也是这个板子和教程。 DMA的基础知识与用法 二、DMA传输设置1、数据来源与数据去向外设到存储器存储器到外设存储器到存储器 2、每次传输大小3、传输结束标志 二、DMA传输设置
通常来说DMA传输最重要的三个内容为
数据来源与数据去向每次传输大小传输结束标志
1、数据来源与数据去向
我们知道 DMA 传输数据的方向有三个
从外设到存储器 P-M从存储器到外设 M-P从存储器到存储器 M-M
具体的方向 DMA_CCR 位 4 DIR 配置0 表示从外设到存储器1 表示从存储器到外设。
这里面涉及到的外设地址由 DMA_CPAR 配置存储器地址由 DMA_CMAR 配置。
外设到存储器
当我们使用从外设到存储器传输时以 ADC 采集为例。
DMA 外设寄存器的地址对应的就是 ADC数据寄存器的地址DMA 存储器的地址就是我们自定义的变量用来接收存储 AD 采集的数据的地址。 #mermaid-svg-GLtuDzhTD5m3mG3S {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S .error-icon{fill:#552222;}#mermaid-svg-GLtuDzhTD5m3mG3S .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GLtuDzhTD5m3mG3S .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-GLtuDzhTD5m3mG3S .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GLtuDzhTD5m3mG3S .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GLtuDzhTD5m3mG3S .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GLtuDzhTD5m3mG3S .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GLtuDzhTD5m3mG3S .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GLtuDzhTD5m3mG3S .marker.cross{stroke:#333333;}#mermaid-svg-GLtuDzhTD5m3mG3S svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GLtuDzhTD5m3mG3S .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S .cluster-label text{fill:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S .cluster-label span{color:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S .label text,#mermaid-svg-GLtuDzhTD5m3mG3S span{fill:#333;color:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S .node rect,#mermaid-svg-GLtuDzhTD5m3mG3S .node circle,#mermaid-svg-GLtuDzhTD5m3mG3S .node ellipse,#mermaid-svg-GLtuDzhTD5m3mG3S .node polygon,#mermaid-svg-GLtuDzhTD5m3mG3S .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GLtuDzhTD5m3mG3S .node .label{text-align:center;}#mermaid-svg-GLtuDzhTD5m3mG3S .node.clickable{cursor:pointer;}#mermaid-svg-GLtuDzhTD5m3mG3S .arrowheadPath{fill:#333333;}#mermaid-svg-GLtuDzhTD5m3mG3S .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GLtuDzhTD5m3mG3S .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GLtuDzhTD5m3mG3S .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-GLtuDzhTD5m3mG3S .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-GLtuDzhTD5m3mG3S .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GLtuDzhTD5m3mG3S .cluster text{fill:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S .cluster span{color:#333;}#mermaid-svg-GLtuDzhTD5m3mG3S div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GLtuDzhTD5m3mG3S :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 外设到存储器 自定义的变量地址 ADC数据寄存器地址 存储器到外设
当我们使用从存储器到外设传输时以串口向电脑端发送数据为例。
DMA 外设寄存器的地址对应的就是串口数据寄存器的地址DMA 存储器的地址就是我们自定义的变量相当于一个缓冲区用来存储通过串口发送到电脑的数据的地址。 #mermaid-svg-duxFD9xDEB8SZZt8 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 .error-icon{fill:#552222;}#mermaid-svg-duxFD9xDEB8SZZt8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-duxFD9xDEB8SZZt8 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-duxFD9xDEB8SZZt8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-duxFD9xDEB8SZZt8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-duxFD9xDEB8SZZt8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-duxFD9xDEB8SZZt8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-duxFD9xDEB8SZZt8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-duxFD9xDEB8SZZt8 .marker.cross{stroke:#333333;}#mermaid-svg-duxFD9xDEB8SZZt8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-duxFD9xDEB8SZZt8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 .cluster-label text{fill:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 .cluster-label span{color:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 .label text,#mermaid-svg-duxFD9xDEB8SZZt8 span{fill:#333;color:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 .node rect,#mermaid-svg-duxFD9xDEB8SZZt8 .node circle,#mermaid-svg-duxFD9xDEB8SZZt8 .node ellipse,#mermaid-svg-duxFD9xDEB8SZZt8 .node polygon,#mermaid-svg-duxFD9xDEB8SZZt8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-duxFD9xDEB8SZZt8 .node .label{text-align:center;}#mermaid-svg-duxFD9xDEB8SZZt8 .node.clickable{cursor:pointer;}#mermaid-svg-duxFD9xDEB8SZZt8 .arrowheadPath{fill:#333333;}#mermaid-svg-duxFD9xDEB8SZZt8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-duxFD9xDEB8SZZt8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-duxFD9xDEB8SZZt8 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-duxFD9xDEB8SZZt8 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-duxFD9xDEB8SZZt8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-duxFD9xDEB8SZZt8 .cluster text{fill:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 .cluster span{color:#333;}#mermaid-svg-duxFD9xDEB8SZZt8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-duxFD9xDEB8SZZt8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 存储器到外设 串口数据寄存器的地址 自定义的变量地址 存储器到存储器
当我们使用从存储器到存储器传输时以内部 FLASH 向内部 SRAM 复制数据为例。
DMA 外设寄存器的地址对应的就是内部 FLASH我们这里把内部 FALSH 当作一个外设来看的地址DMA存储器的地址就是我们自定义的变量相当于一个缓冲区用来存储来自内部 FLASH 的数据的地址。 #mermaid-svg-BpF0bCCorerpLd2s {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-BpF0bCCorerpLd2s .error-icon{fill:#552222;}#mermaid-svg-BpF0bCCorerpLd2s .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-BpF0bCCorerpLd2s .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-BpF0bCCorerpLd2s .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BpF0bCCorerpLd2s .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BpF0bCCorerpLd2s .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BpF0bCCorerpLd2s .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BpF0bCCorerpLd2s .marker{fill:#333333;stroke:#333333;}#mermaid-svg-BpF0bCCorerpLd2s .marker.cross{stroke:#333333;}#mermaid-svg-BpF0bCCorerpLd2s svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-BpF0bCCorerpLd2s .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-BpF0bCCorerpLd2s .cluster-label text{fill:#333;}#mermaid-svg-BpF0bCCorerpLd2s .cluster-label span{color:#333;}#mermaid-svg-BpF0bCCorerpLd2s .label text,#mermaid-svg-BpF0bCCorerpLd2s span{fill:#333;color:#333;}#mermaid-svg-BpF0bCCorerpLd2s .node rect,#mermaid-svg-BpF0bCCorerpLd2s .node circle,#mermaid-svg-BpF0bCCorerpLd2s .node ellipse,#mermaid-svg-BpF0bCCorerpLd2s .node polygon,#mermaid-svg-BpF0bCCorerpLd2s .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-BpF0bCCorerpLd2s .node .label{text-align:center;}#mermaid-svg-BpF0bCCorerpLd2s .node.clickable{cursor:pointer;}#mermaid-svg-BpF0bCCorerpLd2s .arrowheadPath{fill:#333333;}#mermaid-svg-BpF0bCCorerpLd2s .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-BpF0bCCorerpLd2s .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-BpF0bCCorerpLd2s .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-BpF0bCCorerpLd2s .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-BpF0bCCorerpLd2s .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-BpF0bCCorerpLd2s .cluster text{fill:#333;}#mermaid-svg-BpF0bCCorerpLd2s .cluster span{color:#333;}#mermaid-svg-BpF0bCCorerpLd2s div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-BpF0bCCorerpLd2s :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 存储器到存储器 自定义变量的地址 内部FLASH地址 (当做外设看待) 跟上面两个不一样的是这里需要把DMA_CCR 位 14MEM2MEM(存储器到存储器模式)配置为 1启动 M2M 模式。
2、每次传输大小
当我们配置好数据要从哪里来到哪里去之后我们还需要知道我们要传输的数据是多少数据的单位是什么。 #mermaid-svg-7dEnMvzoJrHbj5qI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI .error-icon{fill:#552222;}#mermaid-svg-7dEnMvzoJrHbj5qI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7dEnMvzoJrHbj5qI .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-7dEnMvzoJrHbj5qI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7dEnMvzoJrHbj5qI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7dEnMvzoJrHbj5qI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7dEnMvzoJrHbj5qI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7dEnMvzoJrHbj5qI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7dEnMvzoJrHbj5qI .marker.cross{stroke:#333333;}#mermaid-svg-7dEnMvzoJrHbj5qI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7dEnMvzoJrHbj5qI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI .cluster-label text{fill:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI .cluster-label span{color:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI .label text,#mermaid-svg-7dEnMvzoJrHbj5qI span{fill:#333;color:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI .node rect,#mermaid-svg-7dEnMvzoJrHbj5qI .node circle,#mermaid-svg-7dEnMvzoJrHbj5qI .node ellipse,#mermaid-svg-7dEnMvzoJrHbj5qI .node polygon,#mermaid-svg-7dEnMvzoJrHbj5qI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7dEnMvzoJrHbj5qI .node .label{text-align:center;}#mermaid-svg-7dEnMvzoJrHbj5qI .node.clickable{cursor:pointer;}#mermaid-svg-7dEnMvzoJrHbj5qI .arrowheadPath{fill:#333333;}#mermaid-svg-7dEnMvzoJrHbj5qI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7dEnMvzoJrHbj5qI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7dEnMvzoJrHbj5qI .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-7dEnMvzoJrHbj5qI .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-7dEnMvzoJrHbj5qI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7dEnMvzoJrHbj5qI .cluster text{fill:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI .cluster span{color:#333;}#mermaid-svg-7dEnMvzoJrHbj5qI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7dEnMvzoJrHbj5qI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 传输数据设置 如果打开了自动重加载模式数据量传输至0后复位 设置源地址和目标地址的增量模式 (设置数据存放的方向) 设置源地址和目标地址的宽度 (设置传输单位) 设置传输数据量大小 (设置传输总量) 以串口向电脑发送数据为例我们可以一次性给电脑发送很多数据具体多少由 DMA_CNDTR配置这是一个 32 位的寄存器一次最多只能传输 65535 个数据。
要想数据传输正确源和目标地址存储的数据宽度还必须一致串口数据寄存器是 8 位的所以我们定义的要发送的数据也必须是 8 位。 外设的数据宽度由 DMA_CCRx 的 PSIZE[1:0] 配置可以是 8/16/32 位存储器的数据宽度由 DMA_CCRx 的 MSIZE[1:0] 配置可以是 8/16/32 位。
在 DMA 控制器的控制下数据要想有条不紊的从一个地方搬到另外一个地方还必须正确设置两边数据指针的增量模式。
外设的地址指针由 DMA_CCRx 的 PINC 配置存储器的地址指针由MINC 配置。
以串口向电脑发送数据为例要发送的数据很多每发送完一个那么存储器的地址指针就应该加 1而串口数据寄存器只有一个那么外设的地址指针就固定不变。具体的数据指针的增量模式由实际情况决定。
3、传输结束标志
数据什么时候传输完成我们可以通过查询标志位或者通过中断的方式来鉴别。
每个 DMA 通道在 DMA 传输过半、传输完成和传输错误时都会有相应的标志位如果使能了该类型的中断后则会产生中断。 有关各个标志位的详细描述请参考 DMA 中断状态寄存器 DMA_ISR 的详细描述。
传输完成还分两种模式是一次传输还是循环传输一次传输很好理解即是传输一次之后就停止要想再传输的话必须关断 DMA 使能后再重新配置后才能继续传输。循环传输则是一次传输完成之后又恢复第一次传输时的配置循环传输不断的重复。
具体的由 DMA_CCRx 寄存器的CIRC 循环模式位控制。