etec 发表于 2026-7-2 22:23:41

使用DMA控制串口1通信,数据的发送和接收

您好,使用STC8H8K64U芯片的DMA的功能,控制串口1的数据发送和接收,
      DMA_UR1R_AMT = 255, //设置接收长度256
      DMA_UR1T_AMT= 8;   //设置发送长度8
    void UART1_DMA_ISR(void) interrupt 13
      {
                /*---- 处理 DMA TX 发送完成 ----*/
         if (DMA_UR1T_STA & 0x01)
            {
               COM1_TxCompleteHandler();
            }

    /* 处理 TX 数据覆盖异常 */
    if (DMA_UR1T_STA & 0x04)
       {
          DMA_UR1T_STA &= (unsigned char)~0x04;
       }
    /*---- 处理 DMA RX 缓冲区满(数据接收满)----*/
    if (DMA_UR1R_STA & 0x01)
   {
      DMA_UR1R_STA &= (unsigned char)~0x01;
      COM1_DMA_RxStart();
      }
    /* 处理 RX 数据溢出异常 */
    if (DMA_UR1R_STA & 0x02)
   {
      DMA_UR1R_STA &= (unsigned char)~0x02;
   }
   }


请问,1:DMA 接收,发送中断 ,是发送全部完成了,产生中断,还是发送1个字节,就触发一次中断,同样接收中断是接收到一个字节产生中断,还是接收数组满后产生中断
          2:中断入口地址在大于31后,通过跳转到13中断入口地址,如果有2个以上的中断,地址都大于31,也是用同样方式跳转的13中断入口地址吗,是否会冲突?

狂热主宰 发表于 2026-7-2 23:35:05

使用dma为了传输大量数据
可能没必要频繁中断

狂热主宰 发表于 2026-7-2 23:37:16

中断号大于31的会指定入口
可能之后有判断中断源

_奶咖君_ 发表于 2026-7-2 23:44:00

如果你说的DMA的中断,那么只有接受完成和发送完成你设置的次数的时候,才会触发中断。(不过应该是DMA的发送完成,串口是否发送完成,,这个没有测试过,需要注意一下)

都使用13号中断跳转的时候,需要判断各个中断的标志位,来进行区分是进的哪个中断。。要说有什么问题,,借用13号中断跳转的中断多了之后,可能判断的开销会有一些把。

乘风飞扬 发表于 2026-7-3 09:07:06

13号中断向量没有用到,所以例子都是借用13号中断地址。
除此外,其它所有程序里没有使用的中断向量都可以借用,例如串口1 DMA借用13号中断向量,串口2 DMA借用14号中断向量...
只要做好中断地址跳转映射就行
      CSEG                AT 0193H;UR1T DMA
      LJMP                006BH      ;13号中断地址

      CSEG                AT 01A3H;UR2T DMA
      LJMP                0073H      ;14号中断地址

神农鼎 发表于 2026-7-3 11:06:08


神农鼎 发表于 2026-7-3 11:06:35

<p>好的,我已经完整阅读了该帖子。这是关于 <strong>STC8H8K64U 芯片使用 DMA 控制串口1通信</strong> 的讨论帖。下面为您总结帖子的核心内容及回复:</p>
<hr />
<h2>帖子概要</h2>
<p><strong>标题:</strong> 使用DMA控制串口1通信,数据的发送和接收</p>
<p><strong>楼主(et</strong>*)提出的两个问题:**</p>
<ol>
<li>
<p><strong>DMA 发送/接收中断的触发时机</strong></p>
<ul>
<li>是全部数据发送/接收完成后才产生中断,还是每发送/接收一个字节就触发一次中断?</li>
</ul>
</li>
<li>
<p><strong>多个中断号大于31的中断,都跳转到同一个13号中断入口,是否会冲突?</strong></p>
</li>
</ol>
<hr />
<h2>论坛回复总结</h2>
<h3>问题1:DMA中断触发时机</h3>
<p>据论坛用户 <strong>_奶***</strong> 反馈:</p>
<blockquote>
<p>DMA 的中断,只有<strong>接收完成和发送完成你设置的次数</strong>(即设置的 AMT 长度)时,才会触发中断。不是每发送/接收一个字节就触发一次。</p>
</blockquote>
<p>也就是说:</p>
<ul>
<li>当 <code>DMA_UR1T_AMT = 8</code>,发送完 <strong>8个字节</strong> 后才触发发送完成中断。</li>
<li>当 <code>DMA_UR1R_AMT = 255</code>,接收满 <strong>256个字节</strong>(实际值为 AMT+1)后才触发接收完成中断。</li>
</ul>
<h3>问题2:多个中断借用同一个中断入口</h3>
<p>据论坛用户 <strong>乘风***</strong> 回复:</p>
<blockquote>
<p>13号中断向量没有用到,所以例子都是借用13号中断地址。除此外,其它所有程序里没有使用的中断向量都可以借用,例如串口1 DMA借用13号中断向量,串口2 DMA借用14号中断向量... 只要做好中断地址跳转映射就行。</p>
</blockquote>
<p><strong>不会冲突</strong>,只要每个 DMA 中断映射到<strong>不同的空闲中断向量地址</strong>即可。例如:</p>
<pre><code class="language-asm">      CSEG    AT0193H   ;UR1T DMA
      LJMP    006BH       ;13号中断地址

      CSEG    AT01A3H   ;UR2T DMA
      LJMP    0073H       ;14号中断地址
</code></pre>
<p>然后在对应的中断服务函数中,通过判断 <code>DMA_UR1T_STA</code>、<code>DMA_UR1R_STA</code> 等标志位来区分具体是哪个中断源。</p>
<hr />
<p>如果您需要我进一步查询 <strong>STC8H8K64U 手册中关于 DMA 串口中断的详细说明</strong>,或者需要示例代码的完整解读,请告诉我!</p>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&amp;mod=forum&amp;q=https%3A%2F%2Fwww.stcaimcu.com%2Fthread-24702-1-1.html&amp;f=_all&amp;m=yes&amp;syn=yes&amp;s=relevance&amp;fid=0">🔍 搜索 &quot;https://www.stcaimcu.com/thread-24702-1-1.html&quot;</a></p>
<p>⏱️ 查找用时 2.9s | 总回答用时 9.0s</p>

梁工 发表于 2026-7-3 11:09:19

DMA发送完成,会有DMA发送完成中断,如果允许串口中断,则每发送一个字节,仍然会进入串口发送中断。
同理,DMA接收完成,会有DMA接收完成中断,如果允许串口中断,则每接收一个字节,仍然会进入串口接收中断。

页: [1]
查看完整版本: 使用DMA控制串口1通信,数据的发送和接收