cpubbs论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

LabVIEW+单片机学习套件全套教程资料下载[免费]LabVIEW论坛精华列表贴USB0816数据采集卡《LabVIEW宝典》
LabWindows/CVI论坛精华贴NET0816以太网数据采集卡RC0210远程设备授权系统 关闭关停锁定打开设备 户外分布式数据采集
NET1624低速高精度以太网数据采集卡WIFI0824SD无线WIFI网络数据采集卡脱机运行 SD存储 小尺寸微型 串口采集远程采集 安卓 手持移动采集 纪录仪
查看: 1829|回复: 7

RS232发送字节问题

[复制链接]
发表于 2008-11-8 10:51:44 | 显示全部楼层 |阅读模式
我用编写了下面代码,程序没有语法错误,但在定时器下(设到0.5秒了)运行速度很慢,甚至死面,请问是什么缘故,请高手指点!!!
/*--------------------------------------------------------------*/
/*                发送数据代码1函数                             */
/*--------------------------------------------------------------*/
void fashongdaima1(void)
{
        if (ComWrt (comport,"@00RD0101002551*\r", 18) != 13)
     inqlen = GetInQLen (comport);
  if  (inqlen>100)
     read_data[0] = '\0';
     bytes_read = ComRdTerm (comport, read_data, 500,13);
     CopyString (tbox_read_data, 0, read_data, 0, bytes_read);
    // SetCtrlVal (panelHandle,PANEL_TEXTBOX ,tbox_read_data);
}
/*--------------------------------------------------------------*/
/*                发送数据代码2函数                             */
/*--------------------------------------------------------------*/
void fashongdaima2(void)
{
        if (ComWrt (comport,"@00RD0126002554*\r", 18) != 13)
     inqlen = GetInQLen (comport);
  if  (inqlen>100)
     read_data[0] = '\0';
     bytes_read = ComRdTerm (comport, read_data, 500,13);
     CopyString (tbox_read_data, 0, read_data, 0, bytes_read);
    // SetCtrlVal (panelHandle,PANEL_TEXTBOX ,tbox_read_data);
}
/*--------------------------------------------------------------*/
/*                发送数据代码1函数                             */
/*--------------------------------------------------------------*/
void fashongdaima3(void)
{
        if (ComWrt (comport,"@00RD0151002554*\r", 18) != 13)
     inqlen = GetInQLen (comport);
  if  (inqlen>100)
     read_data[0] = '\0';
     bytes_read = ComRdTerm (comport, read_data, 500,13);
     CopyString (tbox_read_data, 0, read_data, 0, bytes_read);
    // SetCtrlVal (panelHandle,PANEL_TEXTBOX ,tbox_read_data);
}
/*--------------------------------------------------------------*/
/*                发送数据代码1函数                             */
/*--------------------------------------------------------------*/
void fashongdaima4(void)
{
        if (ComWrt (comport,"@00RD0176002551*\r", 18) != 13)
     inqlen = GetInQLen (comport);
  if  (inqlen>100)
     read_data[0] = '\0';
     bytes_read = ComRdTerm (comport, read_data, 500,13);
     CopyString (tbox_read_data, 0, read_data, 0, bytes_read);
    // SetCtrlVal (panelHandle,PANEL_TEXTBOX ,tbox_read_data);
}
/*--------------------------------------------------------------*/
/*                接收数据定时器程序                            */
/*--------------------------------------------------------------*/
int CVICALLBACK jieshouzhihuDSQ (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
int a;
switch (event)
{
  case EVENT_TIMER_TICK:
       a=1;
    while (a<=4)
    {
     a++;
     switch (a)
     {
      case 1:fashongdaima1();break;
      case 2:fashongdaima2();break;
      case 3:fashongdaima3();break;
      case 4:fashongdaima4();break;
     }
    }
   break;
}
return 0;
}


是不是 “发送数据代码1函数 ”代码下的 if 函数运用出了问题还是其它的。
发表于 2008-11-8 22:16:21 | 显示全部楼层
慢的时候您点一下那个调试的STOP,看停在哪里!兄弟最好将程序压缩一下上传,比较容易查问题,只看代码有时候不好查的!好运!
发表于 2008-11-10 11:18:10 | 显示全部楼层
首先,我不知道你的通讯协议,不便于对程序流程作判断!
其次,RS232传输的是ASCII字符,还是Byte字节?
就程序本身来说,说的不客气一点:逻辑混乱!

if (ComWrt (comport,"@00RD0101002551*\r", 18) != 13)   ——〉传输18个字符,返回值怎么会是13!
     inqlen = GetInQLen (comport); ——〉上面的if语句是判定写串口是否出错,if后面应该是错误处理模块。跟上怎么一句,让人匪夷所思!

if  (inqlen>100) ——〉下位机一次传输多少字节(或字符)? 如果输入缓冲区中没有100个以上字符,程序整个就无法按流程执行下去!不知会跑到哪去!

read_data[0] = '\0'; ——〉什么用意? read_data是怎么定义的?

bytes_read = ComRdTerm (comport, read_data, 500,13); ——〉超时定义为多少?这里怎么又设定读取500字节?

。。。。。。
 楼主| 发表于 2008-11-10 16:57:21 | 显示全部楼层
我用的是hostlink协议,传输的是字节,不是ASCII码。我做的是想用CVI做一个上位机监控程序,和OMRIN的PLC通信,下面的这个程序是我从例子里面切过来的,发送没问题,但我一用定时器与PLC通信时就死机。我觉得是下面的循环逻辑都有问题。我这句话是首先ComWrt 发送一串字符到PLC,然后再通过ComRdTerm接收PLC的回复。
您好!netcreature。你说的好,我的程序真是逻辑混乱。
1、“if (ComWrt (comport,"@00RD0101002551*\r", 18) != 13)   ——〉传输18个字符,返回值怎么会是13!”我是看帮助里面的例子上的,我也不清楚。
2、if  (inqlen>100) ——〉下位机一次传输多少字节(或字符)? 如果输入缓冲区中没有100个以上字符,程序整个就无法按流程执行下去!不知会跑到哪去!  每次发送到PLC的都是"@00RD0101002551*\r ,而每次收回来都是109个字符。
3、read_data[0] = '\0'; ——〉什么用意? read_data是怎么定义的?  read_data定义 char read_data[1000],好像没意义,是我朋友编写的。
4、bytes_read = ComRdTerm (comport, read_data, 500,13); ——〉超时定义为多少?这里怎么又设定读取500字节?
我们是用13来表示CR,我们收回来的字节数是109个。
;
void fashongdaima1(void)
{
        if (ComWrt (comport,"@00RD0101002551*\r", 18) != 13)
     inqlen = GetInQLen (comport);
  if  (inqlen>100)
     read_data[0] = '\0';
     bytes_read = ComRdTerm (comport, read_data, 500,13);
     CopyString (tbox_read_data, 0, read_data, 0, bytes_read);
    // SetCtrlVal (panelHandle,PANEL_TEXTBOX ,tbox_read_data);
}
我是刚刚接触C语言不久,对这些不是很熟悉,还请大家多多指教!!!
在下感激不尽!
我把它改为:
void fashongdaima4(void)
{
        if (ComWrt (comport,"@00RD0176002551*\r", 18) != 13)
     RS232Error = ReturnRS232Err ();
  if (RS232Error)
   {
    DisplayRS232Error ();
   }
   else
     read_data[0] = '\0';
     bytes_read = ComRdTerm (comport, read_data, 500,13);
     CopyString (reach4, 0, read_data, 0, bytes_read);
}
就不会出现死机的情况,但把定时器定为一秒时运行很慢;只行动其中的一条void fashongdaima(void)就不会出现这种情况,是不是循环有问题?还是这条语句里的循环问题?还是少了语句?请高手指点指点!!

[ 本帖最后由 xiaowei86 于 2008-11-11 08:49 编辑 ]
发表于 2008-11-11 09:26:13 | 显示全部楼层
呵呵...你的这段代码根本无法正确执行!不死机不代表程序就能正确执行!

if (ComWrt (comport,"@00RD0176002551*\r", 18) != 13) ——〉这条语句在串口不出错的情况下总是成立的!
你应该将它改为:if (ComWrt (comport,"@00RD0176002551*\r", 18) != 18) ;ComWrt (comport,"@00RD0176002551*\r", 18)返回值是串口发送的字符数!
而且ComWrt (comport,"@00RD0176002551*\r", 18)是发送的ASCII字符串,不是字节码,下位机能正确接受吗?

另外,你连基本的串口配置都不说明,串口通讯协议也不讲,至少我是很难帮上什么忙!
 楼主| 发表于 2008-11-11 09:52:05 | 显示全部楼层
谢谢netcreature的提醒!!!
基本的串口配置是:COM2,波特率9600,数据位7,奇偶校验EVEN,停止位2;;
"@00RD0176002551*\r", 这串字符代表的协议是:@是报头,00是机号,RD是识别码(表示读取PLC里DM存储区),0176是表示从D176开始读,0025是表示读取25个地址,从D176开始到D200,51是CRC码,*\r是结束标志。

我现在用ComWrt (comport,"@00RD0176002551*\r", 18) 发送之后,ComRdTerm (comport, read_data, 500,13);收回来的是正确的值,我监测过。

刚刚把13改为18后,不会死机了,但把定时器定到0.5秒下,还是会卡,速度明显变慢,还是语句问题或是循环问题?
还请指教!!!

[ 本帖最后由 xiaowei86 于 2008-11-11 09:59 编辑 ]
 楼主| 发表于 2008-11-17 11:29:10 | 显示全部楼层
此问题已解决,直接加一句
count=GetInQLen (comport);
bytes_read = ComRdTerm (comport, read_data, count,13);
就不会出现上述问题。
发表于 2008-11-17 13:02:46 | 显示全部楼层
你的这几句代码只是在理想条件下才能正常执行!
如:当你读输入缓冲区时,里面可能没有109个字符,此时,count会小于109;
        ComRdTerm ()读串口时,如果发生超时,而定时时间已到,程序就又会出错;
       设计一个健壮的(也就是鲁棒性)程序,还需要考虑更多的问题!这也是我以前不建议你在串口通讯中使用定时器的一个原因!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|cpubbs论坛. ( 粤ICP备09171248号 )

GMT+8, 2025-4-20 12:54 , Processed in 0.624480 second(s), 7 queries , Gzip On, File On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表