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

Keywords: C Ubuntu stm32

1, Serial port transmission file

1. Serial port 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 referred to as serial port for short. Serial Interface refers to the sequential transmission of data bit by bit. To realize two-way communication, a pair of transmission lines, namely TX and RX lines, are required.
Circuit connection mode: if the serial port is to realize bidirectional transmission, device 1 and device 2, TX and RX shall be cross connected.
Start bit: the data line TX changes from high level to low level.
Stop bit: the data line TX changes 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 a stop signal from the transmitting device, indicating the end of one frame of data.
Common serial port transmission format: 1bit start bit + 8bit data bit + 1bit stop bit (no parity bit)

2. File transfer

1. The speed is 115200
Sender:

Receiving end:

Change the saved file to jpg file, and the results are as follows:

2. Set the rate to 2000000
Sender:

Receiving end:

3. Conclusion:
According to the above experimental results, the relationship among file size, baud rate and transmission time can be summarized as follows
Transfer time = file size / baud rate
Using serial port to transmit files, the actual transmission time is larger than the expected transmission time, and there is a delay. To some extent, when files of different sizes are transmitted at the same baud rate, the transmission time increases with the increase of file size; The transmission time required to transmit the same file at different baud rates decreases with the increase of baud rate.

2, Font reading and display of dot matrix Chinese characters

1. Principle

1. Location code
It is stipulated in the national standard GD2312-80 that all national standard Chinese characters and symbols are allocated 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 area code and tag number of each Chinese character and symbol in the square array are combined to form four Arabic numerals, which are their "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 location code. Conversely, any Chinese character or symbol also corresponds to a unique location code.
2. Internal code
The internal code of Chinese characters refers to the code that represents a Chinese character in the computer. The internal code is slightly different from the location code. As mentioned above, the area code and bit code of Chinese 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. In order to achieve these two points, 20H can be added to the area code and bit code respectively, and 80H can be 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 number in the value range of area code and bit code of Chinese characters is 01H5EH), the value range of high-order byte and low-order byte of Chinese characters is A1HFEH
3. 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:

Lattice start position = ((area code-1) 94 + (bit code – 1)) number of Chinese character lattice 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
As we have said earlier, the relationship between the location code of Chinese characters and the internal code is as follows:

High byte of internal code = area code + 20h + 8OH (or area code + A0H)
Low byte of internal code = bit code + 20h + 8OH (or bit code + AOH)

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

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

2. Implementation steps

1. Put Asci0816.zf, HZKf2424.hz, logo.txt and sanli.jpg under this folder:

The contents of the logo.txt file are as follows:

2. Write code

The code is as follows:

#include<iostream>
#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="sanli.jpg";//Picture path
    char* logo_path=(char*)"logo.txt";//Student ID name path
    put_text_to_image(270,280,image_path,logo_path);
    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;
	char buff[16];    //Store ascii font      
	//Open ascii font file
	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++)                  //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 is 8 * 16, which is not large enough, the original pixel is replaced with 4 pixels, and there are 16 * 32 pixels after replacement
				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;            //One pixel becomes four, so x and y should both be + 2
		}
		p.y+=2;
	}
}
void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset)
{
    //Coordinates of pixels actually drawn on the picture
    Point p;
    p.x=x_offset;
    p.y=y_offset;
    //Open hzk24 Chinese character library file
    FILE *HZK;
    char buff[72];//Store Chinese font
    if((HZK=fopen("HZKf2424.hz","rb"))==NULL)
    {
        printf("Can't open HZKf2424.hz,Please check the path!");
        //getch();
        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 font
    //Transpose the Chinese font matrix, because the Chinese font stores the data after the device (reverse)
    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 font
				}
				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)
{
    //Get pictures through picture path
    Mat image=imread(image_path);
    int length=18;//Length of characters to print
    unsigned char qh,wh;//Define area code and tag number
    unsigned long offset;//Offset
    unsigned char hexcode[30];//Hexadecimal used to store Notepad reads
    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);//Move the file pointer to the offset position
    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;)
    {
        if(hexcode[m]==0x23)
        {
            break;//It ends when the # number is read
        }
        //Judge whether the two high-order hexadecimal numbers are greater than or equal to b0 (the first Chinese character is b0a1), and find them from the Chinese character library
        else if(hexcode[m]>0xaf)
        {
            qh=hexcode[m]-0xaf;//Calculation area code
            wh=hexcode[m+1]-0xa0;//Calculation bit code
            offset=(94*(qh-1)+(wh-1))*72L;//Calculate the offset of the Chinese character in the font
            paint_chinese(image,x,y,offset);
            m=m+2;//One Chinese character takes up two chars, so add 2 
            x+=24;//A Chinese character occupies 24 pixels in the picture, so the horizontal coordinates are + 24 each time
        }
        else
        {
            wh=hexcode[m];
            offset=wh*16l;//Calculate the offset of English characters
            paint_ascii(image,x,y,offset);
            m++;//A char
            x+=16;//The original 8 * 16 is changed to 16 * 32. The original pixel is now painted with four pixels
        }
    }
    cv::imshow("image",image);
    cv::waitKey();
}

3. Compile the execution file
Enter the following command

g++ F.cpp -o F `pkg-cnfig --cflags --libs opencv`


The results are as follows:

3, Summary

Through this experiment, I learned how to use the serial port for file transmission, how to use C/C + + to call the opencv Library under Ubuntu to superimpose the name and student number in the logo on the lower right of the picture, and also learned the relationship between file size, baud rate and transmission time, as well as the internal code of Chinese characters Location code coding rules and font data storage format. very interesting.

4, Quote

How does the serial port transmit data.
Principle of Chinese character lattice font.
Drawing dot matrix Chinese characters on pictures with Opencv.
Experiment report assignment 3.

Posted by aunquarra on Wed, 17 Nov 2021 04:53:55 -0800