打印

双串口问题

[复制链接]
4080|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
busdriver|  楼主 | 2012-10-18 22:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 busdriver 于 2012-10-19 12:35 编辑

先说系统配置:
1.内部32M晶振,波特率115200bps
2.双串口,均是接收中断,查询发送。
现象:
1。开机串口1能发送数据
2。一旦接收到串口2的数据后,串口1就不能发送数据。TRMT始终是0,不能变1
可能表述不准确,现在看寄存器TRMT为1,没有问题,但是主程序就卡住了。但是中断正常。下面贴出读串口缓冲期程序。
主程序卡死在这条语句while (TRMT1 == 0);//pending until TSR is empty
接收中断还是正常执行。测量CLK输出也对,说明单片机还在正常跑。
沙发
yewuyi| | 2012-10-19 09:25 | 只看该作者
贴出你的中断程序

使用特权

评论回复
板凳
busdriver|  楼主 | 2012-10-19 12:29 | 只看该作者
CLRWDT(); //clear WDT

    if (TMR1IF) //if timer1 overflow interrupt
    {
        //CLRWDT();
        //LCD_BL_CTRL = ~LCD_BL_CTRL;
        TMR1IF = 0;
        TMR1L = T1L;
        TMR1H = T1H;//Reload timer1 initial value, TMR1H:TMR1L = 0xFC18 = 64536
        lcd_timer++;

        if (key_step == 1) //in the step of delay
        {
            key_timer++;//key timet +1
        }
    }

    if (RC1IF) //if RS232 receive interrupt
    {
        RC1IF = 0;//clear interupt flag
        rx1sign = 1;
        *inlast1 = RCREG1;
        inlast1++;

        if (inlast1 == (rx1buf + RX1BUFLEN) )
            inlast1 = rx1buf;
    }

    if (RC2IF) //if RS485 receive interrupt
    {
        RC2IF = 0;//clear interupt flag
        *inlast2 = RCREG2;
        inlast2++;
        rx2sign = 1;

        if (inlast2 == (rx2buf + RX2BUFLEN) )
        {
            inlast2 = rx2buf;
        }
    }

使用特权

评论回复
地板
busdriver|  楼主 | 2012-10-19 12:30 | 只看该作者
主程序
        if (rx1sign) //if input buffer have incoming data from UART
            rs232_visit();

        if (rx2sign)
        {
            //newline();
            //puts ("get data from TDC...", 0);
            newline();
            puts ("**start data from TDC**", 0);
           tdc_visit();
            //newline();
            //puts ("**end data from TDC**", 0);
            //newline();
            //PutPrompt();
        }

使用特权

评论回复
5
busdriver|  楼主 | 2012-10-19 12:31 | 只看该作者
如果写成:
rx1sign,rx2sign均是unsigned char
        if (rx1sign == 1) //if input buffer have incoming data from UART
            rs232_visit();

        if (rx2sign == 1)
        {
            //newline();
            //puts ("get data from TDC...", 0);
            newline();
            puts ("**start data from TDC**", 0);
           tdc_visit();
            //newline();
            //puts ("**end data from TDC**", 0);
            //newline();
            //PutPrompt();
        }
就不会有问题。奇怪?

使用特权

评论回复
6
busdriver|  楼主 | 2012-10-19 12:35 | 只看该作者
/***********************************************************************
Name:void rs232_visit(unsignde int i)
Function:void
Input:none
Output:none
************************************************************************/
void rs232_visit()
{
    unsigned char cmdbuf;
    unsigned char rs232_cmd[10];
    unsigned char *ptr1, *ptr2;
    unsigned char temp = 0;
    unsigned char str[8];
    unsigned int number = 0;
    //len = 1;
    ptr2 = rs232_cmd;

    while (temp != '\r')
    {
        //if(getc(&cmdbuf,1,timeout,0) == 0x01)//get a character from
        getc (&cmdbuf, 1, 0);
        //return;//timeout, return
        //ptr1 = cmdbuf;
        *ptr2 = cmdbuf;
        temp = *ptr2;
        putc (*ptr2, 0);
        ptr2++;
    }

    *ptr2 = 0;

    if ( (!number_flag) && (strcmp (rs232_cmd, "\r") == 0) )
    {
        newline();
        puts (">", 0);//display prompt
    }
    else if ( (!number_flag) && (strcmp (rs232_cmd, "?\r") == 0) )
    {
        newline();
        puts ("show menu...", 0);
        display_cmd();
    }
    else if ( (!number_flag) && (strcmp (rs232_cmd, "s\r") == 0) )
    {
        newline();
        puts ("save eeprom...", 0);
        store_flag = 1;
        //display_cmd();
    }
    else if ( (!number_flag) && (strcmp (rs232_cmd, "start\r") == 0) )
    {
        newline();
        puts ("start test,ready go...", 0);//
    }
    else if ( (!number_flag) && (strcmp (rs232_cmd, "d\r") == 0) ) //show voltage of 24V and 5V5
    {
        //vdd_24v = 30000;
        num2asc (vdd_24v, str, 3);
        newline();
        puts ("The VDD_24V = ", 0);
        puts (str, 0);
        putc ('V', 0);
        num2asc (vdd_5v5, str, 3);
        newline();
        puts ("The VCC_5V5 = ", 0);
        puts (str, 0);
        putc ('V', 0);
        newline();
        puts (">", 0);//display prompt
    }
    else if ( (!number_flag) && (strcmp (rs232_cmd, "g\r") == 0) ) //get voltaga
    {
        //ptr2 = str;
        newline();
        number_flag = 1;
        puts ("please input number(0-65535):", 0);
        //while(temp != '\r')
        //{
        //        if(getc(&cmdbuf,1,timeout,0) == 0x01)//get a character from
        //        return;//timeout, return
        //ptr1 = cmdbuf;
        //*ptr2 = cmdbuf;
        //temp = *ptr2;
        //putc(*ptr2,0);
        //ptr2++;
        //}
        //asc2num(str,&number);
        //num2asc(number,str,0);
        //puts(str,0);
        //newline();
        //puts(">",0);//display prompt
    }
    else if (number_flag) // && (strcmp(rs232_cmd,"0\r") >= 0) && (strcmp(rs232_cmd,"65535\r") <= 0))//get number
    {
        number_flag = 0;

        //if(asc2num(rs232_cmd,&number) == 0x02)
        if (asc2num (rs232_cmd, &number) == 0x02)
        {
            num2asc (number, str, 0);
            //number = 0;
            newline();
            puts ("You have inputed:", 0);
            puts (str, 0);
            newline();
            puts (">", 0);//display prompt
        }
    }
    else
    {
        newline();
        //if(number_flag)
        //{
        //number_flag = 0;
        //puts("Your input is not number.",0);
        //}
        //else
        //{
        puts ("The command is undefined!", 0);
        //}
        newline();
        puts (">", 0);//display prompt
    }
}

使用特权

评论回复
7
busdriver|  楼主 | 2012-10-19 12:36 | 只看该作者
本帖最后由 busdriver 于 2012-10-19 16:04 编辑

/***********************************************************************
Name:unsigned char putc(void)
Function:get characters from the input buffer
Input:none
Output:the character
************************************************************************/
void getc (unsigned char *data, unsigned char len, unsigned char uart_type)
{
    unsigned char temp = 0;
    unsigned char cnt = 0;
    //unsigned char data = 0x00,cnt = 0;

// if ( !( ((inlast >= getlast) && ((inlast -getlast) < len))
    //     || ((inlast<getlast) && ((ILEN-(getlast-inlast))<len)) ) )
    //{
    switch (uart_type)
    {
    case 0://rs232
    {
        while ( ( (inlast1 >= getlast1) && ( (inlast1 - getlast1) < len) )
                || ( (inlast1 < getlast1) && ( (RX1BUFLEN - (getlast1 - inlast1) ) < len) ) );

        //{
        //cnt += 10;
        //if(cnt>timeout)
        //break;
        //return(UART_TIMEOUT);
        //return(0x01);
        //}
        //RC1IE = 0;//disable receive interrupt

        for (cnt = 0; cnt < len; cnt++)
        {
            *data = *getlast1;
            data++;
            getlast1++;

            if (getlast1 == rx1buf + RX1BUFLEN)
            {
                getlast1 = rx1buf;
            }

            if (getlast1 == inlast1)
            {
                rx1sign = 0;//½ÓÊÕ»º³åÇø¿Õ
            }
        }

        //RC1IE = 1;//enable receive interrupt
        break;
    }
    case 1://rs485
    {
        while ( ( (inlast2 >= getlast2) && ( (inlast2 - getlast2) < len) )
                || ( (inlast2 < getlast2) && ( (RX2BUFLEN - (getlast2 - inlast2) ) < len) ) );

        //{
        //cnt += 10;
        //if(cnt>timeout)
        //return(0x01);
        //break;
        //return(UART_TIMEOUT);
        //}
        //RC2IE = 0;//disable receive interrupt

        for (cnt = 0; cnt < len; cnt++)
        {
            temp = *getlast2;
            //data++;
            getlast2++;

            //temp2 = *getlast2;
            //getlast2++;
            if (temp == 0x7D)
            {
                *data = *getlast2;
                data++;
                getlast2++;
            }
            else
            {
                *data = temp;
                data++;
            }

            if (getlast2 == rx2buf + RX2BUFLEN)
            {
                getlast2 = rx2buf;
            }

            if (getlast2 == inlast2)
            {
                rx2sign = 0;//½ÓÊÕ»º³åÇø¿Õ
            }
        }

        //RC2IE = 1;//enable receive interrupt
        break;
    }
    /*
        case 2://ook
        {
            //unsigned char data = 0x00,cnt = 0;
            //INT1IE = 0;//disable receive interrupt
            //disable_int();
            //for (cnt=0; cnt<8; cnt++)
            while ( ( (ook_inlast >= ook_getlast) && ( (ook_inlast - ook_getlast) < len) )
                    || ( (ook_inlast < ook_getlast) && ( (ILEN - (ook_getlast - ook_inlast) ) < len) ) );

            //{
            for (cnt = 0; cnt < len; cnt++)
            {
                *data = *ook_getlast;
                data++;
                ook_getlast++;

                if (ook_getlast == ookbuf + ILEN)
                {
                    ook_getlast = ookbuf;
                }

                if (ook_getlast == ook_inlast)
                {
                    ooksign = 0;//½ÓÊÕ»º³åÇø¿Õ
                }
            }

            //}
            //INT1IE = 1;//enable receive interrupt
            //return(data);
        }
    */
    default:
        break;
    }

    //return(UART_DONE);
    //return(0x02);
    //}
}

使用特权

评论回复
8
yewuyi| | 2012-10-19 13:23 | 只看该作者
在PIC上,书写中断函数时,应当将中断溢出标志位和中断使能位结合起来判断。

例如:if (TMR0IE&&TMR0IF){}

使用特权

评论回复
9
busdriver|  楼主 | 2012-10-19 16:01 | 只看该作者
中断是一直使能的,好像没有区别啊

使用特权

评论回复
10
busdriver|  楼主 | 2012-10-21 16:54 | 只看该作者
开机启动时,接串口2的设备会发数据过来,而这时程序还没完成初始化,程序就会乱掉,估计是缓冲区指针被破坏了?
解决办法1:
1.修改串口程序,发送接收均设timeout机制,串口1正常了,但是不能响应串口2接收中断;示波器观察串口2发送接收波形正常的。
2.开机是disable串口2,由串口1命令enable之,串口2也正常了。

使用特权

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

本版积分规则

44

主题

416

帖子

0

粉丝