1. 程式人生 > >物聯網之LoRa開發與應用三(Lora人機介面開發)

物聯網之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