串口传输&点阵汉字的字模读取与显示

一.串口传输

1.串口连接

准备两个USB TO TTL和杜邦线若根,将两个USB TO TTL的RX,TX引脚交叉连接,并将两个USB接口接上一台笔记本电脑(模拟两台计算机之间的串口传输)。
在这里插入图片描述

2.传输文件

  • 传输文件:
    利用可以传输文件的串口调试助手,选择端口,这里可以看见串口COM4,这里选择的波特率是115200,数据位8,停止位1,无校验位。

在这里插入图片描述

  • 接收文件:
    选择端口,这里可以看见端口COM5,两个端口波特率需要设置相同,所以也为115200
    在这里插入图片描述
    选择文件,点击发送,可以看到大概需要6.29秒
    在这里插入图片描述

在这里插入图片描述
发送完毕后就会出现这个文件
在这里插入图片描述
将文件后缀改为jpg,打开效果如图
在这里插入图片描述
波特率设置为2400
在这里插入图片描述
波特率设置为200000
在这里插入图片描述
在一定范围内,当波特率增大时,对于同等大小的文件,传输时间会减少,当超过这一范围时,波特率对传输时间的影响就会减小。

二.点阵汉字的字模读取与显示

1.汉字编码

1.区位码

区位码是1980年中国制定的一个字符编码标准。每一个字符都有对应一个4位十进制数字码位表示,其中前两位为“区”,后两位为“位”。中文汉字的编号区号是从16开始的,位号从1开始。

GB2312编码就是基于区位码的,用双字节编码表示中文和中文符号。GB2312编码方式是:0xA0+区号,0xA0+位号。如“安”,区位号是1618(十进制),那么“安”字的GB2312编码就是
0xA0+16 0xA0+18 也就是 0xB0 0xB2 。根据区位码表,GB2312的汉字编码范围是0xB0A1~0xF7FE。

直接向计算机输入区位码而得到汉字的方法叫做区位输入法。相应地,输入国标码而得到汉字的方法叫做GB内码输入法。在DOS时代,许多中文系统都实现了国标码及区位码输入法。普通用户一般不使用这些输入法,在DOS被Windows系统取代后,国标码和区位码输入法已少有人使用。

2.机内码

因为汉字处理系统要保证中西文的兼容,当系统中同时存在ASCII码和汉字国标码时,将会产生二义性。例如:有两个字节的内容为30H和21H,它既可表示汉字“啊”的国标码,又可表示西文“0”和“!”的ASCII码。为此,汉字机内码应对国标码加以适当处理和变换。
国标码的机内码为二字节长的代码,它是在相应国标码的每个字节最高位上加“1”,即 汉字机内码=汉字国标码+8080H
例如,上述“啊”字的国标码是3021H,其汉字机内码则是B0A1H。 汉字机内码的基础是汉字国标码。
机内码:为了避免ASCII码和国标码同时使用时产生二义性问题,大部分汉字系统都采用将国标码每个字节高位置1作为汉字机内码。这样既解决了汉字机内码与西文机内码之间的二义性,又使汉字机内码与国标码具有极简单的对应关系。
汉字机内码、国标码和区位码三者之间的关系为:区位码(十进制)的两个字节分别转换为十六进制后加2020H得到对应的国标码;机内码是汉字交换码(国标码)两个字节的最高位分别加1,即汉字交换码(国标码)的两个字节分别加80H得到对应的机内码;区位码(十进制)的两个字节分别转换为十六进制后加A0H得到对应的机内码。

2.点阵字库结构(24*24点阵字库)

在24×24点阵字库中,每个汉字的字形码所占字节是72.

公式:24x24=576位,一个字节=8位,576/8=72个字节。

释义:24 * 24 = 576 个像素点,一个像素点用 1 bit 存储,8bit 为 1 byte

3.在Ubuntu下用C/C++(或python) 调用opencv库编程显示一张图片,并显示信息

#include <stdio.h>//标准输入输出库
#include <stdlib.h>//
#include <cxcore.h>
#include <highgui.h>
//#include <direct.h>
#include <unistd.h>
using namespace cv;

const int CC_SIZE = 16;
const int SAFE_WIDTH = 10;
const int CC_NUMBER = 15;
// 姓名
unsigned char name[10] = "xxx";//输入自己的姓名
unsigned int name_code[2][2];

// 学号
unsigned int id_code[12][2] = { { 0xa3, 0xb6 }, { 0xa3, 0xb3 }, { 0xa3, 0xb1 }, { 0xa3, 0xb9 }, { 0xa3, 0xb0 }, { 0xa3, 0xb7 }, { 0xa3, 0xb0 }, { 0xa3, 0xb6 }, { 0xa3, 0xb0 }, { 0xa3, 0xb5 }, { 0xa3, 0xb3 }, { 0xa3, 0xb1 } };

// 保存字节的数组
unsigned char mat[16][2];

FILE* HZK16;
IplImage* img;

void get_area_position_codes();

void get_mat(int a_code, int p_code);

void open_file();

void draw_one_cc(int num);

void release();

int main()
{
	open_file();//读取文件
	get_area_position_codes();
	// 写名字
	int i, j;
	for (i = 0; i < 2; ++i)
	{
		get_mat(name_code[i][0], name_code[i][1]);
		draw_one_cc(i);
	}
	// 写学号
	for (j = 0; j < 12; ++j)
	{
		get_mat(id_code[j][0] - 0xa0, id_code[j][1] - 0xa0);
		draw_one_cc(i + j);
	}
	// 显示图片
        //cvSaveImage("IMAGE", img);
	cvShowImage("IMAGE", img);//显示图片
	cvWaitKey(0);//刷新图像,参数单位是毫秒,表示刷新频率
	release();//释放捕捉
	return 0;
}

void get_area_position_codes()
{
	for (int i = 0; i < 2; ++i)
	for (int j = 0; j < 2; ++j)
		name_code[i][j] = name[i * 2 + j] - 0xa0;
}

void get_mat(int a_code, int p_code)
{
	long offset;
	offset = (94 * (a_code - 1) + (p_code - 1)) * 32L;//计算字符偏移量
	// 读取数据存入数组
	fseek(HZK16, offset, SEEK_SET);//设置流HZK16的文件起始位置为给定偏移offset,参数offset意味着从给定的SEEK_SET位置查找的字节数
	fread(mat, 32, 1, HZK16);//从指定流读取数据到mat数组
}

void open_file()
{
	char pbuf[100];
	getcwd(pbuf, 100);//将当前的工作目录绝对路径复制到参数pbuf所指的内存空间,参数100为pbuf 的空间大小。
	strcat(pbuf,"HZKf1616.hz");//把HZKf1616.hz所指向的字符串追加到pbuf所指向的字符串的结尾
	// 读取图片
	if ((img = cvLoadImage("image.png")) == NULL)exit(1);
	// 打开字体文件
	if ((HZK16 = fopen("HZKf1616.hz", "rb")) == NULL)exit(1);
}

void draw_one_cc(int num)
{
	// 图片的像素值
	int width, height;
	width = img->width;
	height = img->height;
	// 开始的x y像素点
	int start_x, start_y, size, current_start_x, current_start_y;
	size = CC_SIZE + SAFE_WIDTH;
	start_x = width - CC_NUMBER * size;
	start_y = height - CC_SIZE - SAFE_WIDTH;
	// 开始绘制
	CvScalar cs;
	for (int i = 0; i < 16; ++i)
	for (int j = 0; j < 2; ++j)
	for (int k = 0; k < 8; k++)
	if (mat[i][j] & (0x80 >> k))
	{
		// 绘点
		current_start_x = j * 8 + k + start_x + size * num;
		current_start_y = start_y + i;
		cs = cvGet2D(img, current_start_y, current_start_x);
		cs.val[0] = 0;//设置打印字体颜色,这里是绿色
		cs.val[1] = 255;
		cs.val[2] = 0;
		cvSet2D(img, current_start_y, current_start_x, cs);//获取像素点的值
	}
}

void release()
{
	cvReleaseImage(&img);
	fclose(HZK16);
	img = NULL;
	HZK16 = NULL;
}

运行后如图:
在这里插入图片描述

总结

波特率和数据的传输速率有关系,但是波特率并不是数据传输速率,数据传输速率是比特率。

参考

https://blog.csdn.net/qq_45659777/article/details/121168590

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值