最近我在做一个项目遇到一个串口异常问题,我用电脑连接的时候,串口通讯时间间隔10ms都是没有问题,最多出现乱码,因为是用485,乱码比较正常,停止10ms发送切换50ms能返回正常的数据。但是我多个单片机通讯的时候,总会有单片机串口崩溃现象,其他操作正常,就是串口没有数据反馈。在串口中断做了帧错误和溢出错误的处理。串口初始化代码
void uart_init(UINT8 brg)
{
TX2STA &= ~(0x01 << 4); //异步串口
//SYNC = 0; //异步串口
if(BRG_9600 == brg)
{
TX2STA &= ~(0x01 << 2); //低速波特率
//BRGH = 0; //低速波特率
BAUD2CON &= ~(0x01 << 3); //使用8位波特率发生器
//BRG16 = 0; //使用8位波特率发生器
SP2BRGL = 51;//9600波特率
}
else if(BRG_115200 == brg)
{
TX2STA |= (0x01 << 2); //高速波特率
//BRGH = 1; //高速波特率
BAUD2CON |= (0x01 << 3); //使用16位波特率发生器
//BRG16 = 1; //使用16位波特率发生器
SP2BRGL = 68;//115200波特率
SP2BRGH = 0;
}
else
{
TX2STA &= ~(0x01 << 2); //低速波特率
BAUD2CON &= ~(0x01 << 3); //使用8位波特率发生器
SP2BRGL = 51;//9600波特率
}
TRISG1 = 0; //IO配置 TX2
TRISG2 = 1; //IO配置 RX2
ANSG2 = 0; //必配
RC2STA |= (0x01 << 7); //使能串口
//SPEN = 1; //使能串口
TX2STA &= ~(0x01 << 6); //发送8位数据位
//TX9 = 0; //发送8位数据位
//CKTXP = 0; //发送数据极性 不翻转
RC2STA &= ~(0x01 << 6); //接收8位数据位
//RX9 = 0; //接收8位数据位
RC2STA |= (0x01 << 4); //使能接收
//CREN = 1; //使能接收
//RC2IF = 0;
RC2IE = 1; //接收使能
//PIE4 |= (0x01 << 5);
//INTCON |= (0x03 << 6);
RC2STAbits.CREN=1;//激活接收
PEIE = 1; //外设中断使能
GIE = 1; //总中断使能
//RC2STA &= ~(0x01 << 4); //使能接收
//RC2STA &= ~(0x01 << 7); //使能串口
//RC2STA |= (0x01 << 4); //使能接收
//RC2STA |= (0x01 << 7); //使能串口
}
复制代码
串口中断:
if (RC2IE && RC2IF)
{
// backlight_Dim(3);
// RC2IF = 0;
if(RC2STAbits.FERR)//监测是否有帧错误
{
err=RC2REG;
return;
}
if(RC2STAbits.OERR)
{
RC2STAbits.CREN=0;
RC2STAbits.CREN=1; //接收模块被复位重置,OERR清零
return;
}
//err = RC2STA & 0x04;
//err = FERR;
//RC2IF = 0;
ch = RC2REG;
if(RC2IF)
{
RC2IF = 0;
}
if(Ccnt > 25)
{
Ccnt = 0;
return;
}
if(ch == SOI0)
{
Ccnt = 0;
SOI_Flag = 1;
return;
}
if(SOI_Flag == 1) //检测是否是包头
{
SOI_Flag = 0;
if(ch == SOI1)
{
Recstatu = 1;
Ccnt = 0;
PackerFlag = 0;
return;
}
else
{
if(Recstatu == 1) //是否处于接收数据包状态
{
RxBuf[Ccnt++] = SOI0;
}
}
}
if(ch == EOI0)
{
EOI_Flag = 1;
return;
}
if(EOI_Flag == 1) //检测是否是包头
{
EOI_Flag = 0;
if(ch == EOI1) //检测是否是包尾
{
Recstatu = 0;
PackerFlag = 1; //用于告知系统已经接收到一个完整的数据包
GIE = 0;
return ;
}
else
{
if(Recstatu == 1) //是否处于接收数据包状态
{
RxBuf[Ccnt++] = EOI0;
}
}
}
if(Ccnt > 25)
{
Ccnt = 0;
return;
}
if(Recstatu == 1) //是否处于接收数据包状态
{
RxBuf[Ccnt++] = ch;
}
}
复制代码 |