当前位置:网站首页>基于485总线的评分系统双机实验报告
基于485总线的评分系统双机实验报告
2022-07-06 09:24:00 【芜湖韩金轮】
本来还想着做多机的,但老师已经打分了就算了。为了压缩到6页删减了很多内容,将就看吧
基于485总线的评分系统实验报告
实验目标:
通过本案例加深理解RS485通信方式,实现上位机的主控制器与所有的下位机进行通信。
B级任务
实验要求:
使用两块STC板分别下载上一节所提供的.hex文件,搭建485双机通信电路,在linux中编程实现打分程序代码。
实验资源:Windows10电脑,Ubuntu18.04,单片机,杜邦线
实验步骤:
阅读程序系统流程框图,明确双机通信的功能需求。
熟悉上一节中模拟MODBUS协议的数据包结构,相关功能码及附加数据定义
回顾485总线数据收发实验,搭建双机通信电路。
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++代码,同时对于单片机的使用和串口助手软件的使用更加得心应手,对于单片机的一些按键能够简单使用。
边栏推荐
- How to learn automated testing in 2022? This article tells you
- Statistics 8th Edition Jia Junping Chapter 4 Summary and after class exercise answers
- 指針:最大值、最小值和平均值
- Zhejiang University Edition "C language programming experiment and exercise guide (3rd Edition)" topic set
- STC-B学习板蜂鸣器播放音乐2.0
- Pointer -- eliminate all numbers in the string
- 【指针】查找最大的字符串
- The four connection methods of JDBC are directly coded
- MySQL中什么是索引?常用的索引有哪些种类?索引在什么情况下会失效?
- [issue 18] share a Netease go experience
猜你喜欢
1.支付系统
How to transform functional testing into automated testing?
数字电路基础(一)数制与码制
Login the system in the background, connect the database with JDBC, and do small case exercises
Fundamentals of digital circuits (I) number system and code system
Want to learn how to get started and learn software testing? I'll give you a good chat today
内网渗透之内网信息收集(三)
Interview Essentials: what is the mysterious framework asking?
STC-B学习板蜂鸣器播放音乐2.0
What is the transaction of MySQL? What is dirty reading and what is unreal reading? Not repeatable?
随机推荐
Statistics 8th Edition Jia Junping Chapter IX summary of knowledge points of classified data analysis and answers to exercises after class
{1,2,3,2,5} duplicate checking problem
Keil5-MDK的格式化代码工具及添加快捷方式
Fundamentals of digital circuit (V) arithmetic operation circuit
数字电路基础(五)算术运算电路
Common Oracle commands
Install and run tensorflow object detection API video object recognition system of Google open source
《统计学》第八版贾俊平第三章课后习题及答案总结
Four methods of exchanging the values of a and B
The salary of testers is polarized. How to become an automated test with a monthly salary of 20K?
Statistics 8th Edition Jia Junping Chapter 4 Summary and after class exercise answers
函数:求方程的根
Statistics 8th Edition Jia Junping Chapter 5 probability and probability distribution
【指针】八进制转换为十进制
STC-B学习板蜂鸣器播放音乐
Detailed introduction to dynamic programming (with examples)
[HCIA continuous update] advanced features of routing
[oiclass] share prizes
《统计学》第八版贾俊平第六章统计量及抽样分布知识点总结及课后习题答案
Build your own application based on Google's open source tensorflow object detection API video object recognition system (I)