【STM32H745I-DISCO试用】7、文本阅读器
本帖最后由 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中的官方函数。
效果:
一、STM32CuteMX配置
1、LTDS配置
参数选默认,后面不通过STM32CuteMX生成初始化代码。
2、DMA2D配置
参数选默认,后面不通过STM32CuteMX生成初始化代码。
3、FMC配置
参数选默认,后面不通过STM32CuteMX生成初始化代码。
4、Project Manager->Advanced Settings
选择不生成代码,这样代码中之包括必要的LTDS、DMA2D、FMC头文件和HAL库文件,后面将用BSP中的文件来实现LTDS、DMA2D、FMC的初始化。
二、代码修改
1、将以下BSP文件加入工程
这些文件是BSP驱动LCD必要的文件。
通过以下代码完成LCD初始化
//BSP_MMC_Init(0);
BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE);
UTIL_LCD_SetFuncDriver(&LCD_Driver);2、可以运行一些程序测试LCD驱动是否成功
static void Display_DemoDescription(void)
{
char desc;
uint32_t x_size;
uint32_t y_size;
UTIL_LCD_SetFont(&UTIL_LCD_DEFAULT_FONT);
/* Clear the LCD */
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
/* Set the LCD Text Color */
UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_DARKBLUE);
/* Display LCD messages */
UTIL_LCD_DisplayStringAt(0, 10, (uint8_t *)"STM32H745I BSP", CENTER_MODE);
UTIL_LCD_DisplayStringAt(0, 35, (uint8_t *)"Drivers examples", CENTER_MODE);
BSP_LCD_GetXSize(0, &x_size);
BSP_LCD_GetYSize(0, &y_size);
BSP_LCD_FillRect(0, 0, y_size/2 - 15, x_size, 100, UTIL_LCD_COLOR_BLUE);
}
如果正常可以显示一些文字和图案
3、编写一些处理获取中文字模和显示中文的函数
先通过U盘功能将gb2312_80.bin字库文件拷贝到emmc中
读取字库文件获取一个汉字的32个字节字模函数:
FRESULT ReadBinaryFile(const char* path, FSIZE_t ofs, uint8_t* buffer, uint32_t* bytesRead)
{
FRESULT res;
FIL MyFile; /* File object */
UINT br; /* Bytes read */
/* Register the file system object to the FatFs module */
if(f_mount(&MMCFatFs, (TCHAR const*)MMCPath, 0) != FR_OK)
{
printf("f_mount error\r\n");
return res;
}
/* open the file in read mode */
res = f_open(&MyFile, path, FA_READ);
if(res != FR_OK)
{
printf("f_open error\r\n");
return res;
}
res = f_lseek(&MyFile,ofs);
if(res != FR_OK)
{
printf("f_lseek error\r\n");
return res;
}
/* Read the file */
res = f_read(&MyFile, buffer, 32, &br);
if (res != FR_OK) {
f_close(&MyFile); /* Close the file if an error occurs */
return res;
}
*bytesRead = br;
f_close(&MyFile);
return FR_OK; /* Success */
}GB2312字库偏移量计算函数
void get_hzk_bmp(uint8_t *gb2312)
{
uint8_t gbh=0, gbl=0;
uint32_t gbbl=0;
uint32_t hzk_buf_size=0;
gbh=gb2312;
gbl=gb2312;
//printf("%02X,%02X\r\n",gbh,gbl);
if(gbh>=0xb0)
gbbl =((gbh - 0xa7) * 94 + (gbl - 0xa1))*32; // 根据偏移量计算公式计算偏移量
else
gbbl =((gbh - 0xa1) * 94 + (gbl - 0xa1))*32; // 根据偏移量计算公式计算偏移量
if(FR_OK==ReadBinaryFile(GB2312_BIN_FILE,gbbl,hzk_bmp,&hzk_buf_size))
{
/*
printf("read:%d\r\n",hzk_buf_size);
for(int i=0;i<32;i++)
{
printf("%02x ",hzk_bmp);
}
printf("\r\n");
*/
//disp_hz_bmp(hzk_bmp);
}
else{
printf("ReadBinaryFile error\r\n");
}
}
在LCD上显示汉字函数:
uint8_t GUI_Write16CnCharMatrix(uint16_t x, uint16_t y, uint8_t *cn, uint32_t wordColor, uint32_t backColor)
{
uint16_t i=0, j,mx,my,wordNum;
uint8_t zm;
uint8_t color;
uint16_t cur_index=0,ascii_num=0;
mx=x;
my=y;
while (*cn != '\0')
{
if(mx>=480){
mx=x;
my+=16;
}
if(*cn<128){
ascii_num++;
cur_index++;
UTIL_LCD_DisplayChar(mx,my,*cn);
cn += 1;
}
else
{
//if((cur_index==1018)&&(ascii_num%2==1)) return 1;
cur_index+=2;
zm=cn;
zm=cn;
get_hzk_bmp(zm);
for(i=0; i<32; i++)
{ //MSK的位数
color=hzk_bmp;
//printf("%02X,",color);
for(j=0;j<8;j++)
{
/*
if(i%2==0)
{
UTIL_LCD_FillRGBRect(mx+j,my+i/2,&color,8,1);
}else
{
UTIL_LCD_FillRGBRect(mx+j+8,my+i/2,&color,8,1);
}
*/
if((color&0x80)==0x80)
{
if(i%2==0)
{
BSP_LCD_WritePixel(0,mx+j,my+i/2,wordColor);
//UTIL_LCD_SetPixel(mx+j,my+i/2,wordColor);
}
else{
BSP_LCD_WritePixel(0,mx+j+8,my+i/2,wordColor);
//UTIL_LCD_SetPixel(mx+j+8,my+i/2,wordColor);
}
}
else
{
if(i%2==0){
BSP_LCD_WritePixel(0,mx+j,my+i/2,backColor);
//UTIL_LCD_SetPixel(mx+j,my+i/2,backColor);
}
else{
BSP_LCD_WritePixel(0,mx+j+8,my+i/2,backColor);
//UTIL_LCD_SetPixel(mx+j+8,my+i/2,backColor);
}
}
color<<=1;
}//for(j=0;j<8;j++)结束
}
//printf("\r\n");
}
cn += 2;
mx += 16;
}
return ascii_num%2;
}4、main文件
按键外部中断回调控制显示下一页:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
cur_page++;
refresh_page=1;
}
}
while(1)
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(refresh_page==1)
{
refresh_page=0;
UTIL_LCD_Clear(UTIL_LCD_COLOR_BLACK);
UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLACK);
FS_listDirectory();
}
HAL_Delay(500);
}
/* USER CODE END 3 */
}FS_listDirectory文件名瞎起的和内容没关系,
主要的功能是打开文本文件wkz.TXT,在LCD上显示文件内容。
static void FS_listDirectory(void)
{
FRESULT res;
DIR dir;
FILINFO fno;
uint32_t bytesread;
uint16_t i;
//printf(":\r\n");
if(f_mount(&MMCFatFs, (TCHAR const*)MMCPath, 0) == FR_OK)
{
//printf("\r\n");
res = f_opendir(&dir, "/");
if (res == FR_OK)
{
//printf("\r\n");
printf("\r\n:\r\n");
for (;;) {
i++;
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname == 0) break;
if (fno.fname == '.') continue;
printFileInfo(&fno);
}
f_closedir(&dir);
}
if(f_open(&MyFile, "wkz.TXT", FA_READ) == FR_OK)
{
/* Read data from the text file */
memset(wz_buff,0,sizeof(wz_buff));
f_lseek(&MyFile,byte_offset);
res = f_read(&MyFile, ( void *)wz_buff, 1020, (void *)&bytesread);
if((bytesread > 0) && (res == FR_OK))
{
//printf("\r\n:\r\n%s\r\n",rtewz_buffxt);
/* Close the open text file */
f_close(&MyFile);
}
wz_buff='\0';
}
}
UTIL_LCD_SetFont(&Font16);
next_align=GUI_Write16CnCharMatrix(0,0,wz_buff,UTIL_LCD_COLOR_GREEN,UTIL_LCD_COLOR_BLACK);
byte_offset=byte_offset+1020-next_align;
}
三、总结
目前USB接入电脑后,U盘中的内容如下:
其中gb2312_80.bin是字库文件,wkz.txt是要显示内容的文本文件。
本文本质上是实现了读取wkz.txt内容,然后按照GB2312偏移计算公式在gb2312_80.bin找到字模,并在LCD上显示汉字。
文本阅读器非常不错的开发
页:
[1]