整个系统的工作模式是做一个通信中转,将一个串口接收到的数据从另一个串口发送出去。<br /> 现遇到以下问题:单向的时候,即一个串口收,一个串口发时还是比较稳定地<br /> 当工作在全双工时,时间一长就会出问题,其中一个串口会接收不到数据<br /> 请问:中断处理上,和初始化上有什么需要注意的?<br /> 两个串口的程序差不多, <br /><br />*/<br />/*<br />* 初始串口0<br />*/<br />void Usart0_init(void)<br />{<br /> extern AT91S_PIO * pPIO ;<br /> <br /> unsigned long statu;<br /><br /> Com0RecBLengA = 0 ; <br /> Com0RecBLengB = 0 ; <br /> Com0RecOK = 0 ;<br /> <br /> /* Disable all interrupt */<br /> pPIO->PIO_ASR = AT91C_PA5_RXD0|AT91C_PA6_TXD0; /* set rxd txd pin contral by pers A */<br /> pPIO->PIO_BSR = 0 ; <br /> pPIO->PIO_PDR = AT91C_PA5_RXD0|AT91C_PA6_TXD0; /* Disable RXD and TXD pin controler by PIO */<br /> AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0); /* enable the clock of the PIOA */<br /><br /> AT91C_BASE_US0->US_IDR = 0xf3fff; <br /> /* reset receive and transmitter, disable receive and transmitter */<br /> AT91C_BASE_US0->US_CR = AT91C_US_RSTRX|AT91C_US_RSTTX|AT91C_US_RXDIS|AT91C_US_TXDIS ;<br /> <br /> AT91C_BASE_US0->US_RCR = 0 ; /* clear receive counter */<br /> <br /> AT91C_BASE_US0->US_TCR = 0 ; /* clear transmit counter */<br /> <br /> AT91C_BASE_US0->US_BRGR = AT91F_US_Baudrate(SYS_MCK, 57600) ; /* Define the baud rate divisor register */<br /><br /> /* Define the USART mode SYNC = 0 OVER = 0 baud = mck/div/16/BRGR */<br /> AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL /* normal */<br /> |AT91C_US_CLKS_CLOCK /* mck/div */<br /> |AT91C_US_CHRL_8_BITS /* 8 bit */<br /> |AT91C_US_PAR_EVEN /* EVEN 奇检验 */<br /> |AT91C_US_NBSTOP_1_BIT ; /* one stop bit */<br /><br /> <br /> AT91C_BASE_US0->US_TTGR = 0 ; /* Write the Timeguard Register */<br /><br /> //* Enable receiver and transmitter<br /> AT91C_BASE_US0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN ;<br /> AT91C_BASE_US0->US_RTOR= 0 ;<br /><br /> AT91C_BASE_US0->US_PTCR = AT91C_PDC_RXTDIS ;<br /> AT91C_BASE_US0->US_PTCR = AT91C_PDC_TXTDIS ;<br /> AT91C_BASE_US0->US_TNPR = 0 ;<br /> AT91C_BASE_US0->US_TNCR = 0 ;<br /> AT91C_BASE_US0->US_RNPR = 0 ;<br /> AT91C_BASE_US0->US_RNCR = 0 ;<br /> AT91C_BASE_US0->US_TPR = 0 ;<br /> AT91C_BASE_US0->US_TCR = 0 ;<br /> AT91C_BASE_US0->US_RPR = (unsigned int)Com0RecBufA ;<br /> Com0RecBufDex = 0 ;<br /> AT91C_BASE_US0->US_RCR = COM0_REC_BUFFER_LENGTH ;<br /> AT91C_BASE_US0->US_RTOR = 10 ;<br /> AT91C_BASE_US0->US_PTCR = AT91C_PDC_RXTEN ;<br /> AT91C_BASE_US0->US_PTCR = AT91C_PDC_TXTEN ;<br /><br /> /* USART IRQ open */<br /> /* Global UART Interrupt: Mode and Vector with Highest Priority and Enable */<br /> AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_US0); // enable interrupt<br /> AT91C_BASE_AIC->AIC_SMR[AT91C_ID_US0] = AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED |<br /> AT91C_AIC_PRIOR_HIGHEST;<br /> AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0] = (unsigned long) USART0_ISR;<br /> AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_US0); // enable interrupt<br /> AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_US0); // clear interrupt<br /><br /> statu = AT91C_BASE_AIC->AIC_IMR ;<br /> statu = AT91C_BASE_AIC->AIC_IPR ;<br /><br /> AT91C_BASE_US0->US_IER=AT91C_US_TIMEOUT|AT91C_US_RXBUFF;<br /> statu = AT91C_BASE_US0->US_IMR;<br /> <br />}<br /><br />int Usart0_send_frame (unsigned char * pbuffer, short bufsize )<br />{<br /> while((pUART0->US_CSR & US_ENDTX ) == 0) ; /* Wait for previous transfer finished */<br /> pUART0->US_TPR = (unsigned int)pbuffer ; /* Store the address of the buffer */<br /> pUART0->US_TCR = bufsize ;<br /> return TRUE ;<br />}<br /><br /><br />void USART0_Handler(void)<br />{<br /> unsigned long statu,length; <br /><br />// *AT91C_AIC_EOICR = 0; /* End of Interrupt */<br /> statu = pUART0->US_CSR ; /* get the channel status */<br /><br /> length = pUART0->US_RCR ;<br /> if ( statu & (AT91C_US_TIMEOUT|AT91C_US_RXBUFF))<br /> {<br /> if(Com0RecBufDex == 0)<br /> {<br /> Com0RecBufDex = 1;<br /> pUART0->US_RPR = (unsigned int) Com0RecBufB;<br /> pUART0->US_RCR = COM0_REC_BUFFER_LENGTH;<br /> Com0RecBLengA = COM0_REC_BUFFER_LENGTH - length ;<br /> Com0RecOK = 1 ;<br /> }<br /> else<br /> {<br /> Com0RecBufDex = 0;<br /> pUART0->US_RPR = (unsigned int) Com0RecBufA;<br /> pUART0->US_RCR = COM0_REC_BUFFER_LENGTH;<br /> Com0RecBLengB = COM0_REC_BUFFER_LENGTH - length ;<br /> Com0RecOK = 1 ;<br /> } <br /> pUART0->US_CR = AT91C_US_STTTO;<br /> }<br /> <br /> pUART0->US_CR = AT91C_US_RSTSTA;<br />}<br /><br /><br />USART0_ISR<br /><br /> sub r14, r14, #4<br /> stmfd sp!, {r14}<br /> mrs r14, spsr<br /> stmfd sp!, {r0,r14} <br /> mrs r14, cpsr<br /> bic r14, r14, #I_Bit<br /> orr r14, r14, #Mode_SVC<br /> msr cpsr_cxsf, r14<br /> stmfd sp!, { r0-r12, r14}<br /> bl USART0_Handler <br /> ldmia sp!, { r0-r12, r14} <br /> mrs r0, cpsr<br /> bic r0, r0, #Mode_SVC<br /> orr r0, r0, #I_Bit:OR:Mode_IRQ<br /> msr cpsr_cxsf, r0<br /> ldr r0, =AIC_BASE<br /> str r0, [r0, #AIC_EOICR]<br /> ldmia sp!, {r0,r14}<br /> msr spsr_cxsf, r14<br /> ldmia sp!, {pc}^
|