共2条
1/1 1 跳转至页
AT91SAM7S64,PDC,quot,DATA,ABORT,quot AT91SAM7S64串口PDC报"DATA ABORT"故障
问
现在我在应用串口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通道将指令流打断造成程序的混乱。
现在我在应用串口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 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |