CANoe下使用COM端口进行RS485/RS232数据通信

1、 Open COM接口
方法描述:打开串口,在软件运行时打开串口。
方法参数:Port
返回值: 1:打开成功;0:打开失败。当连接失败的时候,在write窗口打印相关错误信息。
int Drv_OpenCom(Port),调用CANoe API的Connect和Config
2、Close COM接口
方法描述:断开串口,软件停止运行时调用,会关闭串口通信。
方法参数:Port
返回值: 1:断开成功;0:断开失败,当断开失败的时候,在write窗口打印相关错误信息。
int Drv_CloseCom (Port),调用CANoe API的Disconnect
3、SendData接口
方法描述:串口发送函数,调用此函数进行数据发送
方法参数:
port :端口号;
Databuffer: 发送的数据(byte数组); DatabufferLen:发送的数据长度;
Text : 发送的数据(字符串数组); TextLen :发送的字符串数据长度 ;
返回值: 1 发送成功;0 发送失败
不加CRC校验的发送方法:
int RS232SendDataWithCRC16 (dword port, byte Databuffer[], long DatabufferLen)
注意:发送数据时不带CRC校验,在CANoe API接口中自动添加CRC。CRC格式要求: 16位,低字节在前。
通用发送方法:
int RS232SendData (dword port, byte Databuffer[],long DatabufferLen)
int RS232SendText (dword port, char Text[], long TextLength)
注意:
如果是发送字符串数据,比如SCPI指令,使用RS232SendText方法;
如果是发送字节数组,比如Modbus协议指令,使用RS232SendData方法。
4、ReceiveData接口
使用系统变量进行数据接收,系统变量更新一次,接收一次数据值。
on sysvar_updata NameSpace szRxData
{
sysGetVariableData(sysvar::NameSpace::szRxData, DataBuffer, DataBufferLength);
//数据接收完成判断:完成,进行完整性验证; 未完成,继续接收数据。
//数据完整性验证判断:通过,进行数据解析;不通过,舍弃数据,从新接收。
}

RS485/RS232模组调用流程

调试过程过程如下,主要完成通信连接、在线初始化配置、读取电压电流参数等。
A.通信连接,设置通信端口配置参数
gPortValue = 7; // 端口
gBaudRateValue = 9600; // 波特率
gDataBitsValue = 8; // 数据位
gParityValue = 0; // 奇偶校验位
gStopbitsValue = 1; // 停止位
调用连接函数,OpenCom(gPortValue),判断是否连接成功;

B.在线初始化配置,进行仪器初始参数设置。
由于辅助电源的通信指令是SCPI直流,所以调用RS232SendText函数
分别发生如下几条指令:
1)设置远程模式

char RemoteCtrl[50] = "SYSTem:REMote\n";
RS232SendText(gPortValue, SendBuffer, strlen(RemoteCtrl));

2)设置辅源电压

char SetVolt[50]  = "VOLTage 12\n";
RS232SendText(gPortValue, SendBuffer, strlen(SetVolt));

3)设置辅源电流

 char SetCurrent[50]  = "CURRent 10\n";
RS232SendText (gPortValue, SendBuffer, strlen(SetCurrent));

4)设置辅源输出

char OutputOn[50]  = "OUTPut 1\n";
RS232SendText(gPortValue, SendBuffer, strlen(OutputOn));

调试记录:
①发送上述指令,在CANoe界面打印发送的信息,如下图:

图4:初始化指令发送
②查看电源响应:
源界面显示:电压12V,电流10A,输出Onoff按钮灯亮,显示Rmt,Error信息为空。

C.读取测量电压、测量电流、输出状态以及查询系统状态

char QueryCurrent[50] = "MEASure:CURRent?\n";
RS232SendText(gPortValue, SendBuffer, strlen(QueryCurrent));
char QueryOnOff[50]   = "OUTPut?\n";
RS232SendText(gPortValue, SendBuffer, strlen(QueryOnOff));

调试记录:
①发送上述指令,在CANoe界面打印发送的信息,如下图:
发送获取测量值和状态指令

辅助电源开启输出

调节辅助电源电压测试

svRxData = sysvar::Hardware::AuxPower_IT6900_::szRxData; // 系统变量指向
sysSetVariableData(svRxData,gReceiverBuffer,gNumberOfReceivedBytes);
//底层接收数据赋给系统变量
char RecvBuffer[100];
sysGetVariableData(sysvar::Hardware::AuxPower_IT6900_::szRxData, g_u8_DataBuffer, g_i32_RxBytesCount); //获取系统变量数据到DataBuffer数组
MODBUS_RTU协议,使用下列发送函数进行数据发送:
RS232SendDataWithCRC16(port,byteBuffer, byteBufferLength));
RS232SendData(port, byteBuffer, byteBufferLength);
①使用CRC校验,调用RS232SendDataWithCRC16函数发送。
byte SendCmd[6] = {0x01,0x03,0x10,0x08,0x00,0x02};
RS232SendDataWithCRC16(gPortValue , SendCmd, elCount(SendCmd));

②不使用CRC校验,调用RS232SendData函数发送。
byte SendCmd[8] = {0x01,0x03,0x10,0x08,0x00,0x02,0x41,0x09};
RS232SendData (gPortValue , SendCmd, elCount(SendCmd));

//CAPL语言(RS232.can 源码)
/**************************    RS232底层调用方法             *****************************
1、外部.can程序: #include "RS232.can"
2、外部.can程序:on start中,获取串口初始化参数,分别给下列参数赋值。    long gPortValue;long gBaudRateValue;long gDataBitsValue;long gParityValue;long gStopbitsValue;
3、外部.can程序:对RS232.can中定义的系统变量进行指向
4、初始化:外部.can程序,调用串口初始化函数:initSerialPort();
5、发送数据:外部.can程序,调用发送函数,进行数据发送。     RS232SendData(dword port, byte buffer[], long number, char DataType[])16进制发送时     :DataType="hex"文本形式发送时   :DataType="text"
6、接收数据:系统变量 svRxData 就是每次缓冲区接收到的数据,在处理数据的时候,现在外面建立全局的接收字符串,每次接收到缓冲区的数据后,累加到全局变量中,然后进行判断,当满足接收完成条件后处理数据,处理完毕,再在全局变量中删除已经处理过的部分。
*************************************************************************************/
includes
{}variables
{// GLOBALconst int kBUFFER_SIZE = 100;const int kINFO        = 1;const int kWARN        = 2;const int kERROR       = 3;const int kHANDSHAKE_DISABLED = 0;const int kHANDSHAKE_RTSCTS   = 33;// data is copied from callback buffer to gReceiverBuffer (collects data)byte gReceiverCallbackBuffer[kBUFFER_SIZE];byte gReceiverBuffer[kBUFFER_SIZE];byte gEmptyBuffer   [kBUFFER_SIZE];long gNumberOfReceivedBytes = 0;// state variablebyte g_bySending = 0;byte Buffer[kBUFFER_SIZE];/*****************************************************************/byte g_byCrcResult[2];//公共变量,外部CAN对变量赋值long g_i32PortValue;long g_i32BaudRateValue;long g_i32DataBitsValue;long g_i32ParityValue;long g_i32StopbitsValue;//数据类型标志位,外部赋值char g_szSendDateType[5] = "";//接收数据的系统变量,没有具体指向,外部使用时必须明确指向系统变量sysvarData * g_szRecvData;
}/*******************       通信端口断开         *********************************
函数作用:调用此函数进行通信端口断开,即关闭串口
参数:gPortValue-端口号
返回值:1-断开成功,0-断开失败
**********************************************************************************/
int Drv_Disconnect(long gPortValue)
{int tmp_i16Rs232CloseFlag = 0;// set state (close aborts all open requests)// close serial port (port may have changed, former port shall not remain open)if(Rs232Close(gPortValue)==1)//sysGetVariableInt(getSysVarInt(PortNum_QianBo),PortValue){writeLineEx(0,kINFO, "Serial port %d successfully closed.", gPortValue);tmp_i16Rs232CloseFlag = 1;}else{writeLineEx(0,kERROR,"An error occurred during closing of the serial port %d.", gPortValue);tmp_i16Rs232CloseFlag = 0;}return tmp_i16Rs232CloseFlag;
}/*******************       通信端口连接         *********************************
函数作用:调用此函数进行通信端口连接,即打开串口
参数:gPortValue-端口号
返回值:1-连接成功,0-连接失败
**********************************************************************************/
int Drv_Connect(long gPortValue)
{int tmp_i16ConnectFlag = 0;// open the serial port (comes up with Windows defaults)if(Rs232Open(gPortValue)==1)//open success {writeLineEx(0,kINFO, "Serial port %d successfully opened.", gPortValue); tmp_i16ConnectFlag = 1;}  else{writeLineEx(0,kERROR,":An error occurred during opening of the serial port %d.", gPortValue);tmp_i16ConnectFlag = 0;   }return tmp_i16ConnectFlag;
}
/*******************       串口初始化函数         *********************************
函数作用:调用此函数进行串口初始化
返回值:1-初始化成功,0-初始化失败
**********************************************************************************/
int  Drv_initSerialPort()
{   int tmp_i16ConfigureFlag = 0;g_bySending = 0;// configure the serial port [ - just take the panel content]if(Rs232Configure(g_i32PortValue,g_i32BaudRateValue,g_i32DataBitsValue,g_i32StopbitsValue,g_i32ParityValue)==1){writeLineEx(0,kINFO, "Serial port %d successfully initialized.", g_i32PortValue);tmp_i16ConfigureFlag = 1;}else{writeLineEx(0,kERROR,"An error occurred during initialization of the serial port %d.", g_i32PortValue); tmp_i16ConfigureFlag = 0;} // port, handshake, xonLim, xoffLim, xonChar, xoffChar, writeTimeout// without last timeout parameter: use default timeout// for transmission of small amounts of data one may not need to use handshake ! // e.g. 33 for RTS/CTS as second parameter for large volumes of data, 0 for small volumesif(Rs232SetHandshake(g_i32PortValue, kHANDSHAKE_DISABLED, 0, 0, 0, 0))//setHandshake success{writeLineEx(0,kINFO, "Handshake parameters for serial port %d successfully configured.", g_i32PortValue);}else{writeLineEx(0,kERROR,":An error occurred during the serial port %d configuration of handshake parameters.", g_i32PortValue);}// set buffer for reception (otherwise callback would not work)if(Rs232Receive(g_i32PortValue, gReceiverCallbackBuffer, kBUFFER_SIZE))//Receive success{writeLineEx(0,kINFO, "Receiver buffer for serial port %d successfully set.", g_i32PortValue);    }else{writeLineEx(0,kERROR,":An error occurred during setting the receiver buffer for serial port %d.",  g_i32PortValue);  }return tmp_i16ConfigureFlag;
}/**************************      RS232发送函数            **************************
函数作用:串口发送函数,调用此函数进行数据发送
port    : 端口号;                buffer    ;  发送的数据(byte数组)
number  : 发送的数据长度;        DataType  :   发送方式(hex和text)
/*********************************************************************************/
int RS232SendData( dword port, byte buffer[], long number,char DataType[] )
{    byte ByteCrcBuffer[100];toUpper(DataType, DataType, elcount(DataType));//统一转换为大写if(number >= 100){write("RS232 ByteCrcBuffer out of range");number = 99;}ComFun_CopyBuffer(ByteCrcBuffer,0,buffer,number);//复制buffer给ByteCrcBufferif(strstr(DataType, "HEX")!=-1)//发送数据字符格式中包含HEX,即16进制发送{ ComFun_ModbusCRC16(buffer,number);//计算将要发送的数据的CRC码:TxByteBuffer进行CRC校验        ByteCrcBuffer[number] = g_byCrcResult[1];    //CRC处理,然后追加低字节number = number + 1;ByteCrcBuffer[number] = g_byCrcResult[0];  ///CRC处理,然后追加高字节number = number + 1;     if(0 == Rs232Send(port, ByteCrcBuffer, number))          //返回0-发送失败;返回1-发送成功{    writeLineEx(0,kERROR,"An error occurred during write of block of data to the serial port %d.", port);return 0;} else {//writeLineEx(0,kINFO, "Write block of bytes to serial port %d worked well.", port); return 1;}}else if(strstr(DataType, "TEXT")!=-1)//发送数据字符格式中包含TEXT,即文本形式发送{if(0 == Rs232Send(port, ByteCrcBuffer, number))          //返回0-发送失败;返回1-发送成功{    writeLineEx(0,kERROR,"An error occurred during write of block of data to the serial port %d.", port);return 0;} else {//writeLineEx(0,kINFO, "Write block of bytes to serial port %d worked well.", port); return 1;}}else{write("发送数据格式错误,请检查内容或方式");return 0;}// set stateg_bySending = 1;
}/************************        RS232接收函数      ******************************
函数作用:串口接收函数,RS232OnReceive works after first RS232Receive
RS232OnReceive 中的buffer == RS232Receive中buffer;
RS232OnReceive 长度number 和 RS232Receive长度 mysize 的关系 1<number<=mysize
**********************************************************************************/
RS232OnReceive( dword port, byte buffer[], dword number )
{char allStr[100];char iStr[5];int i =0;
//    int i; byte RecBuffer[100];long RxBytes;dword numberOfBytesToCopy;strncpy(allStr," ",100);for(i =0;i<number;i++){ltoa(buffer[i], iStr, 16);strncat(allStr, iStr,100);strncat(allStr," ",100);}//    write("%s",allStr);
//    write("///");// collect data as long as buffer has space for itif ( (gNumberOfReceivedBytes + number) > kBUFFER_SIZE ){numberOfBytesToCopy = kBUFFER_SIZE - gNumberOfReceivedBytes; // no more than that ! it is full now} else {numberOfBytesToCopy = number;}if ( numberOfBytesToCopy==0 ){return; // nothing to add}ComFun_CopyBuffer(gReceiverBuffer,gNumberOfReceivedBytes,buffer,numberOfBytesToCopy);//局部buffer赋值给一个全局buffergNumberOfReceivedBytes += numberOfBytesToCopy;                  //接收的字节个数// indicate data reception  sysSetVariableData(g_szRecvData,gReceiverBuffer,gNumberOfReceivedBytes);//接收数据赋给系统变量   }/*********************************************************************************
当RS232串口有错误时,触发RS232OnError事件
*********************************************************************************/
RS232OnError( dword port, dword errorFlags )
{// set stateg_bySending = 0;writeLineEx(0,kERROR,"Error handler called with error code %d !", errorFlags);if ( errorFlags & 1 )writeLineEx(0,1,"%d informs of send error",errorFlags);if ( errorFlags & 2 )writeLineEx(0,1,"%d informs of receive error",errorFlags);if ( errorFlags & 4 )writeLineEx(0,1,"%d informs of frame error",errorFlags);if ( errorFlags & 8 )writeLineEx(0,1,"%d informs of parity error",errorFlags);if ( errorFlags & 16 )writeLineEx(0,1,"%d informs of overrun error",errorFlags);if ( errorFlags & 32 )writeLineEx(0,1,"%d informs of receiver overrun error",errorFlags);if ( errorFlags & 64 )writeLineEx(0,1,"%d informs of break state",errorFlags);if ( errorFlags & 128 )writeLineEx(0,1,"%d informs of send timeout error",errorFlags);
}/*************************            byte数组复制函数      ****************************
函数作用:复制RS232Receive的数据到RS232OnReceive
destBuffer[]:目标byte数组               srcBuffer[]:源byte数组
destOffset  :模板byte数组偏置位         srcNumber[]:复制的位数
****************************************************************************************/
ComFun_CopyBuffer( byte destBuffer[], dword destOffset, byte srcBuffer[], dword srcNumber )
{dword i;for (i=0; i<srcNumber; i++){destBuffer[destOffset+i] = srcBuffer[i];}
}/***************************         CRC校验    *************************
函数作用:hex数据的16位CRC校验计算
16位CRC校验函数,低字节在前,高字节在后
data:byte数组,hex形式;           len:需要校验的数据位数;
************************************************************************/
ComFun_ModbusCRC16(byte data[], dword len)
{long crc ;int i,j;crc = 0xFFFF;for (i = 0; i < len; i++){crc  = crc ^ data[i];//write("%x",data[i]);//testing : print datafor(j = 0; j < 8; j++){ int m;m = crc & 1;crc= crc >> 1;crc = crc & 0x7FFF;if(m == 1){crc = crc ^ 0xA001;}crc = crc & 0xFFFF;}    }g_byCrcResult[0] = ((crc >> 8) & 0xFF);  //高字节g_byCrcResult[1] = crc & 0xFF;          //低字节
//    write("%x",CrcResult[1]);//testing : print CRC
//    write("%x",CrcResult[0]);//testing : print CRC
}
/// <

CANoe-RS485/RS232相关推荐

  1. 【工业级串口服务器E810-DTU】RS485/RS232转以太网,双向透明传输

    E810-DTU-V2.0是一款RS485 & RS232转以太网的单串口服务器,实现了RJ45网口与RS485或者RS232之间的数据透明传输.模块搭载M0+系列32位处理器,运行速率快,效 ...

  2. 微硬创新RS485/RS232/MODBUS转PROFINET(PROFINET转RS232/RS485/MODBUS)网关连接西门子PLC和新大陆工业条码扫描枪配置案例

    1.前言: 由于PROFINET网络协议逐渐在各种行业中得到广泛应用,同时条码技术的成熟和广泛应用,生产厂家采用条码标识其产品,在生产.库存.发货.销售.售后中采集产品信息,将扫码扫上来的数据要传送在 ...

  3. RS485/RS232/RS422接口定义

    RS485/RS232/RS422接口定义 rs422接口定义 rs232接口定义 rs485接口定义 Pin 信 号 定 义   RS-232 RS-422 RS-485 1 DCD TX- DAT ...

  4. UART/RS485/RS232

    RS485和RS232是物理总线. RS232 传输距离大概15米左右 只允许一对一通信 全双工 RS485 传输距离大概1200米 总线上允许接多达32个发射器和43个接收器 半双工 UART UA ...

  5. ETHERNET/IP转RS485/RS232网关profinet与Ethernet通讯卡

    网络数据传输遇到的协议不同.数据互通麻烦等问题,一直困扰着大家.然而,现在有一种神器--远创智控YC-EIP-RS485/232,它将ETHERNET/IP网络和RS485/RS232总线连接在一起, ...

  6. RS485,RS232,USB,Ethernet 传输速度分别是多少

    通讯速度,跟通讯用介质.通讯距离以及通讯环境等多项因素有关,一般情况下:1.RS-485的数据最高传输速率为10M 2.RS-232规定的速率为:50.75.100.150.300600.1200.2 ...

  7. RS485 RS232

    RS485:半双工,点对多,分布式网络通信,距离可达1200米. RS232:全双工,点对点,距离20米. 232/485转换器 转载于:https://www.cnblogs.com/embedde ...

  8. EMC设计攻略—各种接口电路的设计!RS485,RS232,以太网等等

    接口电路 接口电路多种多样,一般需电缆引出的接口电路需要较完备的电磁兼容设计,如CAN总线.RS485总线:其他的接口电路如RS232.USB等一般采用磁珠加TVS管设计. 1, RS485/CAN接 ...

  9. RS485,RS232,MODBUS三者之间的关系

    准确讲,MODBUS 叫做 "协议".通俗的讲就是俩个事物之间的通信的"规范".即通信双方要使用相同的协议才能理解彼此的意思.一个很好的例子就是我们的语言.中国 ...

  10. RS485/RS232串口通信实现源码

    之前贴出了代码,但是本地源码已经找不到了:本篇补充了一些使用说明 一.参考代码 1.不方便下载的同学可以参考贴出来的源代码链接:RS485 2.工程链接:RS485 二.基本知识 1.RS485通信讲 ...

最新文章

  1. Android--获取高清的app图标
  2. 基于Http替补新闻WebService数据交换
  3. 想要转人工智能,程序员该如何学习?(学习路线、知识体系)
  4. DPDK Qos之报文处理流水线
  5. hl3150cdn打印不了照片_如何在美国打印证件照片 (Passport Photos)?
  6. 照片浏览器_2020护考报名失败!只因照片太大瞎忙乎三小时...
  7. C#中的换行符、回车
  8. 《Unity3d脚本编程 使用C#语言开发跨平台游戏》读书笔记2
  9. EditText属性大全详解
  10. 股票量化交易有哪些潜在的风险?如何去避免?
  11. 解决Strokeit在win8下的图标问题和开机启动问题
  12. SEO 优化--助力网站推广
  13. 【Python语音分析】从绘制好看的波形图和语谱图开始
  14. 【矩阵计算】QR分解-基于Householder变换
  15. 中国用于先天性代谢错误的医用食品市场深度研究分析报告
  16. Windows10设置挂起(休眠)
  17. 某宝 小黑屋 x-sg?xt x-si?n x-m?ni-w?a 分析学习
  18. dnf加物理攻击的卡片有哪些_dnf物理攻击宝珠_dnf2019物理攻击宝珠大全_快吧游戏...
  19. ios打包报错: DXT1 compressed textures are not supported when publishing to iPhone
  20. bzoj3663/4660CrazyRabbit bzoj4206最大团

热门文章

  1. 虹科案例 | EtherCAT运动控制器与IO在半导体封装设备固晶机上的应用
  2. 【android】解决android SDK 模拟器 运行缓慢
  3. 乐山市计算机学校的董事长是,乐山市计算机学校举行22周年校庆活动
  4. 《程序员修炼之道:从小工到专家》
  5. win7重装win10解决错误代码0x80072F8F
  6. xshell 字体大小和界面字体太小问题解决
  7. 创建shell文本,显示目前身份、所在目录、输入数,累加显示结果
  8. 网络经济学——第二章 网络外部性
  9. PHP Web项目部署记录(一)
  10. 入门精通web前端:三大核心HTML5、CSS3 、JS必学