这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » AT91SAM7S64,PDC,quot,DATA,ABORT,quot AT9

共2条 1/1 1 跳转至

AT91SAM7S64,PDC,quot,DATA,ABORT,quot AT91SAM7S64串口PDC报"DATA ABORT"故障

院士
2006-09-17 18:14:16     打赏
AT91SAM7S64,PDC,quot,DATA,ABORT,quot AT91SAM7S64串口PDC报"DATA ABORT"故障



关键词: AT91SAM7S64     ABORT     串口     故障    

院士
2006-12-22 22:43:00     打赏
2楼

    现在我在应用串口1的PDC时发现串口通讯会造成程序产生"Data abort"故障。
    一般通讯1分钟内就会出现一次"Data abort"故障。
    由于初次使用,目前尚未查出问题。请两位帮忙看看代码有无疏漏。
    谢谢!
    代码如下:

// 中断服务部分
void serial1_handler(void)
{
    unsigned int status;
    unsigned short txd_len;
    AT91S_PDC *pUSART1_PDC = (AT91S_PDC *)&(pUSART1->US_RPR);

    // get Usart status register
    status = pUSART1->US_CSR;

    if ( status & AT91C_US_ENDTX)
    {
        // 发送结束,使能接收
        // Clear ENDTX flag, PDC_TCR写大于1的值能清除ENDTX标志
        pUSART1_PDC->PDC_PTCR = AT91C_PDC_TXTDIS;     
        pUSART1_PDC->PDC_TCR = 2;                        
        // Open UART1 PDC-RX,各寄存器赋值
        pUSART1->US_CR = AT91C_US_STTTO;    // Start Time-out
        pUSART1_PDC->PDC_PTCR = AT91C_PDC_RXTDIS;// Disable PDC-Rx
        pUSART1_PDC->PDC_RPR = (unsigned int)uart1_RxBuff;          
        pUSART1_PDC->PDC_RCR = USART1_RxBuf_LEN;
        pUSART1_PDC->PDC_RNPR = 0;            
        pUSART1_PDC->PDC_RNCR = 0;            
        pUSART1_PDC->PDC_PTCR = AT91C_PDC_RXTEN;// Enable PDC-Rx

    }

    if ( status & AT91C_US_TIMEOUT)
    {    
        // 关闭接收
        pUSART1->US_PTCR = AT91C_PDC_RXTDIS;        

        // 处理数据
        txd_len = ModbusPrs();

        if (txd_len >= MD_MIN_TX_LEN)
        {
            pUSART1_PDC->PDC_TPR = (unsigned int) uart1_TxBuff;
            pUSART1_PDC->PDC_TCR = txd_len;
            pUSART1_PDC->PDC_RNPR = 0;            
            pUSART1_PDC->PDC_RNCR = 0;            
            pUSART1_PDC->PDC_PTCR = AT91C_PDC_TXTEN;// Enable PDC-Tx
        }
        else
        {
            // Open UART1 PDC-RX
            pUSART1->US_CR = AT91C_US_STTTO;    // Start Time-out
            pUSART1_PDC->PDC_PTCR = AT91C_PDC_RXTDIS;
            pUSART1_PDC->PDC_RPR = (unsigned int)uart1_RxBuff;
            pUSART1_PDC->PDC_RCR = USART1_RxBuf_LEN;
            pUSART1_PDC->PDC_RNPR = 0;        
            pUSART1_PDC->PDC_RNCR = 0;                   // Receive Next Counter Register
               pUSART1->US_PTCR = AT91C_PDC_RXTEN;
        }
    }    
    
    pUSART1->US_CR = AT91C_US_STTTO |      // Start Time-out
                    AT91C_US_RSTSTA;          // Reset the status bit

}

// USART1初始化部分
//==================================================================
void init_serial1 (void)                                // Initialize Serial Interface
{
    AT91S_AIC *pAIC = AT91C_BASE_AIC;
    AT91S_PDC *pUSART1_PDC = (AT91S_PDC *)&(pUSART1->US_RPR;   
   *AT91C_PIOA_PDR = AT91C_PA21_RXD1 |                // Enable RxD1 Pin
                                        AT91C_PA22_TXD1 |                 // Enalbe TxD1 Pin
                                        AT91C_PA24_RTS1;                 // Enalbe RTS1 Pin

    pUSART1->US_CR = AT91C_US_RSTRX |                  // Reset Receiver
                    AT91C_US_RSTTX |                  // Reset Transmitter
                    AT91C_US_RXDIS |                 // Receiver Disable
                     AT91C_US_TXDIS;                  // Transmitter Disable

    pUSART1->US_MR = AT91C_US_OVER |                // Over Sampling Mode
                    AT91C_US_USMODE_RS485 |          // RS485 Mode
                      AT91C_US_CLKS_CLOCK |              // Clock = MCK
                      AT91C_US_CHRL_8_BITS |          // 8-bit Data
                      AT91C_US_PAR_NONE |              // No Parity
                      AT91C_US_NBSTOP_1_BIT;            // 1 Stop Bit

    pUSART1->US_BRGR = BRD1;                           // Baud Rate Divisor

    pUSART1->US_RTOR = FRAMEOVERTIME;                // Set Time-out Value

      pUSART1->US_CR = AT91C_US_RXEN |                  // Receiver Enable
                                        AT91C_US_TXEN |                    // Transmitter Enable
                                        AT91C_US_STTTO |                // Start Time-out
                                        AT91C_US_RSTSTA;                // Reset the status bit

    // Clear ENDTX flag, PDC_TCR写大于1的值能清除ENDTX标志
    pUSART1_PDC->PDC_PTCR = AT91C_PDC_TXTDIS;// Disable PDC-Tx
    pUSART1_PDC->PDC_TCR = 2;                  // Transmit Counter Register

    // Configure UART1 interrupt source
    pUSART1->US_IER = AT91C_US_TIMEOUT |     // Time-out of receive a frame
                        AT91C_US_ENDTX;                // Transmitter is Free
   
    // Open UART1 interrupt
    pAIC->AIC_SMR[AT91C_ID_US1] =                      AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE |
                          USART_INTERRUPT_LEVEL;
    pAIC->AIC_SVR[AT91C_ID_US1] = (unsigned long) serial1_handler;

    pAIC->AIC_IECR = (1 << AT91C_ID_US1); // uart1 Interrupt Enable

    // Open UART1 PDC-RX
    pUSART1_PDC->PDC_PTCR = AT91C_PDC_RXTDIS |        // Disable PDC-Rx
                                                    AT91C_PDC_TXTDIS;        // Disable PDC-Tx
    pUSART1_PDC->PDC_RPR = (unsigned int)uart1_RxBuff;    
    pUSART1_PDC->PDC_RCR = USART1_RxBuf_LEN;
    pUSART1_PDC->PDC_RNPR = 0;           // Receive Next Pointer Register
    pUSART1_PDC->PDC_RNCR = 0;              // Receive Next Counter Register
    pUSART1_PDC->PDC_PTCR = AT91C_PDC_RXTEN;// Enable PDC-Rx

}
1: 使用pdc要注意:在使能相应的pdc后最好等一等,什么都别干。仿制dma通道将指令流打断造成程序的混乱。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]