上次我們分享了事件驅動型的菜單框架,也實現了一個基本的小項目,如下:
基于事件型表驅動法菜單框架之小熊派簡易氣體探測器實戰(zhàn)項目開發(fā)(上)
但是怎么看怎么都覺得界面不爽,單純顯示文字的方式實在是太單調了,如果想要顯示顏色豐富的圖片,MCU資源受限又很難直接在程序中直接定義圖片大數組。
于是,我選擇在SD卡中放圖片,通過Fatfs去讀取SD卡中的圖片來進行顯示,圖片都是我自己在阿里圖庫上找的開源素材,然后用PS自己P的:
廢話不多說,來看看實際效果吧!演示視頻如下:
這樣看起來效果就舒服一點啦。
1、新增功能項
本節(jié)分享的內容相較于上篇文章修改/增加了如下功能:
底層配置
-
修改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");
??/*?讀取文件頭信息??兩個字節(jié)*/?????????
??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
????????//這里調用的是寫一次寫兩個字節(jié)的函數
????????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掛載文件系統(tǒng),文件系統(tǒng)掛載時會對串行FLASH初始化
f_res?=?f_mount(&fs,?(TCHAR?const*)SDPath,?1);
if(f_res?==?FR_OK)
??printf("》SD卡文件系統(tǒng)掛載成功\n");
//以后只需要調用顯示即可
Lcd_show_bmp(0,0,START_LOGO);
注意:圖片的路徑是SD卡下存放的路徑,一定要選對。
1.2.2、增加菜單(閾值設置、設置、調試模式、儀器信息)
在主頁面長按右鍵進入菜單:
此時按左鍵可以切換選項,短按右鍵進入某一菜單項,長按右鍵退出回到主頁面,這里只實現了儀器信息,其它項目還沒有實現,但要添加也非常簡單,期待后期分享。
菜單的實現也很簡單,菜單項切換的邏輯和主頁面的切換邏輯是一樣的:
其余功能:后續(xù)還可以做報警記錄存儲、數據上傳到OneNet或者華為云等平臺、參數設置等等,總之這個項目可拓展性非常強,這些功能將在本項目開發(fā)的下一章節(jié)持續(xù)進行拓展并分享,歡迎及時關注我的碼云倉庫與微信公眾號文章更新。
本節(jié)代碼已同步到碼云的代碼倉庫中:
獲取方法如下:
1、新建一個文件夾
2、使用git clone遠程獲取小熊派所有案例代碼
我還將之前做的一些項目以及練習例程在近期內全部上傳完畢,與大家一起分享交流:
公眾號粉絲福利時刻
這里我給大家申請到了福利,本公眾號讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派以及騰訊物聯(lián)網開發(fā)板的朋友,淘寶搜索即可,跟客服說你是公眾號:嵌入式云IOT技術圈?的粉絲,立享9折優(yōu)惠!
往期精彩
STM32系統(tǒng)bootloader應用
【C進階】拿著"sizeof這些用法和坑"去吹牛吧!
基于事件型表驅動法菜單框架之小熊派簡易氣體探測器實戰(zhàn)項目開發(fā)(上)
上海出差之行--領略外灘美景、RT-Thread總部之旅、嵌友面基、返程記錄
覺得本次分享的文章對您有幫助,隨手點[在看]
并轉發(fā)分享,也是對我的支持。
免責聲明:本文內容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!