您的位置:程序门 -> 硬件/嵌入开发 -> 片机/工控



pc与单片机串口通讯,系统重起


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


pc与单片机串口通讯,系统重起[已结贴,结贴人:caolily1984]
发表于:2007-12-19 15:55:49 楼主
我是个菜鸟,最近要做个接收串口数据的程序,用的是vc6.0的oncomm控件来做的。照着龚建伟写的串口调试助手的那篇文章编写了代码,可以将单片机与pc机相连后一运行程序系统就重起,我觉得是接收的数据量太大将内存中系统数据区覆盖造成系统崩溃,可是我定义了缓冲区的大小,为什么会出现这种情况呢,该如何解决呢?
  串口部分代码:
  if(m_ctrlcomm.getportopen())
                m_ctrlcomm.setportopen(false);
             
m_ctrlcomm.setcommport(1);   //选择com1
m_ctrlcomm.setinbuffersize(30720);

          if(!m_ctrlcomm.getportopen())
                m_ctrlcomm.setportopen(true);//打开串口
          else
                afxmessagebox("cannot   open   serial   port");

                m_ctrlcomm.setsettings("9600,n,8,1");   //波特率9600,无校验,8个数据位,1个停止位

                m_ctrlcomm.setinputmode(1);   //1:表示以二进制方式检取数据
                m_ctrlcomm.setrthreshold(1);   //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的oncomm事件
                m_ctrlcomm.setinputlen(0);   //设置当前接收区数据长度为0
                m_ctrlcomm.getinput();//先预读缓冲区以清除残留数据
                updatedata   (true);

            return   true;     //   return   true     unless   you   set   the   focus   to   a   control    
}

oncomm部分代码
  variant   variant_inp;
        colesafearray   safearray_inp;
        long   len,k;
        byte   rxdata[2048];   //设置byte数组   an   8-bit   integerthat   is   not   signed.
        cstring   strtemp;
 

if(m_ctrlcomm.getcommevent()==2)   //事件值为2表示接收缓冲区内有字符
 
 

{                             ////////以下可以根据通信协议加入处理代码
                sleep(20);
variant_inp=m_ctrlcomm.getinput();   //读缓冲区
                safearray_inp=variant_inp;   //variant型变量转换为colesafearray型变量
                len=safearray_inp.getonedimsize();   //得到有效数据长度
                for(k=0;k <len;k++)
                        safearray_inp.getelement(&k,rxdata+k);//转换为byte型数组
                for(k=0;k <len;k++)   //将数组转换为cstring型变量
                {
                        byte   bt=*(char*)(rxdata+k);   //字符型

if(m_ctrlhexdisplay.getcheck())
                                    strtemp.format("%02x   ",bt);   //将字符以十六进制方式送入临时变量strtemp存放,注意这里加入一个空隔
                        else  
                                    strtemp.format("%c",bt);   //将字符送入临时变量strtemp存放
                   
                        m_strrxdata+=strtemp;   //加入接收编辑框对应字符串  

m_edit.setsel(-1,   -1);  
updatedata(true);
     

//将字符存入文件

        cfile   file;
                        file.open("d:/d.txt",cfile::modewrite ¦cfile::modecreate ¦cfile::typebinary);
                        file.seek(0,cfile::begin);
                        file.write(&m_strrxdata,2048);
                        file.close();  

    }
        }
   
updatedata(false);   //更新编辑框内容



有能帮帮我的么,小妹在此先谢谢了
发表于:2007-12-19 16:22:511楼 得分:10
你什么操作系统亚?先确定是不是你vc程序写的有问题,不接你的板子运行也会重起吗?不过windows2000后的系统都挺稳定的。难道是你的板子画错了?
发表于:2007-12-20 09:39:142楼 得分:0
我操作系统是xp,不接板子不会重起,程序可以运行的,我用usb转串口了,因为机器上没有com口,但是用串口调试助手v2.1接板子就可以正常接收,还是我的这个程序中哪里处理的不当吧,这里是不是涉及缓冲区大小的问题,数据量太大造成内存中缓冲区溢出?还是oncomm事件频繁触发造成的呢?请高手指点迷津哦。。
发表于:2007-12-20 09:59:033楼 得分:0
另外,mscomm控件具体处理过程是怎样的呢,当他取缓冲区数据的时候涉及到指针复位吗,那他取一次如果持续有数据进来,那新来的数据是该覆盖还是溢出呢?怎么保证数据的连续呢,好头疼阿
发表于:2007-12-20 17:10:354楼 得分:10
建议你先用串口调试工具调试看看

然后再确定程序哪里出问题。
发表于:2007-12-21 09:00:435楼 得分:0
如果不接你的设备也会重起,可以说是你的vc程序有问题。否则,就要查你的电路板了。
发表于:2007-12-21 09:34:366楼 得分:0
电路板应该是没有问题的,用串口调试助手可以成功接收。不接设备也不会重起。我用两台计算机进行通信我的程序也可以成功,就是一接板子就重起,板子是不断的发数据的,一秒50个数据包,每个数据包12个字节。
我很困惑的是为什么会导致重起呢,程序在取数据时候的毛病吧,症结在哪里呢,是因为缓冲区设置不对大量数据取来将内存中系统文件冲掉导致系统崩溃吗?这种发数据取数据的方法是及时的不丢桢的么````
发表于:2007-12-21 17:49:047楼 得分:0
问题终于解决了,原来都不是那些问题,是主板接出来的串口线接触不好有些短路,谢谢各位了
发表于:2007-12-21 17:49:288楼 得分:0
问题终于解决了,原来都不是那些问题,是主板接出来的串口线接触不好有些短路,谢谢各位了
发表于:2007-12-21 17:49:389楼 得分:0
问题终于解决了,原来都不是那些问题,是主板接出来的串口线接触不好有些短路,谢谢各位了


快速检索

最新资讯
热门点击