[STM32H7] 【STM32H745I-DISCO试用】7、文本阅读器

[复制链接]
1420|1
 楼主| sujingliang 发表于 2025-1-27 11:08 | 显示全部楼层 |阅读模式
本帖最后由 sujingliang 于 2025-1-27 11:45 编辑

本文在以下2篇:
【STM32H745I-DISCO试用】5、eMMC+USB MSC=U盘: https://bbs.21ic.com/icview-3429458-1-1.html
【STM32H745I-DISCO试用】6、FATFS访问EMMC: https://bbs.21ic.com/icview-3429794-1-1.html
基础上继续做个文本阅读器,前面已经实现了U盘功能和FATFS访问文件功能,下面将驱动屏幕,并支持显示文本文件内容。
LCD驱动采用BSP中的官方函数。

效果:
tutieshi_640x360_6s.gif

一、STM32CuteMX配置
1、LTDS配置
参数选默认,后面不通过STM32CuteMX生成初始化代码。
44.png
2、DMA2D配置
参数选默认,后面不通过STM32CuteMX生成初始化代码。
45.png
3、FMC配置
参数选默认,后面不通过STM32CuteMX生成初始化代码。
47.png

4、Project Manager->Advanced Settings
46.png

选择不生成代码,这样代码中之包括必要的LTDS、DMA2D、FMC头文件和HAL库文件,后面将用BSP中的文件来实现LTDS、DMA2D、FMC的初始化。

二、代码修改
1、将以下BSP文件加入工程
372436796f2e2dafa4.png
这些文件是BSP驱动LCD必要的文件。

通过以下代码完成LCD初始化
  1. //BSP_MMC_Init(0);
  2.         BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE);
  3.   UTIL_LCD_SetFuncDriver(&LCD_Driver);
2、可以运行一些程序测试LCD驱动是否成功
  1. static void Display_DemoDescription(void)
  2. {
  3.   char desc[64];
  4.   uint32_t x_size;
  5.   uint32_t y_size;

  6.   UTIL_LCD_SetFont(&UTIL_LCD_DEFAULT_FONT);

  7.   /* Clear the LCD */
  8.   UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
  9.   UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);

  10.   /* Set the LCD Text Color */
  11.   UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_DARKBLUE);

  12.   /* Display LCD messages */
  13.   UTIL_LCD_DisplayStringAt(0, 10, (uint8_t *)"STM32H745I BSP", CENTER_MODE);
  14.   UTIL_LCD_DisplayStringAt(0, 35, (uint8_t *)"Drivers examples", CENTER_MODE);

  15.   BSP_LCD_GetXSize(0, &x_size);
  16.   BSP_LCD_GetYSize(0, &y_size);

  17. BSP_LCD_FillRect(0, 0, y_size/2 - 15, x_size, 100, UTIL_LCD_COLOR_BLUE);
  18. }


如果正常可以显示一些文字和图案
4.jpg

3、编写一些处理获取中文字模和显示中文的函数

先通过U盘功能将gb2312_80.bin字库文件拷贝到emmc中

读取字库文件获取一个汉字的32个字节字模函数:
  1. FRESULT ReadBinaryFile(const char* path, FSIZE_t ofs, uint8_t* buffer, uint32_t* bytesRead)
  2. {
  3.         FRESULT res;
  4.         FIL MyFile;             /* File object */
  5.         UINT br;            /* Bytes read */
  6.         
  7.         /* Register the file system object to the FatFs module */
  8.   if(f_mount(&MMCFatFs, (TCHAR const*)MMCPath, 0) != FR_OK)
  9.   {
  10.                 printf("f_mount error\r\n");
  11.                 return res;
  12.   }
  13.   /* open the file in read mode */
  14.   res = f_open(&MyFile, path, FA_READ);
  15.   if(res != FR_OK)
  16.   {
  17.                 printf("f_open error\r\n");
  18.                 return res;
  19.   }
  20.         
  21.         res = f_lseek(&MyFile,ofs);
  22.   if(res != FR_OK)
  23.   {
  24.                 printf("f_lseek error\r\n");
  25.                 return res;
  26.   }        
  27.         
  28.         /* Read the file */
  29.         res = f_read(&MyFile, buffer, 32, &br);
  30.         if (res != FR_OK) {
  31.                         f_close(&MyFile); /* Close the file if an error occurs */
  32.                         return res;
  33.         }
  34.         
  35.         *bytesRead = br;
  36.         
  37.         f_close(&MyFile);        
  38.         return FR_OK; /* Success */
  39. }
GB2312字库偏移量计算函数
  1. void get_hzk_bmp(uint8_t *gb2312)
  2. {
  3.         uint8_t gbh=0, gbl=0;
  4.         uint32_t gbbl=0;
  5.         uint32_t hzk_buf_size=0;
  6.         
  7.         gbh=gb2312[0];
  8.         gbl=gb2312[1];
  9.         
  10.         //printf("%02X,%02X\r\n",gbh,gbl);
  11.         
  12.         if(gbh>=0xb0)
  13.                         gbbl =((gbh - 0xa7) * 94 + (gbl - 0xa1))*32; // 根据偏移量计算公式计算偏移量
  14.         else
  15.                    gbbl =((gbh - 0xa1) * 94 + (gbl - 0xa1))*32; // 根据偏移量计算公式计算偏移量
  16.         
  17.         if(FR_OK==ReadBinaryFile(GB2312_BIN_FILE,gbbl,hzk_bmp,&hzk_buf_size))
  18.         {
  19.                 /*
  20.                 printf("read:%d\r\n",hzk_buf_size);
  21.                 for(int i=0;i<32;i++)
  22.                 {        
  23.                         printf("%02x ",hzk_bmp[i]);
  24.                 }
  25.                 printf("\r\n");
  26.                 */
  27.                 //disp_hz_bmp(hzk_bmp);
  28.         }
  29.         else{
  30.                 printf("ReadBinaryFile error\r\n");
  31.         }
  32. }


在LCD上显示汉字函数:
  1. uint8_t GUI_Write16CnCharMatrix(uint16_t x, uint16_t y, uint8_t *cn, uint32_t wordColor, uint32_t backColor)
  2. {
  3.   uint16_t i=0, j,mx,my,wordNum;
  4.         uint8_t zm[2];
  5.   uint8_t color;
  6.         uint16_t cur_index=0,ascii_num=0;
  7.         mx=x;
  8.   my=y;
  9.         while (*cn != '\0')
  10.     {
  11.                 if(mx>=480){
  12.             mx=x;
  13.             my+=16;
  14.         }
  15.                
  16.                 if(*cn<128){
  17.                         ascii_num++;
  18.                         cur_index++;
  19.                         UTIL_LCD_DisplayChar(mx,my,*cn);
  20.                         cn += 1;
  21.                 }
  22.                 else
  23.                 {
  24.                         //if((cur_index==1018)&&(ascii_num%2==1)) return 1;
  25.                         cur_index+=2;
  26.                         zm[1]=cn[1];
  27.                         zm[0]=cn[0];
  28.                         

  29.                         
  30.                         get_hzk_bmp(zm);


  31.                         for(i=0; i<32; i++)
  32.                         {   //MSK的位数
  33.                                 color=hzk_bmp[i];
  34.                                 //printf("%02X,",color);
  35.                                 
  36.                                 
  37.                                 for(j=0;j<8;j++)
  38.                                 {
  39.                                         /*
  40.                                         if(i%2==0)
  41.                                         {
  42.                                                 UTIL_LCD_FillRGBRect(mx+j,my+i/2,&color,8,1);
  43.                                         }else
  44.                                         {
  45.                                                 UTIL_LCD_FillRGBRect(mx+j+8,my+i/2,&color,8,1);
  46.                                         }
  47.                                         */
  48.                                        
  49.                                         if((color&0x80)==0x80)
  50.                                         {
  51.                                                 if(i%2==0)
  52.                                                 {
  53.                                                         BSP_LCD_WritePixel(0,mx+j,my+i/2,wordColor);
  54.                                                         //UTIL_LCD_SetPixel(mx+j,my+i/2,wordColor);
  55.                                                 }
  56.                                                 else{
  57.                                                         BSP_LCD_WritePixel(0,mx+j+8,my+i/2,wordColor);
  58.                                                         //UTIL_LCD_SetPixel(mx+j+8,my+i/2,wordColor);
  59.                                                 }
  60.                                         }
  61.                                         else
  62.                                         {
  63.                                                 if(i%2==0){
  64.                                                         BSP_LCD_WritePixel(0,mx+j,my+i/2,backColor);
  65.                                                         //UTIL_LCD_SetPixel(mx+j,my+i/2,backColor);
  66.                                                 }
  67.                                                 else{
  68.                                                         BSP_LCD_WritePixel(0,mx+j+8,my+i/2,backColor);
  69.                                                         //UTIL_LCD_SetPixel(mx+j+8,my+i/2,backColor);
  70.                                                 }
  71.                                         }
  72.                                        
  73.                                         color<<=1;
  74.                                        
  75.                                 }//for(j=0;j<8;j++)结束
  76.                         }
  77.                         //printf("\r\n");
  78.                 }
  79.                 cn += 2;
  80.     mx += 16;
  81.         }
  82.         return ascii_num%2;
  83. }
4、main文件

按键外部中断回调控制显示下一页:
  1. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  2. {
  3.   
  4.   if (GPIO_Pin == GPIO_PIN_13)
  5.   {
  6.                 cur_page++;
  7.                 refresh_page=1;
  8.    
  9.   }
  10. }

while(1)
  1. while (1)
  2.   {
  3.     /* USER CODE END WHILE */

  4.     /* USER CODE BEGIN 3 */

  5.                 if(refresh_page==1)
  6.                 {
  7.                         refresh_page=0;
  8.                         UTIL_LCD_Clear(UTIL_LCD_COLOR_BLACK);
  9.                         UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLACK);
  10.                         FS_listDirectory();
  11.                 }
  12.                 HAL_Delay(500);
  13.   }
  14.   /* USER CODE END 3 */
  15. }
FS_listDirectory文件名瞎起的和内容没关系,
主要的功能是打开文本文件wkz.TXT,在LCD上显示文件内容。
  1. static void FS_listDirectory(void)
  2. {
  3.         FRESULT res;
  4.         DIR dir;
  5.         FILINFO fno;
  6.         uint32_t bytesread;
  7.         uint16_t i;
  8.         
  9.         //printf("[Directory list]:\r\n");
  10.   if(f_mount(&MMCFatFs, (TCHAR const*)MMCPath, 0) == FR_OK)
  11.   {
  12.                         //printf("[mount MMC success]\r\n");
  13.                         res = f_opendir(&dir, "/");
  14.                         if (res == FR_OK)
  15.                         {
  16.                                 //printf("[open directory success]\r\n");
  17.                                 printf("\r\n[list directory / files ......]:\r\n");
  18.         for (;;) {
  19.                                                 i++;
  20.             res = f_readdir(&dir, &fno);
  21.             if (res != FR_OK || fno.fname[0] == 0) break;
  22.             if (fno.fname[0] == '.') continue;
  23.                                        
  24.                                         printFileInfo(&fno);
  25.                                        
  26.         }
  27.                         
  28.         f_closedir(&dir);
  29.                 }
  30.                
  31.                                 if(f_open(&MyFile, "wkz.TXT", FA_READ) == FR_OK)
  32.                                 {
  33.                                                                 /* Read data from the text file */
  34.                                                 memset(wz_buff,0,sizeof(wz_buff));
  35.                                                 
  36.                                                 f_lseek(&MyFile,byte_offset);
  37.                                                 
  38.                                                 res = f_read(&MyFile, ( void *)wz_buff, 1020, (void *)&bytesread);

  39.                                                 if((bytesread > 0) && (res == FR_OK))
  40.                                                 {
  41.                                                         //printf("\r\n[Display wz_buff.TXT file content]:\r\n%s\r\n",rtewz_buffxt);
  42.                                                                                 /* Close the open text file */
  43.                                                                                 f_close(&MyFile);
  44.                                                 }
  45.                                                 wz_buff[1020]='\0';
  46.                                 }
  47.         }
  48.                                 
  49.                                 UTIL_LCD_SetFont(&Font16);
  50.                                 next_align=GUI_Write16CnCharMatrix(0,0,wz_buff,UTIL_LCD_COLOR_GREEN,UTIL_LCD_COLOR_BLACK);
  51.                                 byte_offset=byte_offset+1020-next_align;
  52. }

三、总结
目前USB接入电脑后,U盘中的内容如下:
49.png
其中gb2312_80.bin是字库文件,wkz.txt是要显示内容的文本文件。
本文本质上是实现了读取wkz.txt内容,然后按照GB2312偏移计算公式在gb2312_80.bin找到字模,并在LCD上显示汉字。


星辰大海不退缩 发表于 2025-1-30 13:41 | 显示全部楼层
文本阅读器非常不错的开发
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

147

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部