双串口通讯测试,使用IAP15W4K58S,串口1用232,串口3用RS485,均采用中断接收方式,问题是:
1、 串口1能收到串口助手发送的多字节数据并返回显示,串口3不能(类似有丢码)
2、 用串口3能正常发送数据到串口助手上显示
3、 串口3单个字节中断接收有时候能正确显示
4、 现在怀疑的方向是:
a) 缓存数据区有重叠
b) 串口波特率设置不合适(可能性不大,能正常发送)
c) 串口模式设置问题(可能性不大,理由同上)
d) 中断受到其他时间延时影响(关闭串口1后仍然有此问题)
具体原因在哪里,有几天没找到了,本人菜鸟,在这里请各位大虾提点一下,以下是代码(大部分是官方例程),未优化,还很粗糙,请见谅:
#include "usart.h"
#include "1n3config.h"
#include "delay.h
bit busy1,busy2,busy3,busy4;
u8 xdata bufRX1[10];
u8 xdata bufRX3[10] _at_ 0x0180;
u8 cntRX1=0;
u8 cntRX3=0;
u8 cntTX1=0;
u8 cntTX3=0;
u8 KEY_NUM=0;
//串口1初始化配置
void U1INIT()
{
ACC = P_SW1;
ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0
P_SW1 = ACC;
#if (PARITYBIT == NONE_PARITY)
SCON = 0x50; //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
SCON = 0xda; //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
SCON = 0xd2; //9位可变波特率,校验位初始为0
#endif
AUXR = 0x40; //定时器1为1T模式
TMOD = 0x20; //定时器1为模式2(8位自动重载)
TL1 = (256 - (FOSC/32/BAUD)); //设置波特率重装值
TH1 = (256 - (FOSC/32/BAUD));
TR1 = 1; //定时器1开始工作
ES = 1; //使能串口中断
EA = 1;
}
//串口3初始化
void U3INIT()
{
P_SW2 &= ~S3_S0; //S3_S0=0 (P0.0/RxD3, P0.1/TxD3)
// P_SW2 |= S3_S0; //S3_S0=1 (P5.0/RxD3_2, P5.1/TxD3_2)
#if (PARITYBIT == NONE_PARITY)
S3CON = 0x50; //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
S3CON = 0xda; //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
S3CON = 0xd2; //9位可变波特率,校验位初始为0
#endif
T3L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
T3H = (65536 - (FOSC/4/BAUD))>>8;
T4T3M |= 0x02; //定时器3为1T模式
T4T3M |= 0x08; //定时器3开始计时
IE2 = 0x08; //使能串口3中断
EA = 1;
}
/*----------------------------
发送串口数据
----------------------------*/
void U3SendData(u8 dat)
{
while (busy3); //等待前面的数据发送完成
ACC = dat; //获取校验位P (PSW.0)
if (P) //根据P来设置校验位
{
#if (PARITYBIT == ODD_PARITY)
S3CON &= ~S3TB8; //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
S3CON |= S3TB8; //设置校验位为1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
S3CON |= S3TB8; //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
S3CON &= ~S3TB8; //设置校验位为0
#endif
}
busy3 = 1;
S3BUF = ACC; //写数据到UART2数据寄存器
// S3BUF = dat;
DelayUS(100);
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(u8 dat)
{
while (busy1); //等待前面的数据发送完成
ACC = dat; //获取校验位P (PSW.0)
if (P) //根据P来设置校验位
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 0; //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 1; //设置校验位为1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 1; //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 0; //设置校验位为0
#endif
}
busy1 = 1;
SBUF = ACC; //写数据到UART数据寄存器
}
/*----------------------------
发送字符串
----------------------------*/
void U3SendString(char *s)
{
while (*s) //检测字符串结束标志
{
U3SendData(*s++); //发送当前字符
}
}
/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{
SendData(*s++); //发送当前字符
}
}
//向串口发送多字节,len为该字符串长度
void U3SendBytes(unsigned char *dats,unsigned int len)
{
unsigned int k=0;
do
{
U3SendData(*(dats + k));
k++;
} while(k < len);
}
//向串口发送多字节,len为该字符串长度
void SendBytes(unsigned char *dats,unsigned int len)
{
unsigned int k=0;
do
{
SendData(*(dats + k));
k++;
} while(k < len);
}
/*----------------------------
UART 1中断服务程序
-----------------------------*/
void Uart() interrupt 4 //using 1
{
ES=0;
if(RI)
{
RI = 0; //清除RI位
if(cntRX1<10)
{
bufRX1[cntRX1]= SBUF; //P0显示串口数据
cntRX1++;
if(cntRX1>10)
{
cntRX1=0;
}
}
// P22 = RB8; //P2.2显示校验位
}
if (TI)
{
TI = 0; //清除TI位
busy1 = 0; //清忙标志
}
ES=1;
}
/*----------------------------
UART3 中断服务程序
-----------------------------*/
void Uart3() interrupt 17 //using 1
{
IE2=0X00;
if(S3CON & S3RI)
{
if(cntRX3<10)
{
bufRX3[cntRX3]= S3BUF;
// bufRX3= S3BUF;
LED2=~LED2;
cntRX3++;
if(cntRX3>10)
{
cntRX3=0;
}
}
S3CON &= ~S3RI; //清除S3RI位
}
// P2 = (S3CON & S3RB8); //P2.2显示校验位
if (S3CON & S3TI)
{
S3CON &= ~S3TI; //清除S3TI位
busy3 = 0; //清忙标志
}
IE2=0X08;
}
//主程序
void main()
{
P0M0=0;
P0M1=0;
P2M0=0;
P2M1=0;
//U1INIT();
U3INIT();
// SendString("这是串口1测试\r\n");
RS485_EN=1;
U3SendString("这是串口3测试\r\n");
RS485_EN=0;
while(1)
{
if(KEY1==0)
{
DelayMS(80);
if(KEY1==0)
{
KEY_NUM=1;
}
}
else if(KEY2==0)
{
DelayMS(80);
if(KEY2==0)
{
KEY_NUM=2;
}
}
else if(KEY3==0)
{
DelayMS(80);
if(KEY3==0)
{
KEY_NUM=3;
}
}
else if(KEY4==0)
{
DelayMS(80);
if(KEY4==0)
{
KEY_NUM=4;
}
}
switch(KEY_NUM)
{
case 0:
LED1=1;
LED3=1;
break;
case 1:
RS485_EN=1;
U3SendData(bufRX3[0]);
RS485_EN=0;
LED1=0;
LED3=1;
KEY_NUM=0;
break;
case 2:
RS485_EN=1;
U3SendData(bufRX3[1]);
RS485_EN=0;
LED1=LED3=1;
KEY_NUM=0;
break;
case 3:
LED3=0;
LED1=1;
RS485_EN=1;
U3SendData(bufRX3[3]);
KEY_NUM=0;
break;
case 4:
RS485_EN=1;
U3SendData(bufRX3[4]);
RS485_EN=0;
KEY_NUM=0;
break;
default: break;
}
}
}
|