Font reading and display of serial port transmission file and dot matrix Chinese characters

1, Experimental requirements

1. Serial port file transfer exercise. Connect the two laptops with serial port by means of usb to rs232 module and DuPont line. Then use tools and software such as serial port assistant (with file transfer function) to transfer a large file (picture, video and compressed package software) on one laptop to another computer, budget the relationship between file size, baud rate and transmission time, and compare the actual transmission time.
2. Learn and understand the internal code, location code coding rules and font data storage format of Chinese characters. Under Ubuntu, use C/C + + (or python) to call opencv library to program and display a picture, open a text file named "logo.txt" (there is only one line of text file, including your own name and student number), and read the font data of the corresponding characters in the Chinese character 24 * 24 dot matrix font library (file HZKf2424.hz in the compressed package) according to the name and student number, Overlay the name and student number to the lower right of this picture.

2, Serial port transmission file

1. Serial connection

Cross connect the RXD and TXD pins of the two USB TO TTL serial ports, and connect the two USB interfaces to a laptop respectively to realize the serial port transmission between the two computers.

Serial interface is called serial port for short( Serial Interface)It refers to the sequential transmission of data bit by bit. To realize two-way communication, a pair of transmission lines are required, i.e TX And RX Line.
Circuit connection mode: if the serial port is to realize bidirectional transmission, device 1 and device 2, TX And RX Cross connect.
Start bit: data line TX Change from high level to low level.
Stop bit: data line TX From low level to high level.
Function of start bit and stop bit: if the receiving device detects that the data line changes from high level to low level, it receives the start signal from the transmitting device, indicating the start of data transmission. If the receiving device detects that the data line changes from low level to high level, it receives the stop signal from the transmitting device, indicating the end of a frame of data.
Common serial port transmission format: 1 bit Start bit+8bit Data bit+1bit Stop bit (no parity bit)

2. Transfer file

1) Set baud line to 115200

send out:


Modify the extension. DAT of the saved file to. jpg:

Result display:

2) Set baud line to 2000000

send out:


3. Result analysis

Transfer time = file size / baud rate

① In a certain range, when the baud rate increases, the transmission time will decrease for files of the same size.
② No matter what the baud rate is, the actual transmission time is quite different from the theoretical transmission time.

The baud rate is related to the data transmission rate, but the baud rate is not the data transmission rate, and the data transmission rate is the bit rate. The bit rate is numerically related to the baud rate:
Bit rate = baud rate, the number of bits corresponding to a single modulation state.
Where I is the transmission rate, S is the baud rate, N is the amount of information carried by each symbol, and the unit is bit.

3, Font reading and display of dot matrix Chinese characters

1. Understanding of lattice

In the previous method, one IO port can only control one led. What if we need to use fewer IO ports to control more LEDs? So, there is a dot matrix.
For example, the 8X8 dot matrix is composed of 64 light-emitting diodes, and each light-emitting diode is placed at the intersection of row line and column line. When a corresponding row is set to 1 level and a column is set to 0 level, the corresponding diode will be on; If the first point is to be lit, pin 1 is connected to high level and pin a is connected to low level, then the first point is lit.

Physical map

With the help of modeling software, we can present the words or letters we need in the form of dot matrix

We know that the number of English letters is relatively small. We only need one byte (8 bits) to express it. But there are many Chinese characters. How to express it?

One method adopted by predecessors is to take the high 128 bits of ASCII code as the internal code of Chinese characters, and the low 128 bits as the internal code of English letters, and then use two bytes to represent a Chinese character. Through this internal code, we can obtain the font information of Chinese characters. Then, according to the information of these fonts, the corresponding Chinese characters are displayed.

2. Chinese character coding

1) Location code

In fact, the dot matrix font library stores the font information of Chinese characters according to the internal code order of Chinese characters. sixteen×16 The dot matrix font library has 94 areas, and each area has a font of 94 Chinese characters. There are 94 in total×94 Chinese characters.

In the national standard GD2312—80 It is stipulated that all national standard Chinese characters and symbols are distributed in a square matrix with 94 rows and 94 columns. Each row of the square matrix is called an "area", numbered from 01 to 94, and each column is called a "bit", numbered from 01 to 94. The four Arabic numerals formed by the combination of the area code and bit code of each Chinese character and symbol in the square matrix are their symbols "Location code".

The first two digits of the location code are its area code and the last two digits are its bit code. A Chinese character or symbol can be uniquely determined by the location code.

2) Internal code

The internal code of Chinese characters refers to the code representing a Chinese character in the computer. The internal code is slightly different from the location code.

The area code and bit code of Chinese character location code are between 1-94. If the location code is directly used as the internal code, it will be confused with the basic ASCII code. In order to avoid the conflict between the internal code and the basic ASCII code, it is necessary to avoid the control code (00H~1FH) in the basic ASCII code and distinguish it from the characters in the basic ASCII code.

Therefore, 20H is added to the area code and bit code respectively, and 80H is added on this basis.
(here "H" means that the first two digits are hexadecimal numbers)
After these processes, it takes two bytes to represent a Chinese character with internal code, which are called high byte and low byte respectively. The internal code of these two bytes is represented according to the following rules:

High byte = Area code + 20H + 80H(Or area code + A0H)
Low byte = Bit code + 20H + 80H(Or bit code + AOH)

Since the hexadecimal numbers in the value range of area code and bit code of Chinese characters are 01h-5eh (i.e. 01-94 in decimal system), the value range of high-order bytes and low-order bytes of Chinese characters is a1h-feh (i.e. 161-254 in decimal system).

For example, the location code of the Chinese character "ah" is 1601, and the area code and bit code are expressed in hexadecimal respectively, that is, 1001H. The high byte of its internal code is B0H, the low byte is A1H, and the internal code is B0A1H.

3. Lattice font structure

1) Lattice font storage

In the dot matrix font of Chinese characters, each bit of each byte represents a point of a Chinese character. Each Chinese character is composed of a rectangular dot matrix, 0 represents no, 1 represents a point. Draw 0 and 1 in different colors to form a Chinese character.

Word libraries are divided into horizontal matrix and vertical matrix according to the points represented by bytes. At present, most word libraries are stored in horizontal matrix(The most used should be the early stage UCDOS Font),Longitudinal matrix is generally because some liquid crystals use longitudinal scanning display method. In order to improve the display speed, the font matrix is made into longitudinal matrix.

What is described later refers to the horizontal matrix font.

2) 16 * 16 dot matrix font

For the 1616 matrix, the number of bits required is 1616 = 256 bits, and each word is 8 bits. Therefore, each Chinese character needs to be represented by 256 / 8 = 32 bytes.

Every two bytes represent 16 points in a line, and a total of 16 lines are required. When displaying Chinese characters, you only need to read 32 bytes at one time and print every two bytes as a line to form a Chinese character.

3) 1414 and 1212 dot matrix font

Theoretically, for the word libraries 1414 and 1212, the dot matrices they need are (1414 / 8) = 25 and (1212 / 8) = 18 bytes respectively. However, if they are stored in this way, when taking and displaying the dot matrix, because each line is not the integer of 8, it will involve the calculation and processing of the dot matrix, increase the complexity of the program and reduce the efficiency of the program.

In order to solve this problem, some dot matrix word libraries store the word libraries of 1414 and 1212 as 1614 and 1612, that is, each line is still stored as two bytes, but the last two bits of every two bytes are not used in the word library of 1414, and the last four bits of every two bytes are not used in the byte of 1212. This will be handled differently according to different word libraries, Therefore, we should pay attention to this problem when using word library.

4. Chinese character dot matrix acquisition

1) Using location code to obtain Chinese characters

The Chinese character dot matrix font is stored according to the sequence of location codes. Therefore, we can obtain the dot matrix of a font according to location. Its calculation formula is as follows:

Dot matrix start position = ((area code - 1) * 94 + (bit code - 1)) * number of Chinese dot matrix bytes

After obtaining the starting position of the dot matrix, we can read and take out the dot matrix of a Chinese character from this position.

2) Acquiring Chinese characters by using Chinese character internal code

The relationship between location code and internal code of Chinese characters is as follows:

High byte of internal code = area code + 20H + 80H (or area code + A0H)
Low byte of internal code = bit code + 20H + 80H (or bit code + AOH)

Conversely, we can also obtain the location code according to the internal code:

Area code = high byte of internal code - A0H
Bit code = low byte of internal code - AOH

By combining this formula with the formula for obtaining the Chinese character dot matrix, the position of the Chinese character dot matrix can be obtained.

5. Experimental steps

1) Experimental preparation

A picture to be displayed, 24 * 24 dot matrix. hz file, ASCII code. zf file, and text file to be displayed
(Note: when inputting the text you want to display in the logo.txt file, it needs to be written in ANSI code, otherwise Chinese will be garbled)

2) Write code

Create a wo.cpp file, open the terminal in the folder, and enter the following command
gedit wo.cpp
The code is as follows


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="yingbao.jpg";//Name of picture
    char* logo_path="logo.txt";//Name of Chinese character file
    put_text_to_image(200,350,image_path,logo_path);//change txt place
    return 0;

void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset){
    //Coordinates of the starting point of the drawing
	Point p;
	p.x = x_offset;
	p.y = y_offset;
	 //Storing ascii word film
	char buff[16];           
	//Open ascii font file

	if ((ASCII = fopen("Asci0816.zf", "rb")) == NULL){
		printf("Can't open ascii.zf,Please check the path!");

	fseek(ASCII, offset, SEEK_SET);
	fread(buff, 16, 1, ASCII);

	int i, j;
	Point p1 = p;
	for (i = 0; i<16; i++)                  //Sixteen char s
		p.x = x_offset;
		for (j = 0; j < 8; j++)              //One char and eight bit s
			p1 = p;
			if (buff[i] & (0x80 >> j))    /*Test whether the current bit is 1*/
					Because the original ascii word film was 8 * 16, it was not large enough,
					So the original pixel is replaced by four pixels,
					After replacement, there are 16 * 32 pixels
					ps: I think it's unnecessary to write code like this, but I only think of this method for the time being
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
			   circle(image, p1, 0, Scalar(0, 0, 255), -1);
            p.x+=2;            //One pixel becomes four, so x and y should both be + 2
void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset){//Draw Chinese characters on the picture
    Point p;
    FILE *HZK;
    char buff[72];//72 bytes for storing Chinese characters

        printf("Can't open HZKf2424.hz,Please check the path!");
        exit(0);//sign out
    fseek(HZK, offset, SEEK_SET);/*Move the file pointer to the offset position*/
    fread(buff, 72, 1, HZK);/*Read 72 bytes from the offset position, and each Chinese character occupies 72 bytes*/
    bool mat[24][24];//Define a new matrix to store the transposed text film
    int i,j,k;
    for (i = 0; i<24; i++)                 /*24x24 Dot matrix Chinese characters, a total of 24 lines*/
        	for (j = 0; j<3; j++)                /*There are 3 bytes in the horizontal direction, and the value of each byte is determined by cycle*/
			for (k = 0; k<8; k++)              /*Each byte has 8 bits, and the loop judges whether each byte is 1*/
				if (buff[i * 3 + j] & (0x80 >> k))    /*Test whether the current bit is 1*/
					mat[j * 8 + k][i] = true;          /*1 is stored in a new word film*/
				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);		  //Write (replace) pixels
			p.x++;                                                //Shift right one pixel
		p.y++;                                                    //Move down one pixel

void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path){//Put Chinese characters on the picture
//x and y are the starting coordinates of the first word on the picture
    //Get pictures through picture path
    Mat image=imread(image_path);
    int length=16;//The length of characters to be printed (the length can be as many bytes as you print, which can be adjusted according to your own situation)
    unsigned char qh,wh;//Define area code and tag number
    unsigned long offset;//Offset
    unsigned char hexcode[30];//Hexadecimal used to store Notepad reading. Remember to use unsigned
    FILE* file_logo;

    if ((file_logo = fopen(logo_path, "rb")) == NULL){
		printf("Can't open txtfile,Please check the path!");

    fseek(file_logo, 0, SEEK_SET);
    fread(hexcode, length, 1, file_logo);
    int x =x_offset,y = y_offset;//x. Y: the starting coordinate of the text drawn on the picture

    for(int m=0;m<length;){
            break;//It ends when the # number is read
        else if(hexcode[m]>0xaf){
            qh=hexcode[m]-0xaf;//The font used starts with Chinese characters, not Chinese symbols
            wh=hexcode[m+1] - 0xa0;//Calculation bit code
            Calculate the offset in the Chinese character library
            Each Chinese character is represented by a 24 * 24 dot matrix
            A line has three bytes, a total of 24 lines, so 72 bytes are required

            m=m+2;//The internal code of a Chinese character occupies two bytes,
            x+=24;//A Chinese character has 24 * 24 pixels. Because it is placed horizontally, it moves 24 pixels to the right

        //When the read character is ASCII
        offset=wh*16l;//Calculate the offset of English characters
        m++;//English characters only occupy one byte in the file, so just move back one bit


    cv::imshow("image", image);

Modify the picture name on line 16 as needed
Modify the display position of 18 lines of text
Modify line 115 to print the character length

3) Compile run

Save the wo.cpp file

Compile instruction

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

After no error is reported,. / wo can run

4) Running screenshot

4, Summary

This experiment mainly uses opencv in the virtual machine for image display, and learned how to use the serial port for file transfer, how to call the opencv library with C/C + + under Ubuntu to overlay the name and student number in the logo on the lower right of the image. Finally, pay attention to the image size when selecting the image, because the opencv running screenshot in the virtual machine can not change the image size. In short, the experiment is relatively simple on the whole. Although some problems have been encountered, the operation screenshot has been successfully obtained by referring to the boss blog and Baidu analysis. I hope it will be carried out more smoothly next time.

5, References

Tags: OpenCV Ubuntu stm32

Posted on Fri, 19 Nov 2021 06:19:13 -0500 by shikhartandon