查看: 8570|回复: 9

串口接收与发送字符、数值、ASII和HEX

[复制链接]

41

主题

167

帖子

3102

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3102
发表于 2021-12-11 17:35:27 | 显示全部楼层 |阅读模式
本帖最后由 zly188 于 2021-12-12 09:23 编辑

天问系列的32位芯片,用一个hardwardSerial类封装了串口,让串口发送和接收更加简单了。但很多初学者对串口原理不是清晰,对ASII和HEX没有理解,在串口通信中就会出错而使通信不成功。本文将从字符编码,8位单片机、32位单片机来讲述串口发送的一些知识。

1.二进制数、字符、数值、ASII码和HEX的区别与转换,下面我们用一个实验来说明。
实验准备天问系列任一开发板,串口助手(用STC-ISP内置)。
有一个八位二进制数00110001,准备用串口发送到串口助手。天问Block没有二进制串口发送模块不能直接发送二进制,要把这个二进制数转换成十六进制数,十六进制转换0011->3、0001->1,写作0x31,十进制的值就是49。
天问51串口发送指令:
0x31.png 49.png
天问32位系列串口发送指令:
320x31.png 3249.png
编写程序重复执行每1秒发送一次。
1000send.png
我们用串口助手打开,接收数据,你会发现,串口助手有两种数据显示模式,一种文本模式、一种是HEX模式。
文本模式显示:
wenben.jpg
HEX模式显示:
hex.jpg

串口发送程序修改为发送49.
4949.png
接收结果相同。
为什么文本模式是1呢?HEX模式是0x31?

ASCII码表解开秘密。
单个字符(文本)就是一个8位单字节数。字符、16进制、10进制对应表如下:
ascii.jpg
发送字符0x31就是二进制数0011 0001,十进制49,字符'1'这里是字符不是字符串也不是数字。

2.串口如何发送十六进数?
从以上分析我们可以看出,串口输出十六进制数直接用32位芯片用“串口原始输出”指令、8位芯片用“串口发送字符”,输出的值可以直接用"0x"加上值表示。一条指令只能发送一个8位二制数,不能一条指令发送多个数,需要输出多个数,就要用多条发送指令。在天问ASR中控制外部设备经常用到。多条图形指令代码如下图:
8位51单片机图形化指令。

多字节.png
32位芯片图形化指令。
多字节.png
串口不管发送什么内容,实际都是按这种模式1个字节1个字节发送的。字符串的发送方式就是每个字节一个字符,多个字符组成字符串;整数值的发送一个字节就是8位数,二个字节就是16位数,四个字节就是32位数。

3.串口如何发送字符串?
字符串的本质就是多个字节组成的字符。如串口发送"hello",实际是串口发送5个字节,第一个字节'h'(16进制是0x68)、第二个字节'e'(16进制是0x65)、第三个字节'l'(16进制是0x6c)、第四个字节'l'(16进制是0x6c)、第五个字节'o'(16进制是0x6f)。那我们可以用串口原始输出16进制数,就可以在串口助手看到"hello"字符串。
8位51单片机程序
多字节.png
串口助手文本模式可看到
hello.jpg
32位用串口原始输出模式自己可以参照8位机编写。

'h'的16进制值是0x68,我们也可以用字符的形式来代替16进制,这样就更加方便不用去查询ASCII表。
用字符代替16进制数程序就可以修改成如下所示:
多字节.png
字符图形块在“文本与数组”指令里,第二个单引号图标的就是字符。我们的原始输出和发送字符每次只能发送一个字节,要连续发送字符就要用到发送字符串图形指令。

用字符串发送8位51单片机程序就修改成如下所示:
多字节.png
用字符串发送32位芯片如天问ASR程序就修改成如下所示:
多字节.png
32位用串口打印指令。

4.如何打印回车换行?
我们在打印字符串时,可以看到字符串没有换行一个字符串接一个字符串。要实现换行就需要在字符串末位加上回车符和换行符。回车符转义符表示形式是'\r',16进制值是0x0d;换行符转义符表示形式是'\n',16进制值是0x0a。所以在输出结尾可以加上输出字符'\r'和'\n'或输出16进制0x0d、0x0a就可以回车换行。
程序如下:
多字节.png

5.如何从串口接收字符串?
串口接收本质上也是采用中断模式接收,每次只接收一个8位字符数,字符串是多次接收字符后的一个组合。这就需要设定一个数组和一定的同步协议,可以根据时间判断接收是否一个字符串结束或根据一定的帧头和帧尾格式来判断。
每次接收一个字符存到数组,数组指针加一,不断的接收和存入数组中。由于发送一个字符串每个字符间的间隔会比较短,发送结束后,会间隔相对较长的时间,当超过这个等待时间没有接收到字符。那接收到存在数组的值就是一个完整的字符串。用这种时间判断方式,可以完整的接收一个字符串,前提是每个字符串之间间隔一定时间发送。
同步协议的模式,就是用开始标志值和结束标志值来判断一个完整指令。例如发送字符串,最简单同步协议可以开始时发一个':',结束时发一个回车来判断。
由于进行串口通讯时往往要接收外部模块发来的命令,这就要求我们根据外部模块的命令协议自己去分板如何接收?本质就是把接收到字符值存入数组,进行分析,就能得到相应的命令。

大家只要明白,串口是一个字节一个字节发送,一个字节一个字节接收,实际接收到的就是一个8位二进制数。呈现形式可以文本模式或HEX模式。在后面的实战中,就不会出现根念性的错误,就能实现自己想要的程序设计。


回复

使用道具 举报

0

主题

1

帖子

16

积分

注册会员

Rank: 2

积分
16
发表于 2022-5-17 14:52:40 | 显示全部楼层
要是能把文件打包提供下载就好了
回复

使用道具 举报

7

主题

31

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
发表于 2023-2-28 11:00:21 | 显示全部楼层
想知道浮点数要怎么发送
回复

使用道具 举报

1

主题

5

帖子

47

积分

注册会员

Rank: 2

积分
47
发表于 2023-3-23 17:26:46 | 显示全部楼层
你说了asrorp向单片机发送和单片机接收asrorp的,也说了单片机发送,但但但但但但但但你就是没有说单片机发送过去的asrorp怎么接收来自单片机的字符串和其他
回复

使用道具 举报

2

主题

4

帖子

148

积分

注册会员

Rank: 2

积分
148
发表于 2023-4-27 15:46:15 | 显示全部楼层
老师你好,请教个问题
AA A3 01 00 CB 00 8C 00 00 00 08 5B
我要接收这串数组,我要怎么知道它是否接收完成。
还有我要监控他第7 位数的值要怎么操作。
谢谢
回复

使用道具 举报

1

主题

2

帖子

25

积分

注册会员

Rank: 2

积分
25
发表于 2023-5-10 20:11:59 | 显示全部楼层
稻草人008 发表于 2023-4-27 15:46
老师你好,请教个问题
AA A3 01 00 CB 00 8C 00 00 00 08 5B
我要接收这串数组,我要怎么知道它是否接收完 ...

求一样的设置方法
回复

使用道具 举报

1

主题

3

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2023-8-15 11:41:24 | 显示全部楼层
发送的都说了,就是没说接收的
回复

使用道具 举报

0

主题

1

帖子

22

积分

注册会员

Rank: 2

积分
22
发表于 2023-12-19 08:50:49 | 显示全部楼层
教一路留一路,免得徒弟打师父
回复

使用道具 举报

1

主题

8

帖子

63

积分

注册会员

Rank: 2

积分
63
QQ
发表于 2023-12-21 21:25:41 | 显示全部楼层
为什么不能直接发送中文
回复

使用道具 举报

1

主题

4

帖子

33

积分

注册会员

Rank: 2

积分
33
发表于 2024-3-10 10:16:01 | 显示全部楼层
没有串口中断,查询串口有木有数据慢的无法接受。电脑发过去数据半天asr还没反映。这个问题开发者是不是不知道???
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2024-4-20 16:48 , Processed in 0.747073 second(s), 26 queries .

Powered by Discuz!

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表