打印
[AVR单片机]

GCC 编译,中断中局部变量奇怪变化,请求支援!(UCOS-II)

[复制链接]
2539|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kanprin|  楼主 | 2007-9-4 08:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

//串口0接收到数据
//与从机通信
UCOSISR(SIG_UART0_RECV)
{
    INT8U check=0;
    INT8U i=0;
    INT8U uart1RxLength = 0;
    
    PushRS();
    OSIntEnter();
    if (1 == OSIntNesting)
    OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
    
    
    uart0TimeOutCounter = 0;
    uart0Action = 1;
    uart1RxLength = uart0RxCounter;
    uart0RxBuf[uart1RxLength++] = UDR0;
    
    
    if(1 == uart1RxLength)
    {
        if(0X48 != uart0RxBuf[0])
        {
            uart1RxLength = 0;
            uart0Action = 0;
        }
    }
    else
    if(2 == uart1RxLength)
    {
        if(0X54 != uart0RxBuf[1])
        {
            uart1RxLength = 0;
            uart0Action = 0;
        }
    }
    else
    if(uart1RxLength >3)
    {
        if(uart1RxLength >= UART0_RX_BUF_SIZE - 1)
        {
            uart1RxLength = 0;
            uart0Action = 0;
            uart0TimeOutCounter = 0;
        }
        else
        if((0x48 == uart0RxBuf[0]) && (0x54 == uart0RxBuf[1]) && (uart1RxLength == uart0RxBuf[3]))
        {
            check = 0;
            for(i = 0; i < (uart1RxLength - 1); i++)
            {
                check ^= uart0RxBuf;
            }

            
            if(check == uart0RxBuf)
            {
                if(slaveUpdateFlag)
                {
                    OSSemPost(updateSem);
                }
                else
                {
                    OSSemPost(uart0RxSem);
                }
            }
            else
                {
                sendChar1(uart1RxLength);
                sendChar1(check);
                sendChar1(i);
                for(uart1RxLength=0; uart1RxLength<uart0RxBuf[3]; uart1RxLength++)
                    sendChar1(uart0RxBuf[uart1RxLength]);
                
                RELAY3_ON;
            }
            uart1RxLength = 0;//传输出错
            uart0Action = 0;
            uart0TimeOutCounter = 0;
        }
    }
    
    uart0RxCounter = uart1RxLength;
    
    OSIntExit();
    PopRS();
}

数据的传输格式:0x48 + 0x54 + addr + Length + data + check(异或和)

问题出现在校验一节:
check = 0;
            for(i = 0; i < (uart1RxLength - 1); i++)
            {
                check ^= uart0RxBuf;
            }

            
            if(check == uart0RxBuf)
            {
                if(slaveUpdateFlag)
                {
                    OSSemPost(updateSem);
                }
                else
                {
                    OSSemPost(uart0RxSem);
                }
            }
            else
                {
                sendChar1(uart1RxLength);
                sendChar1(check);
                sendChar1(i);
                for(uart1RxLength=0; uart1RxLength<uart0RxBuf[3]; uart1RxLength++)
                    sendChar1(uart0RxBuf[uart1RxLength]);
                
                RELAY3_ON;

平时,一般情况下计算的if(check == uart0RxBuf)都会成立,偶尔不等的时候,观察发送出来的数据又是正确的,如:0x07 0x00 0x00 0x48 0x54 0x05 0x07 0x00 0x00 0x1E
分析上面发出来的数据,长度为7,check和i的值都为0,而uart0RxBuf中的数据是正确的,猜测程序跳过了for循环引起。局部变量i,check前加volatile后,程序的执行结果不可预测,可能造成系统崩溃。 恳请高人指点,谢谢。
系统为mega64外扩64K RAM。

相关帖子

沙发
JunZe| | 2007-9-4 10:52 | 只看该作者

static

使用特权

评论回复
板凳
kanprin|  楼主 | 2007-9-4 18:37 | 只看该作者

暂时先把校验放到中断外处理了,不过问题还保留,郁闷

使用特权

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

本版积分规则

39

主题

343

帖子

0

粉丝