目录

一、pc串口通信

1.连线设置

2.打开调试助手

2.1加载图片

2.2 设置波特率为15200

2.3点击发送文件

3.将波特率设为2000000

4.结果分析

二、点阵汉字读取与打印

1.点阵汉字知识点

1.1 汉字编码

1.2点阵字库结构

1.3 汉字点阵获取

2.编程实现

2.1创建文本文档

2.2 打开Ubuntu

2.3 运行结果

三、总结


一、pc串口通信

1.连线设置

注意将一个串口的TXD连接另一个串口的RXD,接电源和接地连一起即可。

2.打开调试助手

2.1加载图片

2.2 设置波特率为15200

2.3点击发送文件

预计时间为15s,但是在实际测试过程中用了21s

3.将波特率设为2000000

可见此时预测时间为0.6s,可是实际的传输时间为11s。

4.结果分析

因为传输时延=文件大小/波特率,因为随着波特率的升高,丢包率会更高,因此实际时间与预测时间差别很大。

二、点阵汉字读取与打印

1.点阵汉字知识点

1.1 汉字编码

区位码
        在国标 GD2312—80 中规定,所有的国标汉字及符号分配在一个 94 行、94 列的方阵中,方阵的每一行称为一个“区”,编号为 01 区到 94 区,每一列称为一个“位”,编号为01 位到 94 位,方阵中的每一个汉字和符号所在的区号和位号组合在一起形成的四个阿拉伯数字就是它们的“区位码”。区位码的前两位是它的区号,后两位是它的位号。用区位码就可以唯一地确定一个汉字或符号,反过来说,任何一个汉字或符号也都对应着一个唯一的区位码。汉字“母”字的区位码是 3624,表明它在方阵的 36 区 24 位,问号“?”的区位码为
0331,则它在 03 区 3l 位。

机内码
        汉字的机内码是指在计算机中表示一个汉字的编码。机内码与区位码稍有区别。如上所述,汉字区位码的区码和位码的取值均在 1~94 之间,如直接用区位码作为机内码,就会与基本 ASCII 码混淆。为了避免机内码与基本 ASCII 码的冲突,需要避开基本 ASCII 码中的控制码(00H~1FH),还需与基本 ASCII 码中的字符相区别。为了实现这两点,可以先在区码和位码分别加上 20H,在此基础上再加 80H(此处“H”表示前两位数字为十六进制数)。经过这些处理,用机内码表示一个汉字需要占两个字节,分别 称为高位字节和低位字节,这两位字节的机内码按如下规则表示:

高位字节 = 区码 + 20H + 80H(或区码 + A0H)
        低位字节 = 位码 + 20H + 80H(或位码 + AOH)

由于汉字的区码与位码的取值范围的十六进制数均为 01H~5EH(即十进制的 01~94),所以汉字的高位字节与低位字节的取值范围则为 A1H~FEH(即十进制的 161~254)。 例如,汉字“啊”的区位码为 1601,区码和位码分别用十六进制表示即为 1001H,它的机内码的高位字节为 B0H,低位字节为 A1H,机内码就是 B0A1H。

1.2点阵字库结构

点阵字库存储
        在汉字的点阵字库中,每个字节的每个位都代表一个汉字的一个点,每个汉
字都是由一个矩形的点阵组成,0 代表没有,1 代表有点,将 0 和 1 分别用不同颜色画出,就形成了一个汉字,常用的点阵矩阵有 12 * 12, 14 * 14, 16 * 16 三 种字库。 字库根据字节所表示点的不同有分为横向矩阵和纵向矩阵,目前多数的字库都是横向矩阵的存储方式(用得最多的应该是早期 UCDOS 库),纵向矩阵一 般是因为有某些液晶是采用纵向扫描显示法,为了提高显示速度,于是便把字库 矩阵做成纵向,省得在显示时还要做矩阵转换。我们接下去所描述的都是指横向矩阵字库。

16 * 16 点阵字库
        对于 16 * 16 的矩阵来说,它所需要的位数共是 16 * 16=256 个位,每个字节为 8 位,因此,每个汉字都需要用 256/8=32 个字节来表示。即每两个字节代表一行的 16 个点,共需要 16 行,显示汉字时,只需一次性读取 32 个字节,并将每两个字节为一行打印出来,即可形成一个汉字。

14 * 14 与 12 * 12 点阵字库
        对于 14 * 14 和 12 * 12 的字库,理论上计算,它们所需要的点阵分别为(14 * 14/8)=25, (12 * 12/8)=18 个字节,但是,如果按这种方式来存储,那么取 点阵和显示时,由于它们每一行都不是 8 的整位数,因此,就会涉到点阵的计算处理问题,会增加程序的复杂度,降低程序的效率。
为了解决这个问题,有些点阵字库会将 14 * 14 和 12 * 12 的字库按 16*14和16 * 12 来存储,即,每行还是按两个字节来存储,但是 14 * 14 的字库,每两个字节的最后两位是没有使用,12 * 12 的字节,每两字节的最后 4 位是没有 使用,这个根据不同的字库会有不同的处理方式,所以在使用字库时要注意这个 问题,特别是 14 * 14 的字库。

1.3 汉字点阵获取

利用区位码获取汉字
        汉字点阵字库是根据区位码的顺序进行存储的,因此,我们可以根据区位来
获取一个字库的点阵,它的计算公式如下:
点阵起始位置 = ((区码- 1)*94 + (位码 – 1)) * 汉字点阵字节数
获取点阵起始位置后,我们就可以从这个位置开始,读取出一个汉字的点阵。

利用汉字机内码获取汉字
前面我们己经讲过,汉字的区位码和机内码的关系如下:
        机内码高位字节 = 区码 + 20H + 80H(或区码 + A0H)
        机内码低位字节 = 位码 + 20H + 80H(或位码 + AOH)
反过来说,我们也可以根据机内码来获得区位码:
        区码 = 机内码高位字节 - A0H
        位码 = 机内码低位字节 - AOH
将这个公式与获取汉字点阵的公式进行合并计就可以得到汉字的点阵位置。

2.编程实现

2.1创建文本文档

创建文本文档并保存为ANSI格式

ANSI通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。Unicode字符分为17组编排,   UTF-8用1到6个字节编码UNICODE字符。
ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。表示英文字符时用一个字节,表示中文用两个或四个字节。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。

2.2 打开Ubuntu

  • 编写addtext.cpp文件
#include<opencv/cv.h>#include"opencv2/opencv.hpp"#include<opencv/cxcore.h>#include<opencv/highgui.h>#include<math.h>using namespace cv;using namespace std;void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset);void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset);void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path);int main(){
String image_path="test.png";char* logo_path="logo1.txt";put_text_to_image(700,700,image_path,logo_path);return 0;}void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset){
//绘制的起点坐标Point p;p.x = x_offset;p.y = y_offset;//存放ascii字膜char buff[16];           //打开ascii字库文件FILE *ASCII;if ((ASCII = fopen("Asci0816.zf", "rb")) == NULL){printf("Can't open ascii.zf,Please check the path!");//getch();exit(0);}fseek(ASCII, offset, SEEK_SET);fread(buff, 16, 1, ASCII);int i, j;Point p1 = p;for (i = 0; i<16; i++)                  //十六个char{p.x = x_offset;for (j = 0; j < 8; j++)              //一个char八个bit{p1 = p;if (buff[i] & (0x80 >> j))    /*测试当前位是否为1*/{/*由于原本ascii字膜是8*16的,不够大,所以原本的一个像素点用4个像素点替换,替换后就有16*32个像素点ps:感觉这样写代码多余了,但目前暂时只想到了这种方法*/circle(image, p1, 0, Scalar(0, 0, 255), -1);p1.x++;circle(image, p1, 0, Scalar(0, 0, 255), -1);p1.y++;circle(image, p1, 0, Scalar(0, 0, 255), -1);p1.x--;circle(image, p1, 0, Scalar(0, 0, 255), -1);}                        p.x+=2;            //原来的一个像素点变为四个像素点,所以x和y都应该+2}p.y+=2;}}void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset){//在图片上画汉字Point p;p.x=x_offset;p.y=y_offset;FILE *HZK;char buff[72];//72个字节,用来存放汉字的if((HZK=fopen("HZKf2424.hz","rb"))==NULL){printf("Can't open HZKf2424.hz,Please check the path!");exit(0);//退出}fseek(HZK, offset, SEEK_SET);/*将文件指针移动到偏移量的位置*/fread(buff, 72, 1, HZK);/*从偏移量的位置读取72个字节,每个汉字占72个字节*/bool mat[24][24];//定义一个新的矩阵存放转置后的文字字膜int i,j,k;for (i = 0; i<24; i++)                 /*24x24点阵汉字,一共有24行*/{for (j = 0; j<3; j++)                /*横向有3个字节,循环判断每个字节的*/for (k = 0; k<8; k++)              /*每个字节有8位,循环判断每位是否为1*/if (buff[i * 3 + j] & (0x80 >> k))    /*测试当前位是否为1*/{mat[j * 8 + k][i] = true;          /*为1的存入新的字膜中*/}else {mat[j * 8 + k][i] = false;}}for (i = 0; i < 24; i++){p.x = x_offset;for (j = 0; j < 24; j++){        if (mat[i][j])circle(image, p, 1, Scalar(255, 0, 0), -1);         //写(替换)像素点p.x++;                                                //右移一个像素点}p.y++;                                                    //下移一个像素点}}void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path){//将汉字弄上图片
//x和y就是第一个字在图片上的起始坐标
//通过图片路径获取图片Mat image=imread(image_path);int length=19;//要打印的字符长度unsigned char qh,wh;//定义区号,位号unsigned long offset;//偏移量unsigned char hexcode[30];//用于存放记事本读取的十六进制,记得要用无符号FILE* file_logo;if ((file_logo = fopen(logo_path, "rb")) == NULL){printf("Can't open txtfile,Please check the path!");//getch();exit(0);}fseek(file_logo, 0, SEEK_SET);fread(hexcode, length, 1, file_logo);int x =x_offset,y = y_offset;//x,y:在图片上绘制文字的起始坐标for(int m=0;m<length;){if(hexcode[m]==0x23){break;//读到#号时结束}else if(hexcode[m]>0xaf){qh=hexcode[m]-0xaf;//使用的字库里是以汉字啊开头,而不是以汉字符号开头wh=hexcode[m+1] - 0xa0;//计算位码offset=(94*(qh-1)+(wh-1))*72L;paint_chinese(image,x,y,offset);/*计算在汉字库中的偏移量对于每个汉字,使用24*24的点阵来表示的一行有三个字节,一共24行,所以需要72个字节来表示d5-af=38(十进制),因为是从汉字啊开始的,所以减去的是af而不是a0,38+15等于53与区码相对应d4-a0=52*/m=m+2;//一个汉字的机内码占两个字节,x+=24;//一个汉字为24*24个像素点,由于是水平放置,所以是向右移动24个像素点}else{//当读取的字符为ASCII码时wh=hexcode[m];offset=wh*16l;//计算英文字符的偏移量paint_ascii(image,x,y,offset);m++;//英文字符在文件里表示只占一个字节,所以往后移一位就行了x+=16;}}cv::imshow("image", image);cv::waitKey();}

将需要的文本文档,汉字库,ASCII字库,拖进ubuntu的

2.3 运行结果

Asci0816.zf和HZKf2424.hz可以用FONTSHOW查看

利用g++命令,编译生成执行文件

g++ addtext.cpp -o test `pkg-config --cflags --libs opencv`

输入

./test

三、总结

通过对点阵汉字的学习,明白了除了ASCII能编码英文之外,中文也能够进行编码,不过需要两位,为了与ASCII不冲突,引入了区位码和机内码。opencv的作用就是根据点阵图利用circle函数画实心圆代替像素点来绘字和字符。

参考:(15条消息) 两台PC实现串口通信以及点阵字模读写_Laul Ken-Yi的博客-CSDN博客

两台PC实现串口通信以及点阵字模读写相关推荐

  1. 串口通信--两台PC机之间的简单传输

    串口通信–两台PC机之间的简单传输 文章目录 串口通信--两台PC机之间的简单传输 1.实验器材 2.实物连接 3.选择文件发送 4.计算比较 5.总结 1.实验器材 两台 PC 机器 两个 usb ...

  2. 如何让两台PC通过一根网线相互通信?

    1.如果是同类设备之间相连,比如PC-PC,交换机-交换机,需要用交叉线. 2.如果是不同类设备相连,比如PC-交换机,PC-路由器,需要用直连线. 之前用普通网线(直连线)连接笔记本A和笔记本B,在 ...

  3. 【计算机网络】大作业-实现两台pc间交流的简单的聊天软件

    参考 传送门 - 1 - csdn - 2112222222222 传送门 - 2 - bilibili - 憧憬少 传送门 - 3 - 要求 开发一个聊天程序 包含客户端和服务器段 编程语言不限 要 ...

  4. 【网络通信与信息安全】之深入解析两台主机之间的通信过程和原理

    一.前言 本文通过在 Docker 容器中执行命令,来深入了解两台主机之间的通信过程.阅读完本文,您将熟悉以下内容: Docker 的基本操作: 创建 socket 并发送 HTTP 请求: 路由表. ...

  5. win7 两台PC网线直连创建家庭组局域网分享文件

    设置局域网 首先用网线连接两台电脑,然后打开其中一台右下角的[网络和共享中心],点击左侧的[更改适配器设置]: 可以看到本地连接被提示为连接到"未识别的网络": 双击此[本地连接] ...

  6. 单片机与PC机串口通信编程

    单片机与PC机串口通信编程 实验目的 利用PROTUES仿真软件.串口调试助手.虚拟串口,搭建单片机与PC通信仿真平台,熟悉单片机串口的配置及与PC机的通信方法. 实验目的 1.PROTUES仿真软件 ...

  7. 两台pc如何高速度传输大文件

    今天笔记本跑一个大一点的项目,8G的内存直接100%,i5的CPU直接75%并且在超频工作了,原本1.6Ghz的频率直接飙到了3.8Ghz,由于项目性质原因,采用的是公司配的笔记本,但是年初采购的联想 ...

  8. s7-200和两台变频器modbus rtu通信程序采用西门子224xp

    s7-200和两台变频器modbus rtu通信程序采用西门子224xp,配mcgs触摸屏,变频器一台三菱D700,一台台达vfd-m,通过modbus rtu程序可以控制变频器的正反转,停止,频率的 ...

  9. 两台PC机之间就一定要用交叉线吗?

    起因是这样的,昨天拿回一台上网本回来,为了实现上网本和台机互联且都能上网,常用的也是首选的方法当然是MS自家的ICS,来实现一个帐号可多台电脑共享上网,但在这个xx的社会,此做法当然触碰了xx的利益. ...

最新文章

  1. 《Linux内核分析》MOOC课程之从汇编语言角度看计算机是如何工作的
  2. NYOJ 20 吝啬的国度 (搜索)
  3. 多项式的求逆、取模和多点求值学习小记
  4. final const java_Java中的final关键字 与 C#中的const, readonly关键字
  5. Linux内核很吊之 module_init解析 (下)【转】
  6. linux通过不同端口访问,linux下两个tomcat通过不同端口访问不同项目
  7. 《乔布斯的魔力演讲》书摘
  8. mysql 用户 多次登录失败_限制用户登录失败次数,在连续登陆失败10次后冻结该用户。...
  9. 紧跟步伐,何恺明新作MAE复现历程
  10. 计算机文件只读模式,电脑文件只读模式如何修改 – 手机爱问
  11. MongoDB集群节点RECOVERING故障恢复
  12. 磁盘,分区,文件系统
  13. HTML、CSS、JavaScript学习总结
  14. [资源帖]SIGGRAPH2016 下载地址
  15. 蓝桥杯------蓝桥幼儿园
  16. docker本地PHP开发环境搭建
  17. 2017全球智慧城市战略指数分析
  18. 马丁福勒 关于微服务特点的描述
  19. java环形buff_环形缓冲区.ringbuff(C#和java)
  20. Android 开源的UI框架

热门文章

  1. 敏捷软件开发方法 —— Scrum
  2. 【技术转型】我Android转前端的思考过程
  3. C语言的文件操作(文件指针、文件缓冲区、文件的打开、读写操作)
  4. 嵌入式linux系统中常用的文件系统
  5. 你自学3dmax一直没进步?只因没找到这几个突破口
  6. 【Linux】进程的程序替换
  7. python json变为csv具体代码
  8. BJOI2015 Day3
  9. 什么是Page Objects(PageObjects 设计模式)
  10. 红警2的经验和秘籍及不是秘笈的秘笈(3)