打印
[国产单片机]

STC 双串口中断接收问题请教

[复制链接]
2979|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
DAVIDYE|  楼主 | 2015-11-26 19:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

双串口通讯测试,使用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;
                                }               
                           }
}

相关帖子

沙发
McuPlayer| | 2015-11-26 20:48 | 只看该作者
把每个串口的buf独立使用,不要复用

使用特权

评论回复
板凳
forget345| | 2015-12-8 08:50 | 只看该作者
终端服务程序中 IE2=0X00; 去掉,谁教你一进终端就要关使能?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

235

帖子

2

粉丝