This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123AH6PM:没有原因触发 UART 中断?

Guru**** 2387730 points
Other Parts Discussed in Thread: TM4C123AH6PM, TM4C129ENCPDT
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/662131/tm4c123ah6pm-uart-interrupt-triggered-for-no-reason

器件型号:TM4C123AH6PM
主题中讨论的其他器件: TM4C129ENCPDTTM4C123

我们的 UART ISR 会被触发、但当我们调用时:

//了解触发中断的原因
UINT32_t 状态= MAP_UARTIntStatus (UART6_BASE、1); 

调试器显示状态为0。

为什么触发中断?

我们正在与 DMA 进行 UART 通信、并尝试接收一个8字节的块。 我们期望中断使用 UART_INT_DMARX 触发、并设置指示 DMA 已完成的标志。 相反、状态为0、我们从不对接收到的数据执行操作。

UART 和 DMA 初始化:
















到#if defined (ewarm)#pragma DATA_ALIGNing=1024 uint8_t DmaControlTable[1024];#Elif Defined (CCS)#pragma DATA_ALIGN (DmaControlTable、1024) uint8_t DmaControlTable[1024];#else uint8_t DmaCtlDmaControlTable[1024](Dma_attl)#pragma DATA_aligned (dma_uint_u_t
);在 dma

(Uta_sys_delt_eUST_dma_eDt_dma (Utl)期间启用)中断(Ut_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma


//指向控制表以用于通道控制结构
map_uDMAControlBaseSet (DmaControlTable);

MAP_SysCtlPeripheralDisable (SYSCTL_Periph_UART6);
MAP_SysCtlPeripheralReset (SYSCTL_Periph_UART6);
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_UART6);
while (MAP_SysCtlPeripheralReady (SYSCTL_Periph_UART4_UART6_UART6*


));GPTOP_TOP_UART4_UART4_RETP_UART6_UART4_RETP_UART4_RE_TRUART6_TRUTOP= UTP_TOP_ IN_TOP_ UART_UART4_RE_TOP_ UART4_RE_TOP_ UART_UARTHREST_UART_UARTHREST_UARTHREST_UARTHREST_UART_UART_UAR




global.SysClockFreqHz、u->Baud、(UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE | UART_CONFIG_WLEN_8);

//将 UART Tx 和 Rx FIFO 触发阈值设置为4
MAP_UARTFIFOEnable (UART6_BASE);MAP_UART6_UART4_UART6_UART6_DRQ_TX_RTO_RTO_R0_RTO_RTO_RTO_RTO_R0_RTO_RTO_RTO_R0_R0_RTO_RTO_UART8/ UART6UART6_UART8_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO_RTO









//确保不需要的 Rx 通道 DMA 属性为 map_uDMAChannelAttributeDisable (
UDMA_CH10_UART6RX、UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIOR| UDMA_ATTR_REQMASK)之外;

//设置

源结构/数据大小- 0 始终指向 UART Rx 数据寄存
器//-目标地址增量为字节(8位)
//-仲裁大小为4以匹配 UART Rx FIFO 触发阈
值//-如果可能,DMA 将使用4字节突发传输来实现效率
MAP_uDMAChannelControlSet (
UDMA_CH10_UART6RX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4
);

//确保不需要的 Tx 通道 DMA 属性为 MAP_uDMAChannelAttributeDisable (
UDMA_CH11_UART6TX、UDMA_ATTR_ALTSEL| UDMA_TR_PRIOR/

启用 UDMA_TR_TR_TR_TR_USTR/从 UARTK_TR_TR_TR_TR_TRF/高优先级
传输时启用 UDMA_TR_TR_TR_TR_URTDMA_TR_TR_TR_TR_TRF/以启用 UARTDMA_TR
MAP_uDMAChannelAttributeEnable (UDMA_CH11_UART6TX、UDMA_ATTR_USEBURST);

//设置 Tx DMA 主控制结构:
//-数据大小8位
//-源地址增量为字节(8位)
//-目标地址不递增; 始终指向 UART Tx 数据寄存
器//-仲裁大小为4以匹配 UART Tx FIFO 触发阈值
MAP_uDMAChannelControlSet (
UDMA_CH11_UART6TX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UART_MAP_4
);

启用 UART6中断/ INT_INT_MASTER

开始接收数据块:

//设置 Rx DMA 主控结构传输参数:
//-模式设置为基本(不是乒乓)。
//-源是 UART 数据寄存器
//-目标是接收存储器缓冲
区//-传输大小设置为与缓冲区大小匹配
//
map_uDMAChannelTransferSet (
UDMA_CH10_UART6RX | UDMA_PRI_SELECT、
UDMA_MODE_BASIC、
(void *)(UART6_BASE + UART_O_BuxFDR


、UARTxBuf)

//启用通道,因为它在每次传输完成时被禁用
MAP_uDMAChannelEnable (UDMA_CH10_UART6RX);

//启用 DMA Rx 中断
MAP_UARTDMAEnable (UART6_BASE、UART_DMA_RX);
MAP_UARTIntEnable (UART6_BASE、UART_INT_DMARX); 

中断:

void IsrUart6Handler (void)
{
uint32_t Status;

//找出触发中断的原因
Status = MAP_UARTIntStatus (UART6_BASE、TRUE);

//清除暂挂状态
MAP_UARTIntClear (UART6_BASE、Status);

if (Status & UART_INT_DMARX){
RxDONE = UART6_BASE


;UART6_UART6_BASE = UARTDAT_DAT_UART6_UART6_UARTMCUART_UART_UART6_BASE;UART0_UART6_UART6_UART6_

}

当我们在调试器中检查未屏蔽的 UART 中断状态时、它是0xF;这些置位中的三个位被保留、一个是我们未使用的 CTSRIS。 屏蔽后的中断状态为0。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否曾尝试防止(任何)不需要的)信号在加电后到达 UART 引脚?

    作为一个" kiss 的粉丝"(怀疑您的(临时)绕过 µDMA)将更好地理解 UART 的各种中断机制以及其他行为。 只有这样,我才会恢复 n ü µDMA,并且具有进一步的 UART 知识,即您的问题发生在“何时/何地”的可能性应该更好地揭示。 (有一个希望)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="CB1_MOBIST"]加电后、您是否曾尝试防止(任何)不需要的)信号到达 UART 引脚?

    作为一个" kiss 的粉丝"(怀疑您的(临时)绕过 µDMA)将更好地理解 UART 的各种中断机制以及其他行为。 只有这样,我才会恢复 n ü µDMA,并且具有进一步的 UART 知识,即您的问题发生在“何时/何地”的可能性应该更好地揭示。 (有一个希望)

    [/报价]

    我们需要进行大量的进一步研究和拔头发来弄清这里发生了什么,但我们已经找到了它的底部。

    我们有两种不同的模型、一种在 TM4C129ENCPDT 上运行、另一种在 TM4C123AH6PM 上运行。 这些器件非常相似、但略有不同。

    具体而言、代码如何检测 UART (Tx 或 Rx FIFO)与存储器之间 DMA 传输的完成情况有所不同。

    在 TM4C129ENCPDT (可能还有很多其他器件)中、DMA 会向 UART 发送 DMA_DONE 信号、UART 会在 UARTRIS / UARTMIS 中将其 DMARXRIS 和/或 DMATXRIS 中断标志置为有效。 这可以通过调用 UARTIntStatus()并查找 UART_INT_DMARX 和/或 UART_INT_DMATX 来在中断处理程序中读取。

    在 TM4C123AH6PM (同样、也可能是许多其他器件)中、UART 的 UARTRIS / UARTMIS 中不存在这两个位。 它们在数据表中被标记为"保留"。 相反、DMA 外设置位其 DMACHIS 寄存器中的位并触发 UART 的中断。 在这种情况下,UARTIntStatus()不会显示 UART_INT_DMARX 和/或 UART_INT_DMATX 的任何内容,因为它们不存在。 这解释了为什么我们的 UART 中断似乎"没有理由"被触发。 除了调用 UARTIntStatus()(和 UARTIntClear ())并处理器件中确实存在的任何位之外,软件还必须调用 uDMAIntStatus()(和 uDMAIntClear ()),并通过检查与所用通道相对应的位来检查 DMA 传输是否完成。

    由于我们为两个平台编译相同的代码、因此我们实施了代码来处理 UART 中断处理程序中的这种差异:

    binttxDone = false;
    bool RxDone = false;
    
    #if define(part_TM4C129ENCPDT)
    {
    uint32_t UartIsrStatus = MAP_UARTIntStatus (u->Base、true);
    
    if (UartIsrStatus & UART_INT_DMATX){uart_UARTxIntStatus = MAP_UART32_UART_UARTx
    
    
    
    
    (uart_UARTxTS=
    
    true)
    
    
    
    
    
    ;UART32_UARTxTS_UART_PRU = UART_UARTxTS= UART_PRU = UART_UART32+ UART32_TRUART_UART_PRD (UART_UART_UART_UART_UART_PRU);UART_UARTxINT_UART_PRU = UART_UART_UART_UART_PRU = UART_UART_PRU)
    
    MASK =(1 <<(u->TxDmaCh & 0xF));
    IF (DmaStatus & Mask){
    MAP_uDMAIntClear (Mask);
    TxDone = true;
    }
    
    Mask =(1 <<(u->RxDmaCh & 0xF)));
    IF (DmaStatus & Mask){
    MAP_uDMAIntClear = true;
    
    
    
    
    }正在检查#RxDDMA 传输完成情况;不检查#RxDnone!
    #endif
    
    (TxDone){
    //处理 Tx 完成
    //。
    //。
    //.
    }
    
    if (RxDone){
    //处理 Rx 完成
    //。
    //。
    //.
    }
    

    
    

    代码注释:u->Base 映射到 TivaWare driverlib 中的 UARTn_BASE 定义之一(在本例中为 UART6_BASE)。  u->RxDmaCh 映射到 TivaWare driverlib 中 UDMA_CHt_UARTnRX 定义的其中一个(在本例中为 UDMA_CH10_UART6RX)。  u->TxDmaCh 映射到 TivaWare driverlib 中的 UDMA_CHt_UARTnTX 定义之一(本例中为 UDMA_CH11_UART6TX)。

    我们的实施方案的这一方面尚未完成(这是一种很好的说法、即通信尚未稳定运行)、希望我们不会发现这两个器件之间的其他细微差异、从而使事情变得混乱。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、12月12日下午、

    Amit 过去在 E2E 论坛上分享了以下内容。 您能看到这是否适用于您的案例吗?

    "TM4C123中的 DMA 具有相当复杂的机制。 外设完成的 DMA 和中断在外设中断上触发。 当中断处理程序被调用时、CPU 必须检查外设和 UDMACHIS 的中断状态位来找出中断原因。 如果 uDMACHIS 被置位、那么它必须被清零。"

    您的代码看起来只检查外设状态位、所以请查看 UDMACHIS 是否是您未知中断的原因。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您解释并指出 Amit 对该问题的评论。 在我的上一篇文章(上面)中、我发现了 UDMACHIS、并展示了我们用于处理 TM4C123和 TM4C129之间差异的代码。

    由于这些器件在许多方面都非常相似、因此细微的差异可能会令人困惑、并带来惊喜。