【问题标题】:UART write buffer with PDC带 PDC 的 UART 写缓冲器
【发布时间】:2014-10-30 02:41:26
【问题描述】:

我在使用 const char 缓冲区和 char 数组写入 USART 时遇到问题。

这是我的UART写函数:

unsigned int USART_Send(  unsigned char *p_pucData, 
                              unsigned int p_unLen)
{


  AT91C_BASE_US2->US_TPR = (unsigned int)p_pucData;
  AT91C_BASE_US2->US_TCR =  p_unLen;
  AT91C_BASE_US2->US_PTCR = AT91C_PDC_TXTEN;


  while((AT91C_BASE_US2->US_CSR & ((0x1 << 11) | (0x1 << 4) ) ) == 0);

   AT91C_BASE_US2->US_PTCR = AT91C_PDC_TXTDIS;

    return p_unLen;    
}

下面的函数使用 const char* 像:

USART_Send("IsitDone?",9);   //Working

如果我使用像下面这样的数组缓冲区,它会显示垃圾字符,不知道为什么?

 unsigned char arr[10];
  memcpy(arr, "HelloWorld", 10);
  USART_Send(arr, sizeof(arr));  //Not working properly displaying Garbage chars

【问题讨论】:

  • 哪个处理器,哪个UART,哪个波特率?等等等等
  • 顺便说一句,0x011 更难阅读。
  • 在 ATMEL AT91SAM9M10 控制器上,UART2 和波特率为 115200
  • 看起来像内存缓存问题。在 memcpy 之后插入缓存写回指令。
  • 我认为可能发生的情况是您正在调用 UART_Send 传递一个局部变量,因此在发送数据之前的任何时刻(这可能需要一些时间取决于波特率),这个内存可以在其他情况下使用。

标签: c microcontroller usart


【解决方案1】:

里卡多克鲁多是正确的。您遇到以下问题:

arr is created on the stack
arr is filled
call USART_Send
    fill transmit pointer, counter, enable tx requests
    /* peripheral state is TXBUFE = '0' and ENDTX = '0' because:           */
    /* TXBUFE = '0' when PERIPH_TCR != 0 and                               */
    /* ENDTX = '0' when PERIPH_TCR != 0                                    */
    /* but we just wrote to PERIPH_TCR, so it's != 0                       */
    /* both conditions are satisfied, b/c the transfer hasn't started yet! */
    wait until (TXBUFE = '0' and ENDTX = '0')
    /* your code thinks PDC is done here      */
    /* but in reality, PDC is getting started */
    disable tx requests
return from sub-function
overwrite stack (and arr) with unrelated data here
/* PDC might push out last word(s) here due to pipelining/        */
/* instruction cache/side effects/you-name-it                     */
/* even though its matrix requests were disabled a few cycles ago */

解决方案:

  • 复制到全局缓冲区
  • 在启用 tx 请求和检查 PDC 是否完成之间等待一些周期(可能是整个波特tick
  • 读回 PERIPH_TCR 并检查它是否为零而不是检查标志

理想情况下,您应该为字符串分配一些动态内存,并在 PDC 与您的实际代码异步完成后释放它。您可能想检查在 PDC/外设完成后是否可以获得某种中断,然后释放它读取的内存。

如果您没有动态内存分配,则使用全局环形缓冲区并将您的字符串/字符发送函数抽象为使用此缓冲区。

【讨论】:

    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2021-06-16
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    相关资源
    最近更新 更多