计算机串口使用与测量
3.1准备工作
这里由于直接下载好了VMWork Workstation 16 ,所以选择直接使用VMWork Workstation 16 。
3.2Linux操作系统平台
一、实验目的:
- 了解Linux系统文件系统的基本组织
- 了解Linux基本的多用户权限系统
- 熟练使用ls、cd、cat、more、sudo、gcc、vim等基本命令
- 会使用ls和chmod命令查看和修改文件权限
二、实验基础
这里主要是使用chmod改变文件的权限,这样来读出隐藏文件中的内容,使用这个内容和我们的学号上传到实验平台上到出现OK即为实验成功。
三、实验步骤
1、在Linux虚拟机中,安装下面附件中的firstrun.deb包(这里很容易就可以移到虚拟机中,但是需要注意直接拖动的话是需要tools的)
2、安装成功后,运行根目录下的/gettips可执行程序。该程序将在屏幕上给出下一步骤要探索的目录。
找到了文件所在的目录,使用cd到达对应目录。使用ls发现其中没有任何文件,这时候可以使用ls -a来检查其中有没有隐藏文件,发现如下图:(a.out和text.c是后面自己编写程序所产生的)
3、发现了隐藏文件.answer,发现使用gedit .answer无法直接打开,出现权限不够的错误。进入最高权限模式也就是sudo su,然后输入密码就可以获得最高权限,在最高权限输入chmod -c 777 .answer就可以在正常的命令行打开这个文件了。
修改完权限之后,使用gedit .answer可以看到如下结果:
上面就完成了第三步。
4、使用如下命令将文件内容提交到本次实验服务器,其中xxxxxxxxxx请用读取到的文件内容代替,iiiiiiiiiii用自己学号代替。请同学们务必正确输入自己的学号。
在widows或者linux的命令行中输入curl "132.232.98.70:6363/check?id=202008010206&v=3350344850"可以得到如下的结果:
至此,实验3.2的内容基本完成。
5、(选作内容)这里选择使用取巧的方式,本来是需要采用文件读写的方式来实现的。既然这里已经知道文件里面的内容,就可以直接将它复制出来,然后在C程序中以16进制输出到屏幕上,所以最后的结果为:
3.3Linux平台串口数据接收
一、实验目的
- 熟练使用Linux下io函数read、write和epoll函数
- 了解Linux设备文件机制
- 熟练使用示波器识读UART波形
二、实验说明
在这里,简单地叙述一下实验的内容。这次我们需要做的是使用示波器抓取STC单片计算机板发送的UART信号,分析该信号的波特率,根据识读到的结果编写Linux程序读取UART串口所收到的数据,这个数据也就是单片机的序列号。
实验所用STC单片机,下载dut1.hex文件后会主动按照以下格式发送数据。本次实验是要正确获取序列号内容。
字节1 | 字节2 | 字节3-字节13(共11字节) |
---|---|---|
0xAA | 0x55 | 序列号 |
三、实验内容
1、按照3.3.1节说明,向STC单片计算机板下载程序
这里直接跳转到3.3.1节,为3.3的实验打下基础:
发现,这里是下载驱动程序和一个软件,只需要跟着做很快就可以做出来。
2、使用示波器观察STC单片机UART串口输出信号,识别单片机发送数据所使用的波特率。
根据视频,我们首先向板子上下载程序,下载成功之后,将一端接地,另一端接UART端口,然后调整是下降沿触发,触发电压是2.5V左右,同时这里需要注意我们接在哪个源上就需要选择输出哪个源上的信息。之后,我们使用示波器上面的STOP按钮,找到一个屏幕上有13个左右的波形,然后调整示波器的标尺,直到一个的大小和波形的一个波差不多大为止,下面就是最终的结果:
我们可以知道该单片计算机的波特率为1s/500us也就是接近1800的波特率(这里我们根据单片机所有可能的波特率中选择一个最接近的波特率即可)。
3、根据单片机串口波特率,编写C语言程序从虚拟机的串口读取信息。下面是不完整的参考示例,可以根据自己需要进行修改。
将这三个程序移到虚拟机中,修改com.c中的波特率为1800
然后编译main.c,之后使用./a.out的时候会发现,出现了权限不够的报错。和上面一样的方法改变权限,然后再次./a.out即可输出我们想要的结果。
STC单片机计算串口发出来的内容格式为:
0xAA 0x55 序列号
以上内容为二进制数据表示,共13个字节。例如:
0xAA 0x55 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xAA 0xBB 。
其中0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xAA 0xBB 就是该单片机的序列号。请用程序读出所领单片机的序列号。
根据上述的例子,我知道自己的序列号为A0 1D 56 5D 74 77 CB 09 2B 21 C9。(由于当时忘记截图了)
4、使用如下命令将序列号提交到本次实验服务器,其中112233445566778899AABB请用读取到的序列号代替,iiiiiiiiiii用自己学号代替。请同学们务必正确输入自己的学号。
使用指令curl “132.232.98.70:6363/checkBaud?id=202008010206&v=A01D565D7477CB092B21C9”,即可获得OK即为我们想要的结果。
3.4计算机串口数据收发与测量
一、实验目的
- 熟练使用Linux下io函数read、write和epoll等
- 熟练处理流式通信数据
二、实验过程
1、向STC单片机下载下面的程序
下载程序后,单片机将使用1200波特率发送自身序列号,格式同上一节课(3.3节内容)相同。请记录下该序列号。
这里可以选择使用串口助手,很容易就可以得到序列号为:A0 1D D7 A0 1A 5A 79 66 41 CA 90。
2、向串口写入自己的学号,格式为
0xAA 0x55 十二位学号数字。
例如学号20220110203,应该通过串口发送以下数据
AA 55 02 00 02 02 00 01 01 01 00 02 00 03
解:很容易就可以看出来规律,也就是学号的每一位前面加上一个0,然后组成一个序列,同时最前面需要加上AA 55。
3、STC单片机接收到学号后会发送第一串密码,密码长度为4字节。请将解析出该串密码并原样发回给串口。STC单品机收到返回后会继续发送下一串密码,请继续解析出该串密码并原样发回给串口。以此往复,将收到的最后一串密码记录下来。
例如,收到以下密码串
AA 55 0A 00 00 00 00 00 00 C9 34 3F 5D
其中AA 55为前导串,0A表示起始字节是第10字节。请将密码原样发回给串口。
AA 55 C9 34 3F 5D
解:也就是输入学号之后,可以得到返回出来的对应的结果为第一个密码,然后再将第一个密码通过串口助手发送过去之后会返回第二个密码,这时则需要依次往后。使用串口助手,可以得到的次数很少,最后还是需要编写程序。
这里,直接将第5部分的解答给出:
import serial
import requests
import serial.tools.list_ports
#字符串转字符串
def b2s(data):
return ''.join([f'{ch:0>2x}'for ch in data]).upper()
#连接设备
ser=serial.Serial(list(serial.tools.list_ports.comports()[0])[0],1200)
#判断是否连接到设备
assert(ser!=None)
#输入学号
studentID=input("学号:")
#判断学号是否正确
assert(studentID.isdigit() and len(studentID)==12)
#读入序列号
number=b2s(ser.read(13))
#断言魔数为AA55
assert(number[:4]=="AA55")
#取出序列号
number=number[4:]
assert(len(number)==11*2)
print(f'序列号:{number}')
#使用学号构造即将发送的字节数据
startData=b'\xaa\x55' +bytes([ord(ch)-ord('0') for ch in studentID])
#写入设备
ser.write(startData)
password=b'' #读到的密码
i=1 #循环次数
#开启永真循环,直到ctrl+c被按下
try:
while True:
#读1位,探测魔数
t=b2s(ser.read(1))
#第一个魔数应该是AA
if t !="AA":
continue
#再读一位
t=b2s(ser.read(1))
#第二个魔数应该是55
if t !="55":
continue
#判断魔数后可以放心读取数据
#读入密码开始位置的索引
index=list(ser.read(1))[0]
#若索引大于4,则表明中间有无关字节,吸收掉无关字节
if index-4 >0:
ser.read(index -4)
#读入四字节的密码
password=ser.read(4)
print(f'[{i}]密码:{b2s(password)}')
#使用这次读到的密码构造数据,发送给设备以读取下一次的密码
ser.write(b'\xaa\x55'+password)
i+=1
运行该程序(如果出现少包就使用pip install),就可以得到对应的结果如下:
得到密码为6041C890。
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”
解:根据上面得到的密码输入上述指令即可得到如下结果:
至此,实验全部完成。