mengxuan1303 发表于 2023-10-18 15:05:25

关于寄存器DMA_UR1R_DONE的应用问题

本帖最后由 mengxuan1303 于 2023-10-18 15:20 编辑

准备用串口溢出寄存器进行接收串口数据,方案为:发现溢出读取接收完成寄存器DMA_UR1R_DONE的数据长度,如果没有则清除溢出标记,知道溢出标记和接收完成寄存器同时出现,然后获得串口的DMA数据。调试过程中发现DMA_UR1R_DONE是累计接收数据长度,并且清除不掉,请问他是只读的么?有什么方式在我接收完数据后进行给他清零?


      if(DMA_UR1R_DONE == 0)UR1TOSR &= 0xFE;
      else
      {
                if((UR1TOSR & 0x01) == 0x01)
                {
                        
                        gbR_Len = DMA_UR1R_DONE;
                        for(bI = 0;bI<gbR_Len;bI++)gbpRx = gbpR_Buff;
                        gwMsg |= MSG_UR1R;
                        DMA_UR1R_DONE = 0;
                        DMA_UR1R_DONEH = 0;
                        DMA_UR1R_CR = 0xA1;
                        SBUF = gbR_Len;   //调试用,发现DMA_UR1R_DONE没有被清零,每次电脑端发送数据后,这个数据进行累加。
                }
      }

这是定时器中截取的一小段。

zhp 发表于 2023-10-18 16:39:43

本帖最后由 zhp 于 2023-10-18 16:41 编辑

DMA_UR1R_DONE是只读寄存器
任何时候将DMA_UR1R_CR寄存器的最高位(ENUR1R)位写零,
就可以对DMA_UR1R_DONE进行清零

代码可以这样写:
                        gbR_Len = DMA_UR1R_DONE;
                        for(bI = 0;bI<gbR_Len;bI++)gbpRx = gbpR_Buff;
                        gwMsg |= MSG_UR1R;
                        DMA_UR1R_CR = 0x00;
                        DMA_UR1R_CR = 0xA1;
                        SBUF = gbR_Len;   //调试用,发现DMA_UR1R_DONE没有被清零,每次电脑端发送数据后,这个数据进行累加。

王昱顺 发表于 2023-10-18 16:46:22

这个接受数据长度按道理来讲应该就是只读的。
如果想要清除接收数据长度,可以清除一次状态寄存器后重新开始接收,并且通过置位DMA_UR1R_CR的bit0,在操作前清空fifo。


其他建议:
==接受定长数据可以直接设置指定长度后启动完成中断
==不定长度可以讲接受长度设定为0xffff,然后通过两个位之间的时间判断是否发完了一个包。

mengxuan1303 发表于 2023-10-19 08:19:34

zhp 发表于 2023-10-18 16:39
DMA_UR1R_DONE是只读寄存器
任何时候将DMA_UR1R_CR寄存器的最高位(ENUR1R)位写零,
就可以对DMA_UR1R_DON ...

谢谢!验证过了,好用。

mengxuan1303 发表于 2023-10-19 08:22:35

王昱顺 发表于 2023-10-18 16:46
这个接受数据长度按道理来讲应该就是只读的。
如果想要清除接收数据长度,可以清除一次状态寄存器后重新开 ...

谢谢,不定长数据,最简单的办法还是利用好接收长度寄存器,和超时溢出寄存器,充分利用硬件资源。
页: [1]
查看完整版本: 关于寄存器DMA_UR1R_DONE的应用问题