单片机/MCU论坛
直播中

宾得

9年用户 67经验值
擅长:模拟技术 嵌入式技术 光电显示 控制/MCU EDA/IC设计
私信 关注
[问答]

上位机串口中断问题,搞了一天了还是不对!求大神帮忙

C# 串口中断中接收缓冲区会在下次进入时突然变成几百个数据(断点调试看到的),按理说请求一次数据只会接收到19个字节的,请求数据放在一个100ms的定时器里进行

上位机程序:
        public void port_DataRecived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] r = new byte[serialPort1.BytesToRead];
            if (r.Length != 0){
                serialPort1.Read(r, 0, r.Length);
                PortReceivedList.AddRange(r);
            }
            while (true){
                if (PortReceivedList.Count>19){
                    if (PortReceivedList[0] == 0x66 && PortReceivedList[1] == 0x66 && PortReceivedList[2] == 0x66){
                        int CalculateCRC = 0;
                        int CRC = ((int)PortReceivedList[17] << 8) | PortReceivedList[18];
                        for (int i = 3; i<17; i++) {
                            CalculateCRC += PortReceivedList[i];
                        }
                        if (CRC == CalculateCRC){
                            int ID = PortReceivedList[3];
                            O_DY[ID] = (ushort)(((ushort)(PortReceivedList[5] & 0x0f) << 8) | PortReceivedList[6]);
                            O_DL[ID] = (ushort)(((ushort)(PortReceivedList[7] & 0x0f) << 8) | PortReceivedList[8]);
                            DCDY[ID] = (ushort)(((ushort)(PortReceivedList[9] & 0x0f) << 8) | PortReceivedList[10]);
                            DCDL[ID] = (ushort)(((ushort)(PortReceivedList[11] & 0x0f) << 8) | PortReceivedList[12]);
                            SDDY[ID] = (ushort)(((ushort)(PortReceivedList[13] & 0x0f) << 8) | PortReceivedList[14]);
                            SDDL[ID] = (ushort)(((ushort)(PortReceivedList[15] & 0x0f) << 8) | PortReceivedList[16]);
                            SD[ID] = ((PortReceivedList[4] & 0x01) == 0) ? false : true;
                            YJ[ID] = ((PortReceivedList[4] & 0x02) == 0) ? false : true;
                            GZ[ID] = ((PortReceivedList[4] & 0x04) == 0) ? false : true;
                            myPan();
                            PortReceivedList.RemoveRange(0, 19);
                            InteractiveSuccessful[nowMachine] = true;
                        }else{
                            //SendCmd(LastCmd[nowMachine], nowMachine);
                            InteractiveSuccessful[nowMachine] = false;
                        }
                    }else{
                        PortReceivedList.RemoveRange(0,1);
                    }
                }else{
                    break;
                }
            }
        }

下位机程序:

void USART1_IRQHandler(void)
{
        if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET){
                USART_ReceiveData(USART1);
        }
        if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
                static u8 DataCount = 0;
                r[DataCount] = USART_ReceiveData(USART1);
                if(r[0] != 0x99){
                        DataCount = 0;
                }else{
                        if( DataCount==1 && r[1]!=0x99 ){
                                DataCount = 0;
                        }
                }
                if(++DataCount>=5){
                        DataCount = 0;
                        if(r[0]==0x99 && r[1]==0x99){
                                u8 CalculateCRC  = (r[2]+r[3])/2.0+0.5;
                                u8 Cmd = r[3];
                                if(CalculateCRC == r[4]){
                                        if(r[2]==ID){
                                                u16 Crc = 0,i;
                                                if(Cmd&0x02){ ForceStop = 1;  }else{ ForceStop = 0;  }
                                                if(Cmd&0x04){ ForceStart = 1; }else{ ForceStart = 0; }
                                                txBuffer[4]++;
                                                txBuffer[5] = O_DY>>8;
                                                txBuffer[6] = O_DY&0xff;
                                                txBuffer[7] = O_DL>>8;
                                                txBuffer[8] = O_DL&0xff;
                                                txBuffer[9] = DCDY>>8;
                                                txBuffer[10] = DCDY&0xff;
                                                txBuffer[11] = DCDL>>8;
                                                txBuffer[12] = DCDL&0xff;
                                                txBuffer[13] = SDDY>>8;
                                                txBuffer[14] = SDDY&0xff;
                                                txBuffer[15] = SDDL>>8;
                                                txBuffer[16] = SDDL&0xff;
                                                for(i=3;i<17;i++){
                                                        Crc += txBuffer[i];
                                                }
                                                txBuffer[17] = Crc>>8;
                                                txBuffer[18] = Crc&0xff;
                                                SendDatas();
                                        }
                                }
                        }
                }
        }
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}

上位机发送格式:0x99 0x99   ID    Cmd    CRC(=(byte)(ID+Cmd)/2.0+0.5)
下位机发送格式:0x66 0x66 0x66 ID State(状态标志)  Datas(数据12个)  CRCh   CRCl

回帖(3)

愚塘霸主

2017-10-8 17:24:59

最佳答案

SendDatas();
不知道你这个函数里是怎么实现的,使用查询标志位,是不是判读有问题。如果使用中断发送,但是在你的void USART1_IRQHandler(void)里 我没有看到关于发送的标志位判断。
举报

宾得

2017-11-1 11:23:18
引用: 愚塘霸主 发表于 2017-10-14 11:31
SendDatas();
不知道你这个函数里是怎么实现的,使用查询标志位,是不是判读有问题。如果使用中断发送,但是在你的void USART1_IRQHandler(void)里 我没有看到关于发送的标志位判断。

谢谢你的热心解答,之前很久没人回答就没上这个论坛,今天上来才发现。这个问题解决了。是起始位没有判断正确的原因,因为这是多级通讯,一个单片机发送的数据,不光上位机可以接收到另一个单片机也能接收到,起始位没有判断对所以导致单片机一直在发送数据,另一个单片机误判后也一直发送数据,就存在了许多冲突了!
      不过真的谢谢了!
举报

宾得

2017-11-1 11:35:20
引用: 愚塘霸主 发表于 2017-10-14 11:31
SendDatas();
不知道你这个函数里是怎么实现的,使用查询标志位,是不是判读有问题。如果使用中断发送,但是在你的void USART1_IRQHandler(void)里 我没有看到关于发送的标志位判断。

void USART1_IRQHandler(void)
{
        if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET){
        USART_ReceiveData(USART1);
    }
        if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
                static u8 DataCount = 0;
                r[DataCount] = USART_ReceiveData(USART1);
                if(r[0] != 0x99){
                        DataCount = 0;
                        goto a;
                }else{
                        if( DataCount==1 && r[1]!=0x99 ){
                                DataCount = 0;
                                goto a;
                        }
                }
                if(++DataCount>=5){
                        DataCount = 0;
                        if(r[0]==0x99 && r[1]==0x99){
                                u8 CalculateCRC  = (r[2]+r[3])/2.0+0.5;
                                u8 Cmd = r[3];
                                if(CalculateCRC == r[4]){
                                        if(r[2]==ID){
                                                u16 Crc = 0,i;
                                                if(Cmd&0x02){ ForceStop = 1;  }else{ ForceStop = 0;  }
                                                if(Cmd&0x04){ ForceStart = 1; }else{ ForceStart = 0; }
                                                O_DY++,O_DL++,  DCDY++,DCDL ++,  SDDY++,SDDL++;
                                                txBuffer[4]++;
                                                txBuffer[5] = O_DY>>8;
                                                txBuffer[6] = O_DY&0xff;
                                                txBuffer[7] = O_DL>>8;
                                                txBuffer[8] = O_DL&0xff;
                                                txBuffer[9] = DCDY>>8;
                                                txBuffer[10] = DCDY&0xff;
                                                txBuffer[11] = DCDL>>8;
                                                txBuffer[12] = DCDL&0xff;
                                                txBuffer[13] = SDDY>>8;
                                                txBuffer[14] = SDDY&0xff;
                                                txBuffer[15] = SDDL>>8;
                                                txBuffer[16] = SDDL&0xff;
                                                for(i=3;i<17;i++){
                                                        Crc += txBuffer;
                                                }
                                                txBuffer[17] = Crc>>8;
                                                txBuffer[18] = Crc&0xff;
                                                SendDatas();
                                        }
                                }
                        }
                }
                a:
                txBuffer[0] = 0x66;
        }
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
这是我重新写的,这起始位置判断对了就没问题了
举报

更多回帖

×
20
完善资料,
赚取积分