物聯網之LoRa開發與應用三(Lora人機介面開發)
文章要點:
1、TFT液晶屏工作原理
2、TFT液晶屏驅動開發
3、TFT人機介面開發
TFT液晶屏工作原理
內容概要:
1、TFT液晶屏顯示原理
2、1.44寸TFT液晶屏工作原理
3、1.44寸TFT液晶屏硬體設計
TFT液晶屏如何顯示:
顏色深度:
Color 介紹 :
① R,G,B三基色組合形成各種顏色。
②能顯示的顏色數由RGB的數字訊號的位數來決定。(8bit 數字訊號剛好能顯示16.7M種顏色)
以3bit為例數字訊號為例:
For 3 bit : 23(R) * 23(G) * 23(B) = 256 colors
For 6 bit : 26(R) * 26(G) * 26(B) = 262144 colors(242K)
For8 bit: 28(R) * 28(G) * 28(B) =16777216 colors(16.7M)
For10 bit: 210(R) * 210(G) * 210(B) =1073741824 colors(1 billion)
1.44寸TFT模組:
TFT驅動控制器:
1.44寸模組電路詳解:
TFT液晶屏驅動開發(驅動晶片資料下載連結:https://pan.baidu.com/s/1-tOqlGj_qsniN4xrjIp_aA 密碼:1och)
內容概要:
1、TFT液晶屏硬體介面驅動開發
2、TFT液晶屏取模方式
3、TFT液晶屏顯示字串
硬體介面初始化
根據硬體設計,LoRa與LCD共用SPI匯流排,且LCD_MISO用於命令/資料模式切換控制。
需要修改gpio初始化原始碼,讓片選介面拉高。
寫指令:
寫資料:
初始化:
設定顯示區域:
設定行列起始地址,在此區域內寫點資料自動換行
畫點和清屏:
RGB565顏色對照表:(詳細對照表可以百度搜索)
驅動原始碼移植:(原始碼下載連結:https://pan.baidu.com/s/1MLheOr6d3KDLRROalrPugg 密碼:zdjg)
將原始碼中的三個檔案按照如下位置放入相應的工程檔案目錄下:
開啟工程檔案,將lcd.c新增到工程中:
清除警告:
LoRa模組和LCD顯示屏都是接到同一個SPI引腳,初始化時片選(NSS)引腳要修改為不使能(高電平):
上電後液晶屏顯示黃色螢幕:
在main.c函式中新增如下程式碼:
1、新增標頭檔案:
#include "lcd.h"
2、新增初始化函式和清屏函式:
Lcd_Init();//LCD初始化函式
Lcd_Clear(YELLOW);//全屏清屏函式,引數是清屏時填充的顏色(16位表示)
取模方式:
取模工具:(工具載入連結:https://pan.baidu.com/s/1jwRDjs69i0K9j6ctEFQvtg 密碼:yedy)
文字取模軟體(該工具在本專案中使用不到,可自行了解)
工程中新建一個.h檔案,將生成的子模資料複製到該檔案中,將資料修改成如下陣列,並在lcd.c中新增顯示文字的程式碼:
圖片取模軟體
將生成的.h檔案複製到工程的相關目錄中,並在lcd.c中新增顯示圖片的程式碼:
/*************************************************
函式名:showimage
功能:顯示一副圖片
入口引數:圖片快取
返回值:無
*************************************************/
//因為一副128*128的圖片需要32768個8位陣列成(陣列元素有32768個),很顯然陣列太大,不能放到記憶體中,只能放在靜態儲存區,所以引數使用 const 修飾
void showimage(const unsigned char *p)
{
unsigned int i;
uint16_t HData,LData;
Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
Lcd_WriteIndex(0x2C);
for(i = 0;i < 128*128;i++)//因為我們已經設定顯示屏顯示範圍為128*128,所以寫滿一行會自動換行,不需單獨寫程式碼
{
LData = *(p+i*2);
HData = *(p+i*2+1);
LCD_WriteData_16Bit(HData<<8|LData);
}
}
將該函式申明新增到lcd.h中:
main.c函式中呼叫該函式,將圖片顯示到LCD
showimage_all(0,0,32768, gImage_world);//或者:showimage(gImage_world);
LCD顯示字串:
//lcd.c
/*************************************************
函式名:Gui_DrawFont_GBK16
功能:顯示一個字串
入口引數:列地址、行地址、字型顏色、背景顏色、要寫入的字串
返回值:無
*************************************************/
void Gui_DrawFont_GBK16(uint16_t x0, uint16_t y0, uint16_t fc, uint16_t bc, uint8_t *s)
{
int i,j,k,x,y,xx;
unsigned char qm;
long int ulOffset;
char ywbuf[32];
// char temp[2];
for(i = 0; i<strlen((char*)s);i++)
{
if(((unsigned char)(*(s+i))) >= 161)
{
// temp[0] = *(s+i);
// temp[1] = '\0';
return;
}
else
{
qm = *(s+i);
ulOffset = (long int)(qm) * 16;
for (j = 0; j < 16; j ++)
{
ywbuf[j]=Zk_ASCII8X16[ulOffset+j];
}
for(y = 0;y < 16;y++)
{
for(x=0;x<8;x++)
{
k=x % 8;
if(ywbuf[y]&(0x80 >> k))
{
xx=x0+x+i*8;
Gui_DrawPoint(xx,y+y0,fc);
}
else
{
xx=x0+x+i*8;
Gui_DrawPoint(xx,y+y0,bc);
}
}
}
}
}
}
TFT液晶屏人機介面開發
開機介面設計:
略:講圖片取模軟體時已經做過。。。
選單介面設計:
lcd中新增如下函式:(注:必須將函式宣告新增到lcd.h中)
void show_ssid(uint8_t *s)//將SSID資料顯示到螢幕上
{
Gui_DrawFont_GBK16(60, 50, BLACK, YELLOW," ");
Gui_DrawFont_GBK16(60, 50, BLACK, YELLOW, s);
}
void show_rx(uint8_t *s)//將RX資料顯示到螢幕上
{
Gui_DrawFont_GBK16(60, 77, BLACK, YELLOW," ");
Gui_DrawFont_GBK16(60, 77, BLACK, YELLOW, s);
}
void show_tx(uint8_t *s)//將TX資料顯示到螢幕上
{
Gui_DrawFont_GBK16(60, 104, BLACK, YELLOW," ");
Gui_DrawFont_GBK16(60, 104, BLACK, YELLOW, s);
}
main.c中新增如下程式碼:
Lcd_Clear_xy(0,0,GREEN);
Lcd_Clear_xy(0,45,YELLOW);
Gui_DrawFont_GBK16(12, 10, RED, GREEN, "LoRa Topology");
Gui_DrawFont_GBK16(40, 26, RED, GREEN, "Master");
Gui_DrawFont_GBK16(12, 50, BLACK, YELLOW, "SSID:");
Gui_DrawFont_GBK16(12, 77, BLACK, YELLOW, "RX:");
Gui_DrawFont_GBK16(12, 104, BLACK, YELLOW, "TX:");
show_ssid("ERROR");
show_rx("ERROR");
show_tx("ERROR");
Lcd_WriteIndex(0x29);//Display on 開啟LCD螢幕顯示
實驗結果:
lcd.c檔案完整程式碼及分析如下:
#include "gpio.h"
#include "stdint.h"
#include "lcd.h"
#include "font_lcd.h"
#include "string.h"
#include "spi.h"
void Delay_ms(int time)
{
int i,j;
for(i=0;i<time*10;i++)
{
for(j=0;j<100;j++)
{
}
}
}
void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
/*Configure GPIO pins : PB4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;//根據原理圖可知該引腳為spi的SIMO引腳
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//將PB4重新設定為推輓輸出模式,之前是SPI模式,現重新設定是為了切換資料和命令模式(使用LCD時)
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//向液晶屏寫一個8位指令
void Lcd_WriteIndex(uint8_t Index)
{
//SPI 寫命令時序開始
//NSS = 0;
LCD_CS_CLR; //將PA15拉低,使能LCD顯示屏
LCD_RS_CLR; //LCD_RS_CLR 將PB4拉低,將LCD設定為寫命令模式
HAL_SPI_Transmit(&hspi1,&Index,1,0xfff);
//NSS = 1;
LCD_CS_SET; //將PA15拉高,關閉LCD顯示屏的SPI
}
//向液晶屏寫一個8位資料
void Lcd_WriteData(uint8_t Data)
{
LCD_CS_CLR; //將PA15拉低,使能LCD顯示屏
LCD_RS_SET; //LCD_RS_CLR 將PB4拉高,將LCD設定為寫資料模式
HAL_SPI_Transmit(&hspi1,&Data,1,0xfff);
LCD_CS_SET; //將PA15拉高,關閉LCD顯示屏的SPI
}
void LCD_WriteData_16Bit(uint16_t Data)
{
uint8_t Data_H = Data>>8;
uint8_t Data_L = Data&0xFF;
LCD_CS_CLR;
LCD_RS_SET;
HAL_SPI_Transmit(&hspi1,&Data_H,1,0xfff); //寫入高8位資料
HAL_SPI_Transmit(&hspi1,&Data_L,1,0xfff); //寫入低8位資料
LCD_CS_SET;
}
//LCD Init For 1.44Inch LCD Panel with ST7735R.
void Lcd_Init(void) //LCD初始化函式
{
LCD_GPIO_Init();//spi的SIMO的初始化
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);//根據原理圖可知:PB6引腳為LCD背光設定引腳,這裡設定為使能背光
Lcd_WriteIndex(0x01);//Sleep 寫命令:軟復位
HAL_Delay(120);//寫命令之後需要延時120ms才能寫下一個命令
Lcd_WriteIndex(0x11);//Sleep exit 退出休眠模式
HAL_Delay(120);
Lcd_WriteIndex(0x36); //開啟0x36暫存器,該暫存器可設定:MX(列掃描), MY(行掃描), RGB mode等
Lcd_WriteData(0xC8); //寫資料,設定0x36暫存器的值
Lcd_WriteIndex(0x3A); //65k mode 顏色深度暫存器
Lcd_WriteData(0x05); //設定顯示顏色的資料位為16位
//Lcd_WriteIndex(0x29);//Display on 開啟LCD螢幕顯示
}
/*************************************************
函式名:LCD_Set_Region
功能:設定lcd顯示區域,在此區域寫點資料自動換行
入口引數:xy起點和終點
返回值:無
*************************************************/
void Lcd_SetRegion(uint16_t x_start,uint16_t y_start,uint16_t x_end,uint16_t y_end)
{
Lcd_WriteIndex(0x2a);
Lcd_WriteData(0x00);
Lcd_WriteData(x_start+2);
Lcd_WriteData(0x00);
Lcd_WriteData(x_end+2);
Lcd_WriteIndex(0x2b);
Lcd_WriteData(0x00);
Lcd_WriteData(y_start+3);
Lcd_WriteData(0x00);
Lcd_WriteData(y_end+3);
Lcd_WriteIndex(0x2c);
}
/*************************************************
函式名:Lcd_Clear
功能:全屏清屏函式
入口引數:填充顏色COLOR
返回值:無
*************************************************/
void Lcd_Clear(uint16_t Color)
{
unsigned int i,m;
Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
Lcd_WriteIndex(0x2C);
for(i=0;i<X_MAX_PIXEL;i++)
for(m=0;m<Y_MAX_PIXEL;m++)
{
LCD_WriteData_16Bit(Color);
}
}
/****************************************************/
void Lcd_Clear_xy(uint16_t x,uint16_t y,uint16_t Color)
{
unsigned int i,m;
Lcd_SetRegion(x,y,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
Lcd_WriteIndex(0x2C);
for(i=x;i<X_MAX_PIXEL;i++)
for(m=y;m<Y_MAX_PIXEL;m++)
{
LCD_WriteData_16Bit(Color);
}
}
/*************************************************
函式名:showimage
功能:顯示一副圖片
入口引數:圖片快取
返回值:無
*************************************************/
//因為一副128*128的圖片需要32768個8位陣列成(陣列元素有32768個),很顯然陣列太大,不能放到記憶體中,只能放在靜態儲存區,所以引數使用 const 修飾
void showimage(const unsigned char *p)
{
unsigned int i;
uint16_t HData,LData;
Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
Lcd_WriteIndex(0x2C);
for(i = 0;i < 128*128;i++)//因為我們已經設定顯示屏顯示範圍為128*128,所以寫滿一行會自動換行,不需單獨寫程式碼
{
LData = *(p+i*2);
HData = *(p+i*2+1);
LCD_WriteData_16Bit(HData<<8|LData);
}
}
/*************************************************
函式名:showimage
功能:任何位置顯示任何圖片(必須在顯示屏顯示的範圍之內)
入口引數:列的起始地址、行的起始地址、陣列的大小、圖片快取
返回值:無
*************************************************/
void showimage_all(uint16_t x,uint16_t y,uint16_t size, const unsigned char *p)
{
unsigned int i;
uint16_t HData,LData;
Lcd_SetRegion(x,y,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
Lcd_WriteIndex(0x2C);
for(i = 0;i < size/2;i++)//因為我們已經設定顯示屏顯示範圍為128*128,所以寫滿一行會自動換行,不需單獨寫程式碼
{
LData = *(p+i*2);
HData = *(p+i*2+1);
LCD_WriteData_16Bit(HData<<8|LData);
}
}
/*************************************************
函式名:LCD_DrawPoint
功能:畫一個點
入口引數:無
返回值:無
*************************************************/
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data)
{
Lcd_SetRegion(x,y,x+1,y+1);
LCD_WriteData_16Bit(Data);
}
/*************************************************
函式名:Gui_DrawFont_GBK16
功能:顯示一個字串
入口引數:列地址、行地址、字型顏色、背景顏色、要寫入的字串
返回值:無
*************************************************/
void Gui_DrawFont_GBK16(uint16_t x0, uint16_t y0, uint16_t fc, uint16_t bc, uint8_t *s)
{
int i,j,k,x,y,xx;
unsigned char qm;
long int ulOffset;
char ywbuf[32];
// char temp[2];
for(i = 0; i<strlen((char*)s);i++)
{
if(((unsigned char)(*(s+i))) >= 161)
{
// temp[0] = *(s+i);
// temp[1] = '\0';
return;
}
else
{
qm = *(s+i);
ulOffset = (long int)(qm) * 16;
for (j = 0; j < 16; j ++)
{
ywbuf[j]=Zk_ASCII8X16[ulOffset+j];
}
for(y = 0;y < 16;y++)
{
for(x=0;x<8;x++)
{
k=x % 8;
if(ywbuf[y]&(0x80 >> k))
{
xx=x0+x+i*8;
Gui_DrawPoint(xx,y+y0,fc);
}
else
{
xx=x0+x+i*8;
Gui_DrawPoint(xx,y+y0,bc);
}
}
}
}
}
}
void show_ssid(uint8_t *s)//將SSID資料顯示到螢幕上
{
Gui_DrawFont_GBK16(60, 50, BLACK, YELLOW," ");
Gui_DrawFont_GBK16(60, 50, BLACK, YELLOW, s);
}
void show_rx(uint8_t *s)//將RX資料顯示到螢幕上
{
Gui_DrawFont_GBK16(60, 77, BLACK, YELLOW," ");
Gui_DrawFont_GBK16(60, 77, BLACK, YELLOW, s);
}
void show_tx(uint8_t *s)//將TX資料顯示到螢幕上
{
Gui_DrawFont_GBK16(60, 104, BLACK, YELLOW," ");
Gui_DrawFont_GBK16(60, 104, BLACK, YELLOW, s);
}
相關推薦
物聯網之LoRa開發與應用三(Lora人機介面開發)
文章要點: 1、TFT液晶屏工作原理 2、TFT液晶屏驅動開發 3、TFT人機介面開發 TFT液晶屏工作原理 內容概要: 1、TFT液晶屏顯示原理 2、1.44寸TFT液晶屏工作原理 3、1.44寸TFT液晶屏硬體設計 TFT液晶屏如何顯示: 顏色深度
物聯網之LoRa開發與應用六(LoRa自組網路設計)
深入瞭解LoRaWAN 內容概要: 1、LoRaWAN概述 2、LoRaWAN終端(重點掌握) 3、LoRaWAN伺服器 LoRaWAN是什麼: LoRaWAN採用星型無線拓撲:End Nodes(節點)、Gateway(閘道器)、Network Server
物聯網之LoRa開發與應用一(M0工程建立)
M0工程建立主要分如下四步: 1、IO埠配置 2、時鐘配置 3、外設配置 4、printf函式重定向 IO配置: 1、看懂原理圖 2、建立IO功能對映表 3、通過STM32Cubemx配置IO工作模式 STM32F051K8U6 IO功能對映表 序號
物聯網之LoRa開發與應用二(驅動移植)
LoRa官方韌體下載:https://pan.baidu.com/s/1ftP-HMJTmF9PtA05Lt-Tag 密碼:bc8y IAR程式碼操作快捷鍵 如果要在整個工程中查詢 某個單詞或者其他,則按照如下方式查詢: LoRa驅動框架 硬體介面設計
深度學習框架tensorflow學習與應用3(非線性迴歸訓練示例)
在瞭解了迴歸演算法中的正向傳播和反向傳播之後, 我們可以用梯度下降法來進行一個非線性迴歸的示例. 此次示例中, 我們設定輸入樣本神經元只有一個, 中間神經元有10個, 輸出神經元1個. &
Java 樹結構實際應用 三(二叉排序樹)
二叉排序樹 1 先看一個需求 給你一個數列 (7, 3, 10, 12, 5, 1, 9),要求能夠高效的完成對資料的查詢和新增 2 解決方案分析 使用陣列 陣列未排序, 優點:直接在陣列尾新增,速度快。 缺點:查詢速度慢. 陣列排序,優點:可以使用二分查詢,查詢速度快,缺點:
物聯網之STM32開發三(USART串列埠)
STM32-USART串列埠的應用 內容概要: 序列通訊的基本概念 串列埠暫存器介紹 STM32實現串列埠資料的收發 HAL串列埠庫函式的使用及printf的實現 序列通訊的基本概念: 內容概要: 通訊的基本概念 USART介紹 串列埠的電路連線 串列埠
物聯網技術在智慧城市應用中的發展趨勢與前景
物聯網技術 人工智能 大數據 無線傳輸 物聯網發展 智慧城市應用的逐步發展,物聯網技術也在深化應用中產生了新的變形,我所在團隊佳都科技是做視頻監控作為智慧城市建設切入點的,隨著視頻結構化技術視頻大數據技術的不斷沈澱,也讓團隊的物聯網技術得到了新的結合發展,在業內提出“視頻物聯網”這一產
Spark筆記整理(三):Spark WC開發與應用部署
大數據 Spark [TOC] Spark WordCount開發 創建的是maven工程,使用的依賴如下: <dependency> <groupId>org.scala-lang</groupId> <artifactId>scal
物聯網之NB-IoT技術實踐開發二(NB-IoT開發環境搭建及模組驅動開發)
STM32CubeMX安裝及使用 1、STM32CubeMX介紹 2、STM32CubeMX安裝 3、STM32CubeMX使用 STM32CubeMX介紹 STM32CubeMX簡介: 微控制器圖形化配置 – 自動處理引腳衝突 – 動態設定確定的時鐘樹
物聯網之STM32開發四(中斷系統)
STM32-中斷系統 內容概要: STM32中斷系統概述 外部中斷控制器EXTI 按鍵中斷例項 串列埠中斷例項 STM32中斷系統概述: 內容概要: 中斷的基本概念 巢狀向量控制器NVIC 中斷及異常向量表 中斷優先順序 中斷的基本概念: 處理器中
物聯網之核心及驅動開發初級五(平臺匯流排開發)
高階驅動--平臺匯流排: Linux裝置驅動模型的由來: 1,實現入口函式 xxx_init()和解除安裝函式 xxx_exit() 2,申請裝置號 register_chrdev (與核心相關) 3,利用udev/mdev機制建立裝置檔案(節點) clas
快消品營銷系統-開發與應用-好處
快消品營銷 營銷系統 不少快消品行業老板都感慨生意越來越難做了,為什麽?產品被假冒、竄貨等原因成了阻礙企業發展的影響因素,為此,贏在移動專門研發了智能營銷系統,助力企業快速實現渠道動銷。 贏在移動智能營銷系統就是高效的營銷工具,它可以幫企業監督竄貨,防偽溯源,快速動銷,收集消費者數據
奶粉導購紅包系統-開發與應用-好處
如今二胎經濟帶火奶粉市場,嬰幼兒奶粉、孕婦奶粉的市場容量非常大,而行業競爭也非常激烈。相對其它行業來講,母嬰門店的導購更能影響消費者的購買。贏在移動提供奶粉導購紅包系統,幫助各大乳企借力導購快速提升奶粉的銷量。 奶粉導購紅包系統讓乳企打破傳統營銷
Docker入門與應用系列(八)Docker圖形界面管理之Shipyard
tps 數據庫 sock blog ocs body mage 代理 cell Shipyard基於Docker API實現的容器圖形管理系統,支持container、images、engine、cluster等功能,可滿足我們基本的容器部署需求可堆棧的Docker管理基於
Docker入門與應用系列(七)Docker圖形界面管理之DockerUI
post 簡單的 技術分享 name mage src 入門 .com 系統 1.dockeruiDockerrUI是一個基於Docker API提供圖形化頁面簡單的容器管理系統,支持容器管理、鏡像管理。1.1 下載鏡像 docker pull abh1nav/doc
《Qt5 開發與實例(第三版)》學習筆記(七)
clu idg center ble mil detached pre tab etc 1 // 3.2 停靠窗口 QDockWidget類 2 setFeatures() 3 setAllowedAreas() 4 setWidget() 5 addDockW
《Qt5 開發與實例(第三版)》學習筆記(九)
nal inf lin exc ken right item vbo ott 1 // 3.4 基本布局(QLayout) 2 //dialog.h 3 #ifndef DIALOG_H 4 #define DIALOG_H 5 6 #incl
《Qt5 開發與實例(第三版)》學習筆記(八)
nbsp font public insert enter body win parent hbox 1 // 3.3 堆棧窗體 QStackedWidget類 2 //stackdlg.h 3 #ifndef STACKDLG_H 4 #define STACK
《Qt5 開發與實例(第三版)》學習筆記(十)
fix row tac person als new .cpp exec constrain 1 // 3.5 『綜合實例』 修改用戶資料 2 //main.cpp 3 #include "content.h" 4 #include <QApplic