很多的成品模块,在使用时往往需要通过串口进行数据的读取,所以笔者为了快速实现模块数据的读取,便使用Proteus软件仿真一块arduino,再编程实现数据交互。
创建Proteus工程
首先新建一个arduino Mega 2560的工程,并按照自己的需求绘制原理图。上图中的左边开发板部分为成功创建工程后就存在,右边第一个元器件为VIRTUAL TERMINAL,相当于串口助手,第二个元件为串口连接组件,第三个元器件为DS1302时钟,笔者是为了显示时间,这个元器件非必要。前两个在哪里找到可以看下面的图片。
这两个元器件的具体的使用方法就不在赘述了(需注意的是COMPIM的电路连接方式与平常串口通信的连线方式不同),使用时双击进入属性界面,参数一目了然。
接下来就是在Source Code界面编写程序即可。
编写程序
如果打开工程时,没有Source Code界面,可点击上图中红色箭头处打开。
然后编写几个必要函数即可,具体代码如下。
void setup()
{
Serial.begin(9600); //与COMPIM元器件连接
Serial1.begin(9600); //与VIRTUAL TERMINAL元器件连接
delay(200);
Serial1.println("Start!!!");
}
void loop()
{
Send_Data(0x0055, 0x000C);//发送函数
delay(100);
Receive_Data();//接收函数
delay(2000);
}
void Send_Data(uint16_t function0, uint16_t adrr0)//根据模块协议自行编写
{
data[0] = 0x01;
data[1] = 0x03;
data[2] = function0>>8;
data[3] = (uint8_t)function0;
data[4] = adrr0>>8;
data[5] = (uint8_t)adrr0;
uint16_t crc_data = crcx::crc16(data, len-2);//计算数据CRC数据
data[6] = (uint8_t)crc_data;
data[7] = crc_data>>8; //计算CRC校验
Serial.write(data, len);//发送消息
}
void Receive_Data()
{
if(Serial.available()&&(rx_flag==0)) //判断串口缓存区
{
Serial.readBytes(serialBuffer, bufferLength); //读取一帧数据
uint16_t crc_data = (uint16_t)serialBuffer[28]<<8 | serialBuffer[27];//读取消息中CRC数据
uint16_t crc_cal = crcx::crc16(serialBuffer, bufferLength-2);//计算数据CRC校验
if(crc_data == crc_cal)
{
rx_flag=1;
}
else Serial1.println("rec err!!");
}
if(rx_flag==1)
{
Data_Deal();//调用数据处理函数,根据模块协议自行编写即可
Serial1.println("rec ok!!");
rx_flag=0;
}
}
上述代码中用到了CRCx库,可以在Arduino IDE中搜索添加。
根据模块编写完程序之后,可以自己安装虚拟串口软件后,再使用串口助手验证数据是否正确。
在这过程中,还有一点可以说的。可以使用以下代码将四字节十六进制数转换为单精度浮点数据。
uint32_t x=0;
float *Rec_data = (float *)(&x);
Data=*Rec_data;
原理图和程序都弄好之后,仿真运行效果如下图(如果没有Virtual Terminal窗口,可以在菜单栏的Debug中找到):
总之,实现方法很简单。在手上没有开发板,又不是很会用C#写上位机时,作为快速开发还是蛮有用的。