標(biāo)題: 單片機(jī)設(shè)計(jì)之基于STM32的LCD電子鐘的設(shè)計(jì)(LVGL+TFT彩屏) [打印本頁]
作者: meno 時(shí)間: 2024-12-2 12:57
標(biāo)題: 單片機(jī)設(shè)計(jì)之基于STM32的LCD電子鐘的設(shè)計(jì)(LVGL+TFT彩屏)
零.前置說明 由于本項(xiàng)目使用了LVGL開源框架,建議至少需要了解一點(diǎn)LVGL!。
一.項(xiàng)目背景
最近學(xué)校開始了單片機(jī)設(shè)計(jì),筆者深知自己學(xué)疏才淺,思索再三,選擇了相對比較容易完成的LCD電子鐘的制作。
要求如下:
c004186a972d4cda933cb16206044d9c.jpg (110.18 KB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
也是因?yàn)楣P者最近淺淺學(xué)習(xí)了下LVGL,所以便想利用手里的一塊TFT彩屏和STM32F407來完成這次的設(shè)計(jì)。
二.材料介紹
筆者手里的這塊屏幕是1.8寸128*160的SPI屏幕:
9276135b8fc048ccb0d7cb978c15dcb1.png (67.89 KB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
主控為嘉立創(chuàng)天空星(STM32F407VET6):
e688af948af249c9b2711c1c779218a5.png (707.82 KB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
還有一塊不知是什么芯片的降壓12V-5V,大小大概是16mm*22mm:
57e6ff6cd47945b186c2d8a840270700.jpeg (507.17 KB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
底板是筆者自己繪制的PCB:
82ff5058735c4401b7c4d8bd5adfd79f.png (270.79 KB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
實(shí)物如下:
030150f9cbe44df58531ab0dc2395f11.jpeg (1.59 MB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
d6d5cd485eb14e3db8dea60ffe1e03fe.png (4.86 KB, 下載次數(shù): 0)
下載附件
2024-12-3 12:47 上傳
三.代碼編寫
由于整體功能還是比較簡單的,軟件部分只涉及到按鍵掃描以及時(shí)鐘屏幕刷新,所以我們直接建立好Clock和Key的文件:
按鍵
按鍵就完全是正常按鍵掃描代碼的寫法,注意這里消抖選用的三行按鍵消抖,主要是考慮到延時(shí)按鍵消抖可能會破壞掉LVGL整個(gè)框架的時(shí)基,所以使用的這種方式。
- // KEY1 PD8
- // KEY2 PD9
- // KEY3 PD10
- // KEY4 PD11
- // KEY5 PD12
- // KEY6 PD13
-
- #include "Key.h"
-
- uint8_t Key_Value,Key_Down,Key_Up,Key_Last;
-
- uint8_t Key_GetValue(void)
- {
- if(HAL_GPIO_ReadPin(GPIOD,KEY1_Pin) == 0)
- return 1;
- if(HAL_GPIO_ReadPin(GPIOD,KEY2_Pin) == 0)
- return 2;
- if(HAL_GPIO_ReadPin(GPIOD,KEY3_Pin) == 0)
- return 3;
- if(HAL_GPIO_ReadPin(GPIOD,KEY4_Pin) == 0)
- return 4;
- if(HAL_GPIO_ReadPin(GPIOD,KEY5_Pin) == 0)
- return 5;
- if(HAL_GPIO_ReadPin(GPIOD,KEY6_Pin) == 0)
- return 6;
- return 0;
- }
-
- void Key_RemoveShake(void)
- {
- Key_Value = Key_GetValue();//獲取按下鍵值
- Key_Down = Key_Value & (Key_Value ^ Key_Last);//獲取下降沿
- Key_Up = ~Key_Value & (Key_Value ^ Key_Last);//獲取上升沿
- Key_Last = Key_Value;//鍵值覆蓋
- }
-
- Key_Type Key_Press(void)
- {
- return Key_Down ? (Key_Type)Key_Value : 0;
- }
復(fù)制代碼 時(shí)鐘 時(shí)鐘要實(shí)現(xiàn)正常顯示以及修改界面顯示,所以最好定義一個(gè)模式變量來進(jìn)行分辨,然后根據(jù)模式不同顯示不同的數(shù)據(jù)。
- #include "Clock.h"
- #include <stdio.h>
- #include "Key.h"
-
- extern lv_ui guider_ui;
-
- uint8_t ClockNow[3] = {23,59,55},ClockChange[3] = {0,0,0};
- uint8_t ClockString_hour[2],ClockString_minute[2],ClockString_second[2];
-
- Clock_DisMode Clock_Mode = NormalMode;
-
- //時(shí)鐘初始化
- void Clock_Init(void)
- {
-
- }
-
- void Clock_NumToString(void)
- {
- if(Clock_Mode == NormalMode)
- {
- ClockString_hour[0] = ClockNow[0] / 10 + '0'; // 十位數(shù)字
- ClockString_hour[1] = ClockNow[0] % 10 + '0'; // 個(gè)位數(shù)字
-
- ClockString_minute[0] = ClockNow[1] / 10 + '0'; // 十位數(shù)字
- ClockString_minute[1] = ClockNow[1] % 10 + '0'; // 個(gè)位數(shù)字
-
- ClockString_second[0] = ClockNow[2] / 10 + '0'; // 十位數(shù)字
- ClockString_second[1] = ClockNow[2] % 10 + '0'; // 個(gè)位數(shù)字
- }
- else
- {
- ClockString_hour[0] = ClockChange[0] / 10 + '0'; // 十位數(shù)字
- ClockString_hour[1] = ClockChange[0] % 10 + '0'; // 個(gè)位數(shù)字
-
- ClockString_minute[0] = ClockChange[1] / 10 + '0'; // 十位數(shù)字
- ClockString_minute[1] = ClockChange[1] % 10 + '0'; // 個(gè)位數(shù)字
-
- ClockString_second[0] = ClockChange[2] / 10 + '0'; // 十位數(shù)字
- ClockString_second[1] = ClockChange[2] % 10 + '0'; // 個(gè)位數(shù)字
- }
- }
-
- //時(shí)鐘正常調(diào)度
- void Clock_Handler(void)
- {
- static uint16_t Timer_1000ms;
- if(++Timer_1000ms > 20)
- {
- Timer_1000ms = 0;
- if(++ClockNow[2] >= 60)
- {
- ClockNow[2] = 0;
- if(++ClockNow[1] >= 60)
- {
- ClockNow[1] = 0;
- if(++ClockNow[0] >= 24)
- {
- ClockNow[0] = 0;
- }
- }
- }
- }
- }
-
- void Clock_RefreshToPage(void)
- {
- Clock_NumToString();
- lv_label_set_text(guider_ui.screen_label_hour,(const char*)ClockString_hour);
- lv_label_set_text(guider_ui.screen_label_minute,(const char*)ClockString_minute);
- lv_label_set_text(guider_ui.screen_label_second, (const char*)ClockString_second);
- }
-
- //設(shè)置時(shí)鐘完成
- void Clock_SetValueFinish(void)
- {
- uint8_t i;
- for(i = 0;i < 3;i ++)
- {
- ClockNow[i] = ClockChange[i];
- }
- }
-
- //設(shè)置時(shí)間任務(wù)
- void Clock_SetValueTask(void)
- {
- Key_RemoveShake();
- switch(Key_Press())
- {
- case KEY1:
- {
- uint8_t i;
- for(i = 0;i < 3;i ++)//更新設(shè)置時(shí)間
- {
- ClockChange[i] = ClockNow[i];
- }
- Clock_Mode = SetMode;//轉(zhuǎn)換模式
- break;
- }
- case KEY2://小時(shí)++
- {
- ClockChange[0] = ClockChange[0] >= 23 ? 0 : ClockChange[0] + 1;
- break;
- }
- case KEY3://分鐘++
- {
- ClockChange[1] = ClockChange[1] >= 59 ? 0 : ClockChange[1] + 1;
- break;
- }
- case KEY4:
- {
- Clock_SetValueFinish();
- Clock_Mode = NormalMode;//轉(zhuǎn)換模式
- break;
- }
- default:
- break;
- }
- }
-
- //按鍵測試案例
- void Clock_Demo(void)
- {
- Key_RemoveShake();
- if(Key_Press() == KEY1)
- ClockNow[0]++;
- }
復(fù)制代碼 主函數(shù) 主函數(shù)中只需要在while里調(diào)用CLock的文件即可(整個(gè)工程要在移植好的LVGL環(huán)境下):
- while (1)
- {
- static uint8_t LVGL_Timer_5ms = 0;//任務(wù)調(diào)度函數(shù)的5ms定時(shí)
- HAL_Delay(1-1);
- if(LVGL_Timer_5ms++ >= 5)
- {
- lv_timer_handler();//任務(wù)調(diào)度函數(shù)
- LVGL_Timer_5ms = 0;
- }
- Clock_Init();
- Clock_Handler();
- Clock_SetValueTask();
- Clock_RefreshToPage();
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
- }</font></font></font>
復(fù)制代碼
四.效果
五.總結(jié) 本次只是做了個(gè)簡單的界面實(shí)現(xiàn)了LCD電子鐘,后續(xù)更復(fù)雜的功能待讀者們自行開發(fā)!
由于整個(gè)工程太過龐大,總體積有100+MB無法上傳至本站,因此只上傳核心代碼至此
code.zip
(453.16 KB, 下載次數(shù): 0)
2024-12-3 12:47 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
,LVGL環(huán)境框架還需讀者自行配置。
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |