前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于事件型表驱动法菜单框架之小熊派简易气体探测器实战项目开发(中)

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

作者头像
杨源鑫
发布2020-11-02 10:52:33
5740
发布2020-11-02 10:52:33
举报
文章被收录于专栏:嵌入式开发圈嵌入式开发圈

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

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

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

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

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

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

1、新增功能项

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

底层配置

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

应用逻辑

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

1.1、关于底层配置

1.1.1、提升屏刷新速度

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

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

代码语言:javascript
复制
/* 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背光,然后等图刷完了再开背光,这样看到就是一张完整的图,这个过程可以用长按一个按键开机的方式来代替,代码实现如下:

代码语言:javascript
复制
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的屏,根据现有的屏我做了一些修改:

代码语言:javascript
复制
uint8_t pColorData[960];     /* 一行真彩色数据缓存 320 * 3 = 960 */
//uint8_t pColorData[720];     /* 一行真彩色数据缓存 240 * 3 = 720 */

显示bmp函数:

代码语言:javascript
复制
/**
  * 函数功能: 显示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<height;++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<width;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);    
}

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

代码语言:javascript
复制
#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远程获取小熊派所有案例代码

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

往期精彩

STM32系统bootloader应用

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

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式云IOT技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、新增功能项
    • 1.1、关于底层配置
      • 1.1.1、提升屏刷新速度
      • 1.1.2、增加Fatfs、SD卡读写功能
    • 1.2、关于应用逻辑
      • 1.2.1、增加模拟长按开机识别
      • 1.2.2、增加开机LOGO以及其它UI的显示
      • 1.2.2、增加菜单(阈值设置、设置、调试模式、仪器信息)
      • 1、新建一个文件夹
      • 2、使用git clone远程获取小熊派所有案例代码
  • 往期精彩
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档