计算机视觉技术 Zookeeper使用 人脸识别 vbscript playframework clojure triggers pagination GMU vue特点 less官网 matlab停止运行命令 hbase端口 js对象添加元素 oracle增加主键 python中文 java的包 java时间戳转换 qtp下载 图片链接生成器 枪神传说辅助 数科阅读器 字符串分割成数组 spss20安装教程 论文修改软件 cdr怎么画波浪线 看图软件cad rpm卸载命令 txplatform edquota 氤氲之息哪里爆率高 谷歌地球怎么用不了 ps蒙版抠图 xfce4 win10工作组 微博实名认证 java下载文件 360街机三国 黑市商人在哪 直播源
当前位置: 首页 > 学习教程  > 

物联网之LoRa开发与应用三(Lora人机界面开发)

2020/10/16 17:46:09 文章标签: lora开发

文章要点: 1、TFT液晶屏工作原理 2、TFT液晶屏驱动开发 3、TFT人机界面开发 TFT液晶屏工作原理 内容概要: 1、TFT液晶屏显示原理 2、1.44寸TFT液晶屏工作原理 3、1.44寸TFT液晶屏硬件设计 TFT液晶屏如何显示: 颜色深度: …

文章要点:

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);
}

 


本文链接: http://www.dtmao.cc/news_show_300108.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?