3.1 准备工作
这部分需要我们安装好linux的Ubuntu操作系统。
由于安装虚拟机占用空间较大还有个人偏好的原因,我安装的是WSL(Windows Subsystem for Linux),就是Win10子系统的Linux。具体操作上还是没有差别的。
3.2 Linux操作系统平台
一、实验目的
1、了解Linux系统文件系统的基本组织
2、了解Linux基本的多用户权限系统
3、熟练使用ls、cd、cat、more、sudo、gcc、vim等基本命令
4、会使用ls和chmod命令查看和修改文件权限
实验步骤
1、在Linux虚拟机中,安装下面附件中的firstrun.deb包(数据包在学习通对应的章节)
2、安装成功后,运行根目录下的/gettips可执行程序。该程序将在屏幕上给出下一步骤要探索的目录。
3、在第2步给出的目录中存在一个文件,请找到这个文件并将文件内容显示在屏幕上。
4、使用如下命令将文件内容提交到本次实验服务器,其中xxxxxxxxxx请用读取到的文件内容代替,iiiiiiiiiii用自己学号代替。请同学们务必正确输入自己的学号。
curl “132.232.98.70:6363/check?id=iiiiiiiiiiii&v=xxxxxxxxxx”
(ps.1-3步的截图都是写报告的时候重新截的图,因为之前忘记截图了。第4步的图是当时上课截的图,但是第一次提交忘记截图了,所以是DUP。最后,两次截图的电脑的设备命不一样是因为我重装系统了,痛苦。)
3.3 Linux平台串口数据接收
一、实验目的
1、熟练使用Linux下io函数read、write和epoll函数
2、了解Linux设备文件机制
3、熟练使用示波器识读UART波形
二、实验说明
实验使用示波器抓取STC单片计算机板发送的UART信号,分析该信号的波特率,根据识读到的结果编写Linux程序读取UART串口所收到的数据。
UART串口是通过移位寄存器将所传输的数据按时间顺序进行传输的方式。信号线在没有数据传输时保持高电平。信号以下降沿表示传输开始。传输开始时,UART固定传输一个码片时间的低电平作为起始位,然后开始移位所传输载荷数据的最低比特。
每次传输可以传输7比特、8比特或者9比特数据,可以选择带奇偶校验位,最后再固定传输一个码片宽度的高电平作为停止位。
例如,最主流的UART串口配置是8N1,就是1个起始位、8个数据位,1个停止位,无奇偶校验位。又例如下图所示,就是1个起始位,7个数据位,1个奇偶校验位,1个停止位。
由于UART串口没有时钟信号,所以需要通信双方约定一个码片的时间长度。人们习惯使用波特率来表示每秒钟所能发送的码片数量。码片长度越长,波特率越低;码片长度越短,波特率越高。常用的波特率有1200、1800, 2400, 4800, 9600,19200, 38400, 57600, 115200等。这次实验所用的波特率都是常用波特率。
实验所用STC单片机,下载dut1.hex文件后会主动按照以下格式发送数据。本次实验是要正确获取序列号内容。
三、实验内容
1、按照3.3.1节说明,向STC单片计算机板下载程序
运行软件点击文件->打开程序代码文件选dut7.hex,点击下载编程,再按一下板子上摇杆正左边的红色按钮就开始下载程序了,软件的右下方有进度提示。
2、使用示波器观察STC单片机UART串口输出信号,识别单片机发送数据所使用的波特率。
示波器忘记拍照了。用示波器读波特率就是单次触发看波形间距和设置的间距作比较,用1秒除以这个间距的值就能估算出波特率。
根据单片机串口波特率,编写C语言程序从虚拟机的串口读取信息。下面是不完整的参考示例,可以根据自己需要进行修改
修改com.c中的波特率。
修改main.c中串口与软件中显示的接口一致,编译运行:
这里也能看到与STC-ISP软件读到的数据一致
4、使用如下命令将序列号提交到本次实验服务器,其中112233445566778899AABB请用读取到的序列号代替,iiiiiiiiiii用自己学号代替。请同学们务必正确输入自己的学号。
curl “132.232.98.70:6363/checkBaud?id=iiiiiiiiiiii&v=112233445566778899AABB”
截图不见了,呜呜呜
3.4 计算机串口数据收发与测量
一、实验目的
1、熟练使用Linux下io函数read、write和epoll等
2、熟练处理流式通信数据
二、实验过程
1、向STC单片机下载下面的程序
下载程序后,单片机将使用1200波特率发送自身序列号,格式同上一节课(3.3节内容)相同。请记录下该序列号。
2、向串口写入自己的学号,格式为
0xAA 0x55 十二位学号数字。
例如学号20220110203,应该通过串口发送以下数据
AA 55 02 00 02 02 00 01 01 01 00 02 00 03
3、STC单片机接收到学号后会发送第一串密码,密码长度为4字节。请将解析出该串密码并原样发回给串口。STC单品机收到返回后会继续发送下一串密码,请继续解析出该串密码并原样发回给串口。以此往复,将收到的最后一串密码记录下来。
这里用那个程序做因为信号传输速度很快,手速跟不上,所以收发不了几次就不行了,这里我们写C语言程序来跑。
首先将com.c中波特率改为1200,main.c中串口名称改成和软件读取的那个串口。
WSL用这个代码替换main.c(记得改学号和串口)
#include <stdio.h>
#include "com.h"
#include "com.c"
#include <assert.h>
int main(void)
{
//unsigned char tmp[15] = {0}; //用于存放读取出来的数据的缓冲区
int rl; //读取数据的长度(单位:字节)
fd = openSerial("/dev/ttyS3"); //打开串口,ttyUSB0是串口文件
if(fd < 0)
{
printf("open com fail!\n");
return 0;
}
EpollInit(fd); //初始化终端事件触发函数epoll,设置要监听的事件及相关参数等
unsigned char number[14] = {0xAA,0x55,0x02,0x00,0x02,0x00,0x00,0x08,0x00,0x01,0x00,0x03,0x00,0x03};
write(fd, number, sizeof(number));
unsigned char tmp[19] = {0};
unsigned char fill[6] = {0};
while(1)
{
int i;
//bzero(tmp,sizeof(tmp)); //把tmp对应的内存块的前sizeof(tmp)置零
rl = ComRead(tmp,18);//读取18个字节放到缓存
assert(rl > 6);
//打印读到的数据
printf("read_len = %d\n", rl);
tmp[rl] = '\0';
for(i = 0; i < rl; i++)
printf(" %02x", tmp[i]);
printf("\n\n");
for(i = 0; i < 6; i++)
{
if(i == 0)
fill[i] = 0xAA;
else if(i == 1)
fill[i] = 0x55;
else
fill[i] = tmp[(int)tmp[2]-3+i];
}
for(i = 0; i < 6; i++)
printf(" %02x", fill[i]);
printf("\n\n");
//unsigned char fill[6] = {0xaa, 0x55, 0xe4, 0xc3, 0x11, 0x7a};
bzero(tmp, 19);
if(write(fd, fill, 6) > 0)
printf("Write success\n");
bzero(fill, 6);
}
close(epid);
close(fd);
return 0;
}
用虚拟机的同学问问身边朋友肯定能要到代码(滑稽.jpg)
也许是因为我用的wsl的缘故通信有优化,代码写的很简洁也能得出正确的结果,我的代码在舍友的虚拟机上跑不了,舍友写的代码在我这里也读不到数据。
4、将学号、序列号、最后一串密码发送到课程后台。上送命令语法为
curl “132.232.98.70:6363/checkSecret?id=学号&v=序列号&s=密码”
例如,序列号是A01D564D744A42C9363F5E,学号是202201110203,最后一串密码为51ED8D3A,那么上报结果命令为:
curl “132.232.98.70:6363/checkSecret?id=202201110203&v=A01D564D744A42C9363F5E&s=51ED8D3A”