基于485总线的评分系统双机实验报告

基于485总线的评分系统双机实验报告,第1张

本来还想着做多机的,但老师已经打分了就算了。为了压缩到6页删减了很多内容,将就看吧

基于485总线的评分系统实验报告 实验目标:

通过本案例加深理解RS485通信方式,实现上位机的主控制器与所有的下位机进行通信。

B级任务 实验要求:

使用两块STC板分别下载上一节所提供的.hex文件,搭建485双机通信电路,在linux中编程实现打分程序代码。

实验资源:Windows10电脑,Ubuntu18.04,单片机,杜邦线 实验步骤:
  1. 阅读程序系统流程框图,明确双机通信的功能需求。

  2. 熟悉上一节中模拟MODBUS协议的数据包结构,相关功能码及附加数据定义

  3. 回顾485总线数据收发实验,搭建双机通信电路。

  4. PC端串口设置如下:串口波特率:9600 数据位:8位 校验位:无 停止位:

5.所编写的PC端程序应参考上一节中的通信协议完成一次完整的评分过程:

  • 需要包含串口的设置

  • 主节点发起从机检测过程:发送指定从机编号正常检测数据包,判断回应查询数据包是否符合上一节中的通信协议。

  • 主机获取从机评分过程:发送指定从机评分相关数据包,判断回应查询数据包是否符合上一节中的通信协议。

  • 主机发起结束评分的过程,若复位成功,STC从机上第1位和第8位LED 灯会熄灭。

  • 展示串口相关信息,展示检测到的从机编号和从机的评分等。

代码设计思路:

1.定义了几个本次实验要用到的函数:

string format(const vector<uchar> &data);		  //数据处理为字符串
int check(serial &pipe, int addr);				 //设备检测
int get_score(serial &pipe, int addr);			  //获取分数
void reset(serial &pipe);				         //从机复位

2.接下来是主函数,首先从单片机读入数据,波特率设为9600(题目已给出)

serial pipe("/dev/ttyUSB0", B9600);

3.接着根据题目的要求根据用户输入来选择想要的功能。第一个是根据单片机的编号查找对应的分数,第二个是将从机复位,第三个是退出程序,通过设置循环来重复用户的选择。具体代码如下:

    while(1){
        cout<<"--------------------基于RS485总线的评分系统-------------------------"<<endl;
        cout<<"输入说明:\n1. 输入合法从机地址查询分数\n2. 输入-2将从机复位\n3. 输入-1退出程序\n请输入指令:";
        cin>>addr;
        if(addr == -1) break;
        if(addr == -2) {
            reset(pipe);
            continue;
        }
        check_ret = check(pipe, addr);
        if(check_ret == 1){
            cout<<"设备检测正常"<<endl;
            sleep(1);
    	    if(!(score = get_score(pipe, addr)))
    	        cout<<"获取分数失败"<<endl;
    	    else 
    	        cout<<"分数:"<<score<<endl;
        }
        else if(check_ret == 0){
            cout<<"地址错误,请输入地址重试"<<endl;
            continue;
        }
	else{
	    cout<<"数据传输错误,请重启从机"<<endl;
	}        

        //reset(pipe);
        cout<<"从机已复位,输入-1退出"<<endl;
    }

可以看到,输入-1时退出循环,然后return 0退出程序。输入-2时调用reset函数使从机复位。输入正确的从机编号后就会输出对应的成绩,主要是通过调用check函数来检测从机编号是否正确,调用get_score来获得成绩,下面具体再分析一下这三个函数的实现思路。

4.reset函数完整代码:

void reset(serial &pipe){
	vector<uchar> code = {0x5a, 0x00, 0x01,0x00,0x5b};
	//cout <<"reset:"<< format(code) << endl;				
	/* 发送数据包 */
	for(int i=0;i<600;i++) {
	    pipe.myWrite(code);
	}
	return;	    
}

参数值是serial串口的数据,根据实验指导可以知道,当主机要发送复位信号给从机时,其序列号应为5a + 广播地址00 + 复位功能码01 + 00 +校验字节,所以实现思路就是定义一个字符串序列号,然后通过主机不断向从机发送数据包,最终实现从机复位。

5.check函数完整代码:

int check(serial &pipe,int addr){
	int check_code = 117 + addr, ret;				//校验码为累加和
	vector<uchar> code = {0x5a, 0x08, 0x13};
	vector<uchar> rec;
	code.insert(code.begin()+1, (uchar)addr);			//插入从机地址
	code.push_back((uchar)check_code);				//插入校验码
	//cout << format(code) << endl;					
	/* 写入并接收回应数据包 */
	pipe.myWrite(code);
	sleep(1);
	rec = pipe.myRead(5);
	if(format(rec) == format(code))				//检验接收数据包是否与发送相同,相同则从机地址正确
	    ret = 1;
	else{
	    if(rec[3] == 0x6f) ret = 0;
	    else ret = -1;
	}
	return ret;	    
}

函数的参数为串口数据和从机地址。主机发送进行数据检测的序列号为5a + 从机地址 + 检测功能码08 + 13 + 校验码 。实现思路就是将数据检测序列号写入,然后根据收到的数据包来判断从机地址是否正确。如果返回1说明地址正确,返回0说明地址错误,返回-1说明数据错误。

6.get_score函数完整代码:

int get_score(serial &pipe, int addr){
	int check_code = 93 + addr, ret;				//校验码为累加和
	vector<uchar> code = {0x5a, 0x00, 0x03};
	vector<uchar> rec;
	code.insert(code.begin()+3, (uchar)addr);			//插入从机地址
	code.push_back((uchar)check_code);				//插入校验码
	//cout << format(data) << endl;					
	/* 写入并接收回应数据包 */
	pipe.myWrite(code);
	sleep(1);
	rec = pipe.myRead(5);
	if(rec[3] == 0x6f) ret = -1;					//检验是否错误
	else {
	    ret = (int)rec[3];						//转为数字
	    if(ret < 0 || ret > 100) ret =-2;				//检测数字是否合法
	}
	return ret;	    
}

函数的参数为串口数据和从机地址。主机发送进行分数获取序列号为5a + 00 + 读取功能码03 + 从机地址 + 校验码 。实现思路和上一个函数一样,将数据检测序列号写入,然后根据收到的数据包来获得分数,同时要对分数的合法性进行判断。如果正确则返回正确分数,返回-1说明从机未准备好,返回-2说明从机错误。

7.format函数完整代码如下:

string format(const vector<uchar> &data) {
    std::string str(2 * data.size() + 1, '\x00');
    for (int i = 0; i < data.size(); i++) {
        sprintf(&str[i * 2], "%02X", data[i]);
    }
    return str;
}

函数的功能主要是将数据处理为字符串,在check函数中使用

验证及结果分析:

这里设置下位机的编号为2号,分数为66分

打开程序,运行后输入从机编号2可得成绩,输入-2可复位从机,输入-1可退出程序

可以看到,结果正确,当输入正确的从机地址2时,输出了分数66。当输入了-2时,从机就会复位,效果如第一张图所示,单片机上的第一个和第八个灯熄灭。当输入-1时,直接退出程序。

实验总结:
  • 人文:认识到交流的重要性。很多不懂的问题通过和同学交流都得到了有效解决。同时遇到问题时可以向老师虚心求问。
  • 知识:掌握了基于485总线的评分系统的工作原理和具体实现。学会了如何获取串口数据,并利用串口数据进行一些判断。还学会了如何使用c++来实现基于485总线的评分系统的双机评分。
  • 技能:能够较快的编写出c++代码,同时对于单片机的使用和串口助手软件的使用更加得心应手,对于单片机的一些按键能够简单使用。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1499165.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-25
下一篇 2022-06-25

发表评论

登录后才能评论

评论列表(0条)

保存