当前位置:首页 > 公众号精选 > 嵌入式云IOT技术圈
[导读]上篇分享了事件驱动型的菜单框架,也实现了一个基本的小项目。但是怎么看怎么都觉得界面不爽,单纯显示文字的方式实在是太单调了,如果想要显示颜色丰富的图片,MCU资源受限又很难直接在程序中直接定义图片大数组。于是,这次选择在SD卡中放图片,通过Fatfs去读取SD卡中的图片来进行显示……

上次我们分享了事件驱动型的菜单框架,也实现了一个基本的小项目,如下:

基于事件型表驱动法菜单框架之小熊派简易气体探测器实战项目开发(上)

但是怎么看怎么都觉得界面不爽,单纯显示文字的方式实在是太单调了,如果想要显示颜色丰富的图片,MCU资源受限又很难直接在程序中直接定义图片大数组。

于是,我选择在SD卡中放图片,通过Fatfs去读取SD卡中的图片来进行显示,图片都是我自己在阿里图库上找的开源素材,然后用PS自己P的:

废话不多说,来看看实际效果吧!演示视频如下:

这样看起来效果就舒服一点啦。

1、新增功能项

本节分享的内容相较于上篇文章修改/增加了如下功能:

底层配置

  • 修改LCD寄存器,提升LCD刷屏速度
  • 增加Fatfs、SD卡读写功能

应用逻辑

  • 增加模拟长按开机识别
  • 增加开机LOGO以及其它UI的显示
  • 增加菜单(阈值设置、设置、调试模式、仪器信息)

1.1、关于底层配置

1.1.1、提升屏刷新速度

由于要刷图,所以只能想办法尽量提升屏的刷新速度,于是在LCD手册里有这么一个寄存器,可以提升屏的刷新速度:

在LCD驱动初始化代码里,这个寄存器默认配置的是60Hz,也就是0x0F这个值

/* Frame Rate Control in Normal Mode */
LCD_Write_Cmd(0xC6);
// LCD_Write_Data(0x0F); //60HZ
LCD_Write_Data(0x01);  //111Hz 提升屏的刷新速度

本来设置为0x00为119Hz,但是设置完LCD就黑屏了,改为0x01就不会,目前没找到具体原因,将就着用吧。

1.1.2、增加Fatfs、SD卡读写功能


之前也分享了配置方法,详情可以看以下文章:

基于小熊派SD卡+Fatfs+移植开源iniparse解析库并使用

1.2、关于应用逻辑

1.2.1、增加模拟长按开机识别

由于开机前需要加载整幅图片,会存在刷新慢的问题,我们可以先关掉LCD背光,然后等图刷完了再开背光,这样看到就是一张完整的图,这个过程可以用长按一个按键开机的方式来代替,代码实现如下:

void PowerOn(void)
{
    static uint32_t power_press_count = 0;
    HAL_Delay(500);
    while(1)
    {
        if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
        {
            power_press_count ++;
      
            if(power_press_count >= 100)
            {
                //开指示灯
                HAL_GPIO_WritePin(GPIOC, LED_Pin, GPIO_PIN_SET);
                while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
                {
                    HAL_Delay(10);
                }
                break;
            }
        }
        else
        {
            power_press_count = 0;
        }

        HAL_Delay(10);
    }
}

然后在显示开机LOGO前调用即可,显示开机LOGO调用完毕后打开背光显示。

1.2.2、增加开机LOGO以及其它UI的显示

图片资源采用的是24位bmp图,这些图片都存放在SD卡根目录下的LOGO文件夹的子文件夹中:

(1)开机LOGO


(2)主页面UI

(3)检测页面动画LOGO

显示接口移植了硬石科技提供的bsp_bmp.c,他们用的是320*480的RGB屏,小熊派用的是240*240的屏,根据现有的屏我做了一些修改:

uint8_t pColorData[960];     /* 一行真彩色数据缓存 320 * 3 = 960 */
//uint8_t pColorData[720];     /* 一行真彩色数据缓存 240 * 3 = 720 */

显示bmp函数:

/**
  * 函数功能: 显示bmp图片, 24位真彩色
  * 输入参数: x:显示图片左上角x轴坐标
  *           y:显示图片左上角y轴坐标
  *           pic_name:显示图片文件名称
  * 返 回 值: 无
  * 说    明:图片宽度和高度根据图片大小而定
  */
void Lcd_show_bmp(uint16_t x, uint16_t y,char *pic_name)
{
 uint16_t i, j, k;
 int width, height, l_width;
  
 BMP_FileHeader FileHeader;
 BMP_InfoHeader InfoHeader;
  
/*-------------------------------------------------------------------------------------------------------*/
 f_res=f_open(&file,pic_name, FA_OPEN_EXISTING|FA_READ); 
 if(f_res == FR_OK)
 {
  BMP_DEBUG_PRINTF("Open file success\r\n");

  /* 读取文件头信息  两个字节*/         
  f_res=f_read(&file,&FileHeader,sizeof(BMP_FileHeader),&f_num);     
    
  /* 判断是不是bmp文件 "BM"*/
  if(FileHeader.bfType!=0x4d42)
  {
   BMP_DEBUG_PRINTF("file is not .bmp file!\r\n");
   return;
  }
  else
  {
   BMP_DEBUG_PRINTF("Ok this is .bmp file\r\n"); 
  }
  /* 读取BMP文件头信息*/      
  showBmpHeader(&FileHeader);
   
  /* 读取位图信息头信息 */
  f_res=f_read(&file,&InfoHeader,sizeof(BMP_InfoHeader),&f_num);      
  showBmpInforHeader(&InfoHeader);
 }    
 else
 {
  BMP_DEBUG_PRINTF("file open fail!\r\n");
  return;
 }  
/*-------------------------------------------------------------------------------------------------------*/
 width  = InfoHeader.biWidth;
 height = InfoHeader.biHeight; 
  
 /* 计算位图的实际宽度并确保它为32的倍数 */
 l_width = WIDTHBYTES(width* InfoHeader.biBitCount);
  
 if((l_width>960)||(InfoHeader.biBitCount!=24))
 {
  BMP_DEBUG_PRINTF("\n SORRY, PIC IS TOO BIG (X<=320 and bit!=16)\n");
  return;
  }
  f_lseek(&file,FileHeader.bfOffBits);
   
  if(InfoHeader.biBitCount == 24)
  {
    for(i=0;i    {
      /* 开一个图片大小的窗口*/
      LCD_OpenWindow(x, y+height-i-1, width, 1);
   LCD_Write_Cmd(0x2C);
      /* 读取一行bmp的数据到数组pColorData里面 */
      f_read(&file,pColorData,l_width,&f_num);      
      for(j=0;j      {        
        k = j*3;                  //一行中第K个像素的起点        
        //LCD_WRITE_DATA(RGB24TORGB16(pColorData[k+2],pColorData[k+1],pColorData[k])); //写入LCD-GRAM
        //这里调用的是写一次写两个字节的函数
        LCD_Write_2Byte(RGB24TORGB16(pColorData[k+2],pColorData[k+1],pColorData[k]));
      }
    }
  }
 f_close(&file);    
}

修改完后在如果需要图片显示则调用如下接口:

#define START_LOGO "0:/UI/start_logo/start_logo.bmp"

//最开始的时候调用挂载,只挂载一次就好了
//在串行FLASH挂载文件系统,文件系统挂载时会对串行FLASH初始化
f_res = f_mount(&fs, (TCHAR const*)SDPath, 1);
if(f_res == FR_OK)
  printf("》SD卡文件系统挂载成功\n");


//以后只需要调用显示即可
Lcd_show_bmp(0,0,START_LOGO);

注意:图片的路径是SD卡下存放的路径,一定要选对。

1.2.2、增加菜单(阈值设置、设置、调试模式、仪器信息)

在主页面长按右键进入菜单:

此时按左键可以切换选项,短按右键进入某一菜单项,长按右键退出回到主页面,这里只实现了仪器信息,其它项目还没有实现,但要添加也非常简单,期待后期分享。

菜单的实现也很简单,菜单项切换的逻辑和主页面的切换逻辑是一样的:

其余功能:后续还可以做报警记录存储、数据上传到OneNet或者华为云等平台、参数设置等等,总之这个项目可拓展性非常强,这些功能将在本项目开发的下一章节持续进行拓展并分享,欢迎及时关注我的码云仓库与微信公众号文章更新。

本节代码已同步到码云的代码仓库中:

获取方法如下:

1、新建一个文件夹

2、使用git clone远程获取小熊派所有案例代码

我还将之前做的一些项目以及练习例程在近期内全部上传完毕,与大家一起分享交流:

公众号粉丝福利时刻

这里我给大家申请到了福利,本公众号读者购买小熊派开发板可享受9折优惠,有需要购买小熊派以及腾讯物联网开发板的朋友,淘宝搜索即可,跟客服说你是公众号:嵌入式云IOT技术圈 的粉丝,立享9折优惠!

往期精彩

STM32系统bootloader应用

【C进阶】拿着"sizeof这些用法和坑"去吹牛吧!

基于事件型表驱动法菜单框架之小熊派简易气体探测器实战项目开发(上)

上海出差之行--领略外滩美景、RT-Thread总部之旅、嵌友面基、返程记录

觉得本次分享的文章对您有帮助,随手点[在看]并转发分享,也是对我的支持。

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

加利福尼亚州圣克拉拉市—2024年4月30日―AMD(NASDAQ: AMD)今日公布2024年第一季度营业额达55亿美元,毛利率为47%,经营收入3600万美元,净收入1.23亿美元,摊薄后每股收益为0.07美元。基于...

关键字: 嵌入式 PC 人工智能

这款全新的中端MCU系列为设计人员提供了更高水平的安全性和灵活性

关键字: 嵌入式 单片机

2024年4月11日,中国——意法半导体的ST25R100近距离通信(NFC)读取器芯片独步业界,集先进的技术功能、稳定可靠的通信连接和低廉的成本价格于一身,在大规模制造的消费电子和工控设备内,可以提高非接触式互动功能的...

关键字: 嵌入式 数据读取器 芯片

单片机是一种嵌入式系统,它是一块集成电路芯片,内部包含了处理器、存储器和输入输出接口等功能。

关键字: 单片机 编写程序 嵌入式

深圳2024年4月23日 /美通社/ -- 全球AI解决方案与工业级存储领导品牌宜鼎国际 (Innodisk)持续深化边缘AI布局,今(23)日发表全球首创"MIPI over Type-C"独家技术,让旗下嵌入式相机模...

关键字: AI 嵌入式 相机

为增进大家对嵌入式主板的认识,本文将对嵌入式主板以及嵌入式主板常见问题及其解决方法予以介绍。

关键字: 嵌入式 指数 主板

为增进大家对嵌入式系统的认识,本文将对嵌入式系统、嵌入式系统的特点予以介绍。

关键字: 嵌入式 指数 嵌入式系统

为增进大家对嵌入式的认识,本文将对嵌入式、嵌入式工作相关的内容予以介绍。

关键字: 嵌入式 指数 嵌入式技术

机器人操作系统(ROS)驱动程序基于ADI产品而开发,因此可直接在ROS生态系统中使用这些产品。本文将概述如何在应用、产品和系统(例如,自主导航、安全气泡地图和数据收集机器人)中使用和集成这些驱动程序;以及这样将如何有助...

关键字: 电机控制器 机器人 嵌入式

支持高达48V@5A的PD受电模式,达到目前USB PD最高标准。

关键字: 嵌入式 开发板
关闭
关闭