Thanks again to Qinheng for sending this CH32V103 development board, which integrates a simulation downloader, USB to serial converter, and is compatible with Arduino interfaces, making it very convenient to use.The FAT file system has evolved over the years (FAT, FAT12, FAT16, FAT32, exFAT) and is now widely used in small capacity storage media such as memory cards and USB drives.Due to maximum capacity limitations, FAT and FAT16 have gradually faded into history, while FAT32 is still widely used and is what I am currently using.This article uses FATFS to implement file directory retrieval and long file name reading and conversion, ultimately printing the results to the serial debugging assistant.First, let’s take a look at what is stored on the USB drive (accidentally revealing my age).:
That’s half the battle won. However, since long file names are encoded in Unicode, reading them directly and printing them via the serial port results in garbled characters. This involves encoding conversion issues, as the serial assistant generally displays characters in GBK encoding. Different encodings lead to garbled text, requiring the use of encoding conversion functions in FATFS. However, since the conversion between GBK and Unicode is irregular, it can only be done through a lookup table. Why make it difficult for Chinese and non-English characters? This table is quite large and occupies over 170K of storage space…But I have a 64K Flash microcontroller???Challenges drive motivation. Should I add external Flash? If there is no Flash, I can only use a memory card, which is convenient since these songs are also stored on the memory card. So, I will create a directory, SYS, to store the Unicode and GBK conversion lookup table.When the memory card is inserted, mount the file system and read the Unicode and GBK conversion table.
if(SD_Detect()) { if(sd_status == 0) { sd_status = 1; printf("Insert\r\n"); } } else { sd_status = 0; } if(sd_status == 1) { path[0] = '0'; path[1] = ':'; path[2] = 0; res_sd = f_mount(&fs,path,1); if(res_sd == FR_OK) { sd_status = 2; printf("Mount Ok\r\n"); path[0] = '0'; path[1] = ':'; path[2] = '/'; path[3] = 'S'; path[4] = 'Y'; path[5] = 'S'; path[6] = '/'; path[7] = 'U'; path[8] = 'N'; path[9] = 'I'; path[10] = 'G'; path[11] = 'B'; path[12] = 'K'; path[13] = '.'; path[14] = 'B'; path[15] = 'I'; path[16] = 'N'; path[17] = 0; res_sd = f_open(&gd_FileUNItoGBK,path,FA_READ); if(res_sd == FR_OK) printf("Load UNIGBK.BIN Ok\r\n"); else printf("Load UNIGBK.BIN Fail\r\n"); path[2] = '/'; path[3] = 0; scan_files(path); } else if(res_sd == FR_NO_FILESYSTEM) { printf("No File System\r\n"); } else { printf("Mount Fail\r\n"); } }
Rewrite the ff_convert function in cc936.c to read the lookup table information from the specified offset on the memory card.
WCHAR ff_convert ( /* Converted code, 0 means conversion error */ WCHAR src, /* Character code to be converted */ UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */){ WCHAR t[2]; WCHAR c; DWORD i, li, hi; WCHAR n; UINT cout; DWORD offset; if(src < 0x80) // ASCII return src; else { if(dir) // GBK TO UNICODE { offset = gd_FileUNItoGBK.fsize >> 1; } else // UNICODE TO GBK { offset = 0; } if(gd_FileUNItoGBK.fsize != 0) { hi = gd_FileUNItoGBK.fsize >> 1; hi = (hi >> 2) - 1; li = 0; for(n=16; n; n--) { i = li + ((hi - li) >> 1); f_lseek(&gd_FileUNItoGBK, (i << 2) + offset); f_read(&gd_FileUNItoGBK, &t, 4, &cout); if(src == t[0]) break; if(src > t[0]) li = i; else hi = i; } c = n ? t[1] : 0; } else c = 0; } return c;}
The core part is basically complete. Next, read the long file names, convert them to GBK encoding, and print them.
p = pt; pth = *fno.lfname ? fno.lfname : fno.fname; while(*pth != 0) { ct = ff_convert(*pth, 0); if(ct > 255) { *p = (u8)(ct>>8); p++; *p = (u8)ct; p++; } else { *p = (u8)ct; p++; } pth++; } *p = 0; printf("%s\r\n", pt);
Finally, we can display Chinese long file names.This time, let’s change the display method.Let’s get to work.
I found a 12864 display screen from the clutter, a very mini one, 0.96 inches, which can be found on various online stores for about 10 yuan.
How to light up the screen is not covered in this article; the materials provided with the screen are sufficient to light it up.This time, the main goal is to read and display the font library from the memory card.Since the files stored on the memory card may have various names, to display any Chinese character, we need to generate a font library by taking a modulus of all Chinese characters.Why not just print all the Chinese characters and take a modulus one by one?2. With so many Chinese characters, how do I quickly find the modulus for the character “我” among them?What? I forgot the position of the modulus for “我” when I took it?
For the first issue, thanks to some predecessors, there are already many software tools available for generating font libraries.For the second issue, there are many types of Chinese character encodings, such as GB2312 (which includes 6763 characters), GBK (which includes 21886 characters), Unicode (which includes over 60,000 characters), and UTF-32 (which includes 120,000 characters).With these various encodings, the encoding represents the order of the characters, so we can directly compare them. Here, we take GBK and Unicode as examples. The first Chinese character in GBK is “丂”, with a hexadecimal encoding of 8140, and each character is represented by 2 bytes.How to obtain the GBK encoding of a Chinese character? Here is a simple method using the serial assistant!Short the RX and TX pins, set the sending character to GBK encoding, and the receiving setting to hexadecimal. The received character encoding after sending will be:
qh = *Str; ql = *(++Str); if(qh<0x81 || ql<0x40 || ql==0xff || qh==0xff) // Rarely used Chinese characters { for(i=0; i<(Size<<1) ;i++) *Buff++ = 0x00; // Fill return 0; } if(ql < 0x7f) ql-=0x40; else ql-=0x41; qh -= 0x81; foffset = ((u32)190 * qh + ql) * (Size&0x07 ? (Size>>3)+1 : Size>>3) * Size; // Get the byte offset in the font library
Once the font information is obtained, it can be displayed, and I won’t elaborate further. Here is the image:
ENDThis article is an original piece written by gtbestom, a senior member of 21ic.▍Recommended ReadingLighting Up the Onboard 0.91-inch OLED of HC32F460 Development BoardUsing TencentOS Tiny Operating System on STM32L431 to Connect to Tencent IoT Development PlatformTeach You a Trick: How to Efficiently Manage Memory on MCU?→ Follow for more updates ←