SPI3+DMA外设驱动-TFTLCD初始化

news2024/11/24 8:53:23

前言

(1)本系列是基于STM32的项目笔记,内容涵盖了STM32各种外设的使用,由浅入深。

(2)小编使用的单片机是STM32F105RCT6,项目笔记基于小编的实际项目,但是博客中的内容适用于各种单片机开发的同学学习和使用。

学习目标

本章有五个任务:

  1. 了解关于TFTLCD液晶屏的硬件接口
  2. 学习和了解STM32 DMA驱动
  3. TFTLCD液晶屏的硬件接口初始化
  4. LCD液晶初始化
  5. TFTLCD液晶屏代码移植和显示测试

TFTLCD液晶屏硬件电路分析

接口说明:TFTLCD液晶屏是连接到了单片机的SPI3接口。

TFTDIO ---- PB5 SPI3-MOSI 数据发送管脚 SPI硬件控制

TFTCMD---- PB4 SPI3-MISO 数据/指令控制脚

TFTCLK ----- PB3 SPI3-SCK 数据发送时钟脚 SPI硬件控制

CS ------PB6 片选脚位

LEDA_EN— PC10 LCD屏背光控制脚

FTFRES — PA15 LCD复位脚

电路设计说明:

● 硬件电路设计是参考液晶屏官方给的参考资料设计的。基本是按照芯片资料照抄过来即可

● 为了提高液晶屏的刷屏效率,我们选择了SPI3接口。采用单线模式

● DIO CLK 必须固定连接 MOSI SCK ,其他管脚可以连任意IO口

TFTLCD液晶屏初始化

hal_tftlcd.c 代码

#include "hal_tftlcd.h"
#include "stm32F10x.h"
//#include "lcd_font.h"

//-----------------LCD端口定义---------------- 
#define LCD_SCLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_3)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_3)

#define LCD_MOSI_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_5)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(GPIOB,GPIO_Pin_5)

#define LCD_DC_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_4)//DC
#define LCD_DC_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_4)

#define LCD_CS_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
#define LCD_CS_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)

#define LCD_RES_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_15)//RES
#define LCD_RES_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_15)

#define LCD_BLK_Clr()  GPIO_ResetBits(GPIOC,GPIO_Pin_10)//BLK
#define LCD_BLK_Set()  GPIO_SetBits(GPIOC,GPIO_Pin_10)



void hal_tftlcdConfig(void)
{
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	DMA_InitTypeDef  DMA_InitStructure;//DMA初始化结构体

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);  //相关IO的初始化
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	//RES-PA15
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOA, &GPIO_InitStructure);	  //初始化GPIOA
	GPIO_SetBits(GPIOA,GPIO_Pin_15);
	
	//CMD-PB4
	//CS-PB6
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOA	
	GPIO_SetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_6);
	
		//BLK-PC10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOC, &GPIO_InitStructure);	  //初始化GPIOA		
	GPIO_ResetBits(GPIOC,GPIO_Pin_10);
	
	//CLK-PB3
	//MOSI-PB5
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 |GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
	
	/* SPI3 configuration */ 
	SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI1设置为单线
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	                     //设置SPI1为主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  //SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;	 		                   //串行时钟在不操作时,时钟为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;		                   //第二个时钟沿开始采样数据
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;			                     //NSS信号由软件(使用SSI位)管理
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //定义波特率预分频的值:波特率预分频值为8
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				         //数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;						               //CRC值计算的多项式
	SPI_Init(SPI3, &SPI_InitStructure);

	//使能DMA发送
	DMA_DeInit(DMA2_Channel2); 
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR; //数据传输目标地址
																															//数据缓存地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 	//外设作为数据传输的目的地
	DMA_InitStructure.DMA_BufferSize = 1024;            //发送Buff数据大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置外设地址是否递增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;          //设置内存地址是否递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;       	//内存数据宽度为8位	

	DMA_InitStructure.DMA_Mode =   DMA_Mode_Normal;                              //普通缓存模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                        //高优先级
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                 //禁止DMA2个内存相互访问
	DMA_Init(DMA2_Channel2, &DMA_InitStructure);                                 //初始化DMA,SPI在DMA1的通道2

	SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE);                               /使能SPI2 DMA发送功能*/	
	SPI_Cmd(SPI3, ENABLE);//使能SPI2
}

// SPI3 DMA发送
void DMA_SPI3_TX(unsigned char *buffer,unsigned short len)
{
	DMA2->IFCR |=(0xf<<4);    //清除通道2上面所有的标志位
	DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
	DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
	DMA2_Channel2->CCR|=0x1;   ///启动DMA
        while(!(DMA2->ISR&(1<<5)));///等待数据数据传输完成
	DMA2_Channel2->CCR &=(uint32_t)~0x1;//关闭DMA
}

void LCD_Writ_Bus(unsigned char dat) 
{	
	LCD_CS_Clr();
	DMA_SPI3_TX(&dat,1);
}

/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(unsigned char dat)
{
	LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(unsigned short dat)
{
	unsigned char d[2];
	d[0] = dat>>8;
	d[1] = dat;
	DMA_SPI3_TX(&d[0],2);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(unsigned char dat)
{
	LCD_DC_Clr();//写命令
	LCD_Writ_Bus(dat);
	LCD_DC_Set();//写数据
}

void hal_Oled_Display_on(void)
{
	LCD_BLK_Set();
}

void hal_Oled_Display_off(void)
{
	LCD_BLK_Clr();
}
///

void hal_oled_RestH(void)
{
	LCD_RES_Set();
}
void hal_oled_RestL(void)
{
	LCD_RES_Clr();
}

hal_tftlcd.h 代码

#ifndef ____HAL_TFTLCD_H_
#define ____HAL_TFTLCD_H_

void hal_tftlcdConfig(void);

void LCD_WR_REG(unsigned char dat);
void LCD_WR_DATA8(unsigned char dat);
void LCD_WR_DATA(unsigned short dat);
void DMA_SPI3_TX(unsigned char *buffer,unsigned short len);

void hal_Oled_Display_on(void);
void hal_Oled_Display_off(void);
void hal_oled_RestH(void);
void hal_oled_RestL(void);
#endif

代码分析

hal_tftlcd.c 包括

● TFTLCD液晶屏通讯接口初始化

● TFTLCD通过DMA数据发送函数

● TFTLCD液晶屏其他端口控制函数

TFTLCD SP3接口初始化流程

➢ 定义TFTLCD通讯的接口

//-----------------LCD端口定义---------------- 
#define LCD_SCLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_3)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_3)

#define LCD_MOSI_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_5)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(GPIOB,GPIO_Pin_5)

#define LCD_DC_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_4)//DC
#define LCD_DC_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_4)

#define LCD_CS_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
#define LCD_CS_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)

#define LCD_RES_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_15)//RES
#define LCD_RES_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_15)

#define LCD_BLK_Clr()  GPIO_ResetBits(GPIOC,GPIO_Pin_10)//BLK
#define LCD_BLK_Set()  GPIO_SetBits(GPIOC,GPIO_Pin_10)

➢ 打开相关时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);  //相关IO的初始化

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//打开端口重映射,PB3、PB4端口默认的功能不是SPI3,是JTAG,所以要对端口重映射,让它们具备SPI3的功能

➢ 初始化TFTLCD 液晶屏 和SPI3相关的GPIO口

	//CMD-PB4
	//CS-PB6
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOA	
	GPIO_SetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_6);
	
		//BLK-PC10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOC, &GPIO_InitStructure);	  //初始化GPIOA		
	GPIO_ResetBits(GPIOC,GPIO_Pin_10);
	
	//CLK-PB3
	//MOSI-PB5
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 |GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	

➢ 初始化SPI3相关参数

/* SPI3 configuration */ 
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI1设置为单线
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	                     //设置SPI1为主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  //SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;	  //串行时钟在不操作时,时钟为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;		 //第二个时钟沿开始采样数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	 //NSS信号由软件(使用SSI位)管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //定义波特率预分频的值:波特率预分频值为8
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;			 //CRC值计算的多项式
SPI_Init(SPI3, &SPI_InitStructure);

➢ 配置SPI3 DMA功能。

DMA介绍:

直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。

总之,当我们的功能中涉及数据传输功能时,例如ADC、DMA、USART等,为了使数据传输更快,可以在数据传输中加上DMA功能,使能DMA发送或接收。

DMA1 各个通道对应表:

DMA2 各个通道对应表:

我们项目用到是DMA2的发送功能,因为我们只需要对TFTLCD显示屏发送数据。

//使能DMA发送
DMA_DeInit(DMA2_Channel2); 
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR; //数据传输目标地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 	数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = 1024;            //发送Buff数据大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置外设地址是否递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //设置内存地址是否递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据宽度为8位	

DMA_InitStructure.DMA_Mode =   DMA_Mode_Normal;                         //普通缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                        //高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;            //禁止DMA2个内存相互访问
DMA_Init(DMA2_Channel2, &DMA_InitStructure);        //初始化DMA,SPI在DMA1的通道2

SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE); /使能SPI2 DMA发送功能*/	
SPI_Cmd(SPI3, ENABLE);//使能SPI2

SPI3 DMA 数据发送函数
// SPI3 DMA发送
void DMA_SPI3_TX(unsigned char *buffer,unsigned short len)
{
	DMA2->IFCR |=(0xf<<4);    //清除通道2上面所有的标志位
	DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
	DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
	DMA2_Channel2->CCR|=0x1;   ///启动DMA
        while(!(DMA2->ISR&(1<<5))) ; ///等待数据数据传输完成
	DMA2_Channel2->CCR &=(uint32_t)~0x1;//关闭DMA
}
void LCD_Writ_Bus(unsigned char dat) 
{	
	LCD_CS_Clr();
	DMA_SPI3_TX(&dat,1);
}

其他LCD脚位控制函数
void hal_Oled_Display_on(void)
{
	LCD_BLK_Set();
}

void hal_Oled_Display_off(void)
{
	LCD_BLK_Clr();
}

void hal_oled_RestH(void)
{
	LCD_RES_Set();
}
void hal_oled_RestL(void)
{
	LCD_RES_Clr();
}

LCD指令和数据发送函数
/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(unsigned char dat)
{
	DMA_SPI3_TX(dat);
}

/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(unsigned short dat)
{
	unsigned char d[2];
	d[0] = dat>>8;
	d[1] = dat;
	DMA_SPI3_TX(&d[0],2);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(unsigned char dat)
{
	LCD_DC_Clr();//写命令
	LCD_Writ_Bus(dat);
	LCD_DC_Set();//写数据
}

以上内容都是hal_tftlcd.c 和hal_tftlcd.h文件内容,都是有关于stm32外设 DMA SPI3 的初始化的函数.

以下内容将会是mt_tftlcd.c 和mt_tftlcd.h文件内容,都是有关于模块 LCD屏幕 的初始化内容,LCD屏幕模块的初始化都是基于stm32外设初始化的函数写的,所以模块的初始化函数都是调用外设初始化函数组合而成的,底层就是stm32外设的初始化函数,模块的初始化函数和代码,相对来说是应用层代码。所以,mt文件中是应用层驱动代码,hal文件中是底层驱动代码。

LCD屏幕初始化和LCD填充函数

LCD驱动和LCD相关其他驱动函数,我们直接从官方参考的例程移植过来使用即可,不需要自己深入的研究。

void mt_tftlcd_init(void);

LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color);

注意:不论是底层驱动代码还是应用层驱动代码,都是基于配置STM32寄存器写的程序,不要求深入研究,会调用即可;应用层驱动程序是基于底层驱动程序编程的。

mt_tftlcd.c代码

#include "mt_Tftlcd.h"
#include "hal_tftlcd.h"

static void hal_tftlcd_Delay(unsigned int de);
unsigned char ColorBuf[640];

void mt_tftlcd_init(void)
{
  		hal_tftlcdConfig();//初始化GPIO
		hal_tftlcd_Delay(10000);
		hal_oled_RestL();//复位
		hal_tftlcd_Delay(10000);
		hal_oled_RestH();
		hal_tftlcd_Delay(100);

	//************* Start Initial Sequence **********//
		LCD_WR_REG(0x11);
		hal_tftlcd_Delay(10000);//delay_ms(100); //Delay 120ms
		LCD_WR_REG(0X36);// Memory Access Control
		if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
		else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
		else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
		else LCD_WR_DATA8(0xA0);
		LCD_WR_REG(0X3A);
	 // LCD_WR_DATA8(0X03);   //12bit
		LCD_WR_DATA8(0X05);  
		//--------------------------------ST7789S Frame rate setting-------------------------

		LCD_WR_REG(0xb2);
		LCD_WR_DATA8(0x0c);
		LCD_WR_DATA8(0x0c);
		LCD_WR_DATA8(0x00);
		LCD_WR_DATA8(0x33);
		LCD_WR_DATA8(0x33);

		LCD_WR_REG(0xb7);
		LCD_WR_DATA8(0x35);
		//---------------------------------ST7789S Power setting-----------------------------

		LCD_WR_REG(0xbb);
		LCD_WR_DATA8(0x35);

		LCD_WR_REG(0xc0);
		LCD_WR_DATA8(0x2c);

		LCD_WR_REG(0xc2);
		LCD_WR_DATA8(0x01);

		LCD_WR_REG(0xc3);
		LCD_WR_DATA8(0x13);

		LCD_WR_REG(0xc4);
		LCD_WR_DATA8(0x20);

		LCD_WR_REG(0xc6);
		LCD_WR_DATA8(0x0f);

		LCD_WR_REG(0xca);
		LCD_WR_DATA8(0x0f);

		LCD_WR_REG(0xc8);
		LCD_WR_DATA8(0x08);

		LCD_WR_REG(0x55);
		LCD_WR_DATA8(0x90);

		LCD_WR_REG(0xd0);
		LCD_WR_DATA8(0xa4);
		LCD_WR_DATA8(0xa1);
		//--------------------------------ST7789S gamma setting------------------------------
		LCD_WR_REG(0xe0);
		LCD_WR_DATA8(0xd0);
		LCD_WR_DATA8(0x00);
		LCD_WR_DATA8(0x06);
		LCD_WR_DATA8(0x09);
		LCD_WR_DATA8(0x0b);
		LCD_WR_DATA8(0x2a);
		LCD_WR_DATA8(0x3c);
		LCD_WR_DATA8(0x55);
		LCD_WR_DATA8(0x4b);
		LCD_WR_DATA8(0x08);
		LCD_WR_DATA8(0x16);
		LCD_WR_DATA8(0x14);
		LCD_WR_DATA8(0x19);
		LCD_WR_DATA8(0x20);
		LCD_WR_REG(0xe1);
		LCD_WR_DATA8(0xd0);
		LCD_WR_DATA8(0x00);
		LCD_WR_DATA8(0x06);
		LCD_WR_DATA8(0x09);
		LCD_WR_DATA8(0x0b);
		LCD_WR_DATA8(0x29);
		LCD_WR_DATA8(0x36);
		LCD_WR_DATA8(0x54);
		LCD_WR_DATA8(0x4b);
		LCD_WR_DATA8(0x0d);
		LCD_WR_DATA8(0x16);
		LCD_WR_DATA8(0x14);
		LCD_WR_DATA8(0x21);
		LCD_WR_DATA8(0x20);
		LCD_WR_REG(0x29);
		hal_Oled_Display_on();//打开背光

		LCD_Fill(0,0,LCD_W,LCD_H,RED);
} 

/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:  无
******************************************************************************/
void LCD_Address_Set(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2)
{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1+2);
		LCD_WR_DATA(x2+2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1+1);
		LCD_WR_DATA(y2+1);
		LCD_WR_REG(0x2c);//储存器写
}

static void hal_tftlcd_Delay(unsigned int de)
{
	while(de--);
}

void LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color)
{          
	unsigned short i; 
	LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
	for(i=0;i<xend;i++)
  {
		ColorBuf[i++] = color>>8;
		ColorBuf[i] = color;
	}
	for(i=ysta;i<yend*2;i++)
	{		
		 DMA_SPI3_TX(ColorBuf,xend);
	}	
}

mt_Tftlcd.h代码

#ifndef ____MT_TFTLCD_H_
#define ____MT_TFTLCD_H_

#define USE_HORIZONTAL 3  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏

#if USE_HORIZONTAL==0||USE_HORIZONTAL==1

#define LCD_W 240
#define LCD_H 320

#else
#define LCD_W 320
#define LCD_H 240
#endif

///RGB565
#define WHITE         	 0xFFFF
#define BLACK         	 0x0000	  
#define BLUE           	 0x001F  
#define BRED                  0XF81F
#define GRED 		 0XFFE0
#define GBLUE	         0X07FF
#define RED           	         0xF800
#define MAGENTA       	 0xF81F
#define GREEN         	 0x07E0
#define CYAN          	 0x7FFF
#define YELLOW        	 0xFFE0
#define BROWN 			     0XBC40 //棕色
#define BRRED 			     0XFC07 //棕红色
#define GRAY  			     0X8430 //灰色
#define DARKBLUE      	 0X01CF	//深蓝色
#define LIGHTBLUE      	 0X7D7C	//浅蓝色  
#define GRAYBLUE       	 0X5458 //灰蓝色
#define LIGHTGREEN     	 0X841F //浅绿色
#define LGRAY 			     0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)

enum
{
	FORTSIZE_12 = 12,
	FORTSIZE_16 = 16,	
	FORTSIZE_24 = 24,
	FORTSIZE_32 = 32,	
	FORTSIZE_48 = 48,	
};

#define HUE_LCD_FONT     WHITE
#define HUE_LCD_BACK     BLACK//YELLOW  //BLACK//
#define HUE_FONT_BACK    GRAY

void mt_tftlcd_init(void);
void LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color);
#endif

功能测试验证

LCD屏幕全屏显示黄色,表示驱动完成OK。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法leetcode|74. 搜索二维矩阵(rust重拳出击)

文章目录 74. 搜索二维矩阵&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 74. 搜索二维矩阵&#xff1a; 给你一个满足下述两条属性的…

新手将最简单的springboot部署上tomcat出现的意外问题

现阶段springboot部署到tomcat的文章一抓一大把且都相同,便贴一个地址以展示流程: SpringBoot打war包部署Tomcat(最全)_spring boot war 部署tomcat_聊Java的博客-CSDN博客 那么就说一下我出现的问题: 在完整复现流程且确认代码无误的情况下,部署到tomcat,此时问题出现了:启动…

vue中html引入使用<%= BASE_URL %>变量

首先使用src相对路径引入 注意&#xff1a; js 文件放在public文件下 不要放在assets静态资源文件下 否则 可能会报错 GET http://192.168.0.113:8080/src/assets/js/websockets.js net::ERR_ABORTED 500 (Internal Server Error) 正确使用如下&#xff1a;eg // html中引…

Midjourney学习(二)参数的基础

prompt的组成 prompt 可以由三部分组成&#xff0c; 第一部分是垫图部分&#xff0c;也就是一张网络图片 第二部分是文本描述内容 第三部分则是参数 参数列表 --aspect <value> 或者 --ar <value> 控制画面的比例&#xff0c;横竖比例 --version <value> -…

复数的四则运算(java版)

复数的四则运算&#xff08;java版&#xff09; 目录 复数的四则运算&#xff08;java版&#xff09;介绍复数的四则运算实现思路代码1、封装复数类2、测试复数类3、代码测试结果 介绍 复数&#xff0c;为实数的延伸&#xff0c;它使任一多项式方程都有根。复数当中有个“虚数单…

攻击与防御实战经验分享:分析真实的攻击事件和入侵行为,讨论防御方法和实践经验

章节 1: 前言 作为IT领域的从业者&#xff0c;我们时刻都面临着网络安全的挑战。攻击者不断寻找漏洞&#xff0c;而防御者则需要时刻保持警惕&#xff0c;采取最佳实践来保护系统和数据。在本文中&#xff0c;我们将分享一些真实的攻击事件和入侵行为&#xff0c;并探讨针对这…

JVM 垃圾收集

垃圾收集 分代理论Java 堆的内存分区不同分代收集垃圾收集算法 分代理论 弱分代假说&#xff1a;绝大多数对象都是朝生夕灭&#xff0c;即绝大多数对象都是用完很快需要销毁的。强分代假说&#xff1a;熬过多次垃圾收集过程的对象就越难以消亡&#xff0c;即如果对象经过多次垃…

6. vue-element-admin 二次开发避坑指南

vue-element-admin 二次开发避坑指南 1.1 前言1.1.1 切换标签时未保存页面的操作内容1.1.2 markdown 样式乱码1.1.3 修改默认尺寸1.1.4 当后端服务器宕机情况下页面加载层一直转圈无法停止&#xff0c;只能关闭页面1.1.5 隐藏齿轮 1.1 前言 上一篇博文&#xff0c;我们分享了vu…

HarmonyOS Codelab 优秀样例——购物应用,体验一次开发多端部署魅力

一. 样例介绍 本篇Codelab基于自适应布局和响应式布局&#xff0c;实现购物应用在手机、折叠屏、平板不同屏幕尺寸设备上按不同设计显示。通过三层工程结构组织代码&#xff0c;实现一次开发&#xff0c;多端部署 。 手机运行效果如图所示&#xff1a; 折叠屏运行效果图&#x…

Thymeleaf解析表达式

首先springThymeleaf必过的点 org.springframework.web.servlet.DispatcherServlet#doDispatch那么先跟入handle()方法 然后跟进handleInternal方法 可以看到mav的获取方法&#xff0c;继续跟进invokeHandlerMethod 继续跟进invokeAndHandle 这里判断returnvalue是否有值…

智能工厂移动式作业轻薄加固三防平板数据采集终端

在这个高度自动化和数字化的环境中&#xff0c;数据采集变得尤为重要。为了满足这个需求&#xff0c;工业三防平板数据采集终端应运而生。工业三防平板数据采集终端采用了轻量级高强度镁合金材质&#xff0c;这使得它在保持轻薄的同时具有更强的坚固性。这种材质还具有耐磨防损…

XML—DTD、 Schema

目录 DTD是什么&#xff1f; DTD有什么用途&#xff1f; DTD与XML有什么联系&#xff1f; DTD原理图 外部DTD DTD文件book.dtd: 使用外部DTD文件的XML文件 PCDATA XML 文档构建模块 一、元素 1、元素声明 ①、有元素&#xff1a; ②、空元素&#xff1a; ③、ANY…

Kubernetes(K8s 1.28.x)部署---超详细

目录 一、基础环境配置&#xff08;所有主机均要配置&#xff09; 1、配置IP地址和主机名、hosts解析 2、关闭防火墙、禁用SELinux 3、安装常用软件 4、配置时间同步 5、禁用Swap分区 6、修改linux的内核参数 7、配置ipvs功能 二、容器环境操作 1、定制软件源 2、安…

MySQL select语句的执行流程

MYSQL基础架构 连接器查询缓存分析器优化器执行器存储引擎 比如说&#xff0c;我们经常能够在mysql的查询语句中看到如下的查询语句&#xff1a; mysql> select * from T where ID10&#xff1b;在了解它在mysql中的执行流程之前&#xff0c;首先我们来看一下mysql中的基本…

Qt之进程通信-IPC(QLocalServer,QLocalSocket 含源码+注释)

文章目录 一、IPC通信示例图1.1 设置关键字并连接的示例图1.2 进程间简单的数据通信示例图1.3 断开连接的示例图1.3.1 由Server主动断开连接1.3.2 由Socket主动断开连接 1.4 Server停止监听后的效果二、个人理解与一些心得三、一些疑问&#xff08;求教 家人们&#x1f602;&am…

VueRouter的基本使用

路由的基本使用 文章目录 路由的基本使用01-VueRouterVueRouter的使用 &#xff08; 5 2&#xff09;综合代码 拓展&#xff1a;组件存放问题 什么是路由呢&#xff1f; 在生活中的路由&#xff1a;设备和IP的映射关系 在Vue中&#xff1a;路径 和 组件 的 映射 关系。 01-Vu…

与面试官互动:建立积极的技术讨论氛围

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

OpenCV简介

OpenCV简介 OpenCV&#xff08;开源计算机视觉库&#xff1a;http://opencv.org&#xff09;是一个开源库&#xff0c;包含数百种计算机视觉算法。OpenCV 具有模块化结构&#xff0c;主要包括下列模块&#xff1a; 核心功能&#xff08;core&#xff09; - 定义基本数据结构的…

3、监测数据采集物联网应用开发步骤(3)

监测数据采集物联网应用开发步骤(2) 系统整体结构搭建 新建项目 输入项目名称&#xff1a;MonitorData 所谓兵马未动粮草先行&#xff0c;按下图创建好对应的模块备用&#xff1a; com.plugins 业务插件模块 com.zxy.adminlog 日志或文本文…

【从零开始学习JAVA | 第四十六篇】处理请求参数

前言&#xff1a; 在我们之前的学习中&#xff0c;我们已经基本学习完了JAVA的基础内容&#xff0c;从今天开始我们就逐渐进入到JAVA的时间&#xff0c;在这一大篇章&#xff0c;我们将对前后端有一个基本的认识&#xff0c;并要学习如何成为一名合格的后端工程师。今天我们介绍…