我用了s3c2410外扩了4个串口,用的是tl16c754. s3c2410的D0~D7接754的D0~D7,s3c2410的读使能和写使能分别接754的读使能和写使能。现在遇到的问题是,通过PC机给某一路发送数据,字节数过多时,一般28个字节之后就全是乱码了,不知道怎么解决。
不过,我尝试过,将计算出来的分频值减去1之后再写���DLL和DLM,接收数据正常;或者将PC机的串口调试助手停止位设为2,754接收数据也没问题。但这些毕竟没有彻底解决问题!
另外,发送数据没有问题,754的串口之间发送、接收也没有问题,但就是外部发来的数据不能正确接收
在754端晶体用了3.6864MHz,两个腿接的电容都是22pF,晶体工作正常,也比较稳定。
我用了外部中断,中断方式接收数据。
ChangeClockDivider(1,0); // 1:2:2
ChangeMPllValue(0xa1,0x3,0x3); // FCLK=50.7MHz
// 总线初始化 BANK3
rBWSCON=rBWSCON& (~(0xf<<12))|(0<<12);// |(1<<14)|(1<<15)
rBANKCON3=0x5650;
Port_Init(); // 初始化I/O口
Isr_Init();
/*************** TL16C754中断管脚定义 *****************/
rGPGCON &= ~((3<<0)|(3<<2)|(3<<4)|(3<<6)|(3<<8)|(3<<10)|(3<<12)|(3<<14));
rGPGCON |= ((2<<0)|(2<<2)|(2<<4)|(2<<6)|(2<<8)|(2<<10)|(2<<12)|(2<<14));
//GPG0 ~ 7 set eint8 ~ 15
rEXTINT1 &= (~((7<<0)|(7<<4)|(7<<8)|(7<<12)|(7<<16)|(7<<20)|(7<<24)|(7<<28)));
rEXTINT1 |= ((4<<0)|(4<<4)|(4<<8)|(4<<12)|(4<<16)|(4<<20)|(4<<24)|(4<<28));
//set eint rising edge int
rEINTPEND |= (1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<15); //
rEINTMASK &= ~((1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<15)); //
//enable eint8~15
ClearPending(BIT_EINT8_23);
pISR_EINT8_23 = (U32)Uart_RxInt;
rINTMSK &= ~(BIT_EINT8_23); // 开中断
// rPRIORITY &= ~(3<<9); // 设定中断优先级
/**************** TL16C754复位 **********************/
rGPFDAT &= ~(1<<7);
Delay(100);
rGPFDAT |= (1<<7);
Delay(200);
rGPFDAT &= ~(1<<7);
/**************** TL16C754初始化 **********************/
for( ch=0; ch<8; ch++ )
{
writeb( pEXT_COM_BASE_ADDR[ch]+LCR, 0x80 ); // when LCR b7 is 1, DLL & DLH are accessed
writeb( pEXT_COM_BASE_ADDR[ch]+DLH, (BaudRateTab[3]>>8)&0x00ff );
writeb( pEXT_COM_BASE_ADDR[ch]+DLL, BaudRateTab[3]&0x00ff );
writeb( pEXT_COM_BASE_ADDR[ch]+LCR, 0x03 ); // 8-bits 1-stop no-parity
writeb( pEXT_COM_BASE_ADDR[ch]+FCR, 0xc7 ); // c7
writeb( pEXT_COM_BASE_ADDR[ch]+IER, 0x01 ); //0x01 enable receive interrupt
writeb( pEXT_COM_BASE_ADDR[ch]+IIR, 0x01 );
writeb( pEXT_COM_BASE_ADDR[ch]+MCR, 0x00 ); // 08
Delay(1);
}
while(1)
{
if( (NumOfUartRxInt>0)&&(NumOfUartRxInt<9) )
{
temp = readb( pEXT_COM_BASE_ADDR[(NumOfUartRxInt-1)]+IIR );
temp = temp&0x3f;
if( (temp==0x0c)||(temp==0x04) )
{
temp1 = readb( pEXT_COM_BASE_ADDR[(NumOfUartRxInt-1)]+LSR );
// if( temp1&0x1)
{
RecData = readb( pEXT_COM_BASE_ADDR[(NumOfUartRxInt-1)]+RHR );
writeb( pEXT_COM_BASE_ADDR[(NumOfUartRxInt-1)]+THR, RecData );
NumOfUartRxInt = 0;
RecData = 0;
}
}
}
}
|