今天把0.96寸的ST7735的LCD从新唐的M030TD2AE移到STM32F103C8T6上用,驱动文件直接复制过来,屏幕死活显示不了。
搞了好久,最后能显示了,但还是不明白为什么,想不通,记录一下。以后明白了再回来修改
问题:LCD无显示,驱动在新唐单片机测试过没问题可以使用
解决方法:GPIO初始化的时候将SCL拉高,下面代码中的LCD_GPIO_Init函数中(不明白为什么)
代码:Lcd_Driver.h
#ifndef __LCD_DRIVER_H__
#define __LCD_DRIVER_H__
#include "stm32f10x.h"
#include "GPIOLIKE51.h"
//类型定义
#define u8 unsigned char
#define u16 unsigned short
#define uint8_t unsigned char
#define uint16_t unsigned short
//屏幕分辨率
#define X_MAX_PIXEL 160
#define Y_MAX_PIXEL 80
//引脚定义
#define LCD_SCL PAout(8) //PB13--->>TFT --SCL/SCK
#define LCD_SDA PAout(9) //PB15 MOSI--->>TFT --SDA/DIN
#define LCD_CS PAout(12) //PB10--->>TFT --RST
#define LCD_DC PAout(11) //PB11--->>TFT --RS/DC
#define LCD_RST PAout(10) //PB10--->>TFT --RST
#define LCD_BL PAout(15) //PB10--->>TFT --BL
//液晶控制口置1操作语句宏定义
#define LCD_SCL_SET LCD_SCL = 1
#define LCD_SDA_SET LCD_SDA = 1
#define LCD_CS_SET LCD_CS = 1
#define LCD_DC_SET LCD_DC = 1
#define LCD_RST_SET LCD_RST = 1
#define LCD_BL_SET LCD_BL = 1
//液晶控制口置0操作语句宏定义
#define LCD_SCL_CLR LCD_SCL = 0
#define LCD_SDA_CLR LCD_SDA = 0
#define LCD_CS_CLR LCD_CS = 0
#define LCD_DC_CLR LCD_DC = 0
#define LCD_RST_CLR LCD_RST = 0
#define LCD_BL_CLR LCD_BL = 0
//颜色值
#define BLACK 0x0000
#define WHITE 0xffff
#define GRAY50 0x8430 //灰色50%
#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define YELLOW 0xFFE0
//函数声明
extern void LCD_GPIO_Init(void);
extern void Lcd_WriteIndex(u8 Index);
extern void Lcd_WriteData(u8 Data);
extern void Lcd_WriteReg(u8 Index,u8 Data);
extern u16 Lcd_ReadReg(u8 LCD_Reg);
extern void Lcd_Reset(void);
extern void Lcd_Init(void);
extern void Lcd_Clear(u16 Color);
extern void Lcd_SetXY(u16 x,u16 y);
extern void Gui_DrawPoint(u16 x,u16 y,u16 Data);
extern unsigned int Lcd_ReadPoint(u16 x,u16 y);
extern void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end);
extern void LCD_WriteData_16Bit(u16 Data);
extern void f_Lcd_ShowBmp_ColorValue(const uint8_t * pbmp, uint8_t x0, uint8_t y0, uint8_t x_Len, uint8_t y_Len);
extern void f_Lcd_ClearBlock(uint16_t Color, uint8_t x0, uint8_t y0, uint8_t x_Len, uint8_t y_Len); //清除区块
#endif
头文件:Lcd_Driver.c
#include "Lcd_Driver.h"
void DelayMs(uint32_t cnt) {
u16 i=0;
while(cnt--)
{
i=12000; //自己定义
while(i--) ;
}
}
//液晶IO初始化配置
void LCD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
LCD_CS_CLR;
LCD_BL_CLR;
LCD_SCL_SET; //这里没拉高无法显示
}
//向SPI总线传输一个8位数据
void SPI_WriteData(u8 Data)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
if(Data&0x80)
LCD_SDA_SET; //输出数据
else LCD_SDA_CLR;
LCD_SCL_CLR;
LCD_SCL_SET;
Data<<=1;
}
}
//向液晶屏写一个8位指令
void Lcd_WriteIndex(u8 Index)
{
//SPI 写命令时序开始
LCD_DC_CLR;
SPI_WriteData(Index);
}
//向液晶屏写一个8位数据
void Lcd_WriteData(u8 Data)
{
LCD_DC_SET;
SPI_WriteData(Data);
}
void delay(void)
{
uint8_t count =0;
for(count =0;count<50;count++);
}
//向液晶屏写一个16位数据
void LCD_WriteData_16Bit(u16 Data)
{
unsigned char i = 0;
LCD_DC_SET;
for(i = 0; i < 16; i++)
{
LCD_SCL_CLR;
if(Data & 0x8000)
{LCD_SDA_SET;}
else {LCD_SDA_CLR;}
Data <<= 1;
LCD_SCL_SET;
}
}
void Lcd_WriteReg(u8 Index,u8 Data)
{
Lcd_WriteIndex(Index);
Lcd_WriteData(Data);
}
void Lcd_Reset(void)
{
LCD_RST_SET;
DelayMs(50);
LCD_RST_CLR;
DelayMs(100);
LCD_RST_SET;
DelayMs(50);
}
//LCD Init For 1.44Inch LCD Panel with ST7735R.
void Lcd_Init(void)
{
LCD_GPIO_Init();
Lcd_Reset(); //Reset before LCD Init.
Lcd_WriteIndex(0x11); //Sleep exit
DelayMs (120);
// Lcd_WriteIndex(0x20); //0x20:反色关; 0x21:反色开
Lcd_WriteIndex(0x21);
Lcd_WriteIndex(0xB1);
Lcd_WriteData(0x05);
Lcd_WriteData(0x3A);
Lcd_WriteData(0x3A);
Lcd_WriteIndex(0xB2);
Lcd_WriteData(0x05);
Lcd_WriteData(0x3A);
Lcd_WriteData(0x3A);
Lcd_WriteIndex(0xB3);
Lcd_WriteData(0x05);
Lcd_WriteData(0x3A);
Lcd_WriteData(0x3A);
Lcd_WriteData(0x05);
Lcd_WriteData(0x3A);
Lcd_WriteData(0x3A);
Lcd_WriteIndex(0xB4);
Lcd_WriteData(0x03);
Lcd_WriteIndex(0xC0);
Lcd_WriteData(0x62);
Lcd_WriteData(0x02);
Lcd_WriteData(0x04);
Lcd_WriteIndex(0xC1);
Lcd_WriteData(0xC0);
Lcd_WriteIndex(0xC2);
Lcd_WriteData(0x0D);
Lcd_WriteData(0x00);
Lcd_WriteIndex(0xC3);
Lcd_WriteData(0x8D);
Lcd_WriteData(0x6A);
Lcd_WriteIndex(0xC4);
Lcd_WriteData(0x8D);
Lcd_WriteData(0xEE);
Lcd_WriteIndex(0xC5); /*VCOM*/
Lcd_WriteData(0x0E);
Lcd_WriteIndex(0xE0);
Lcd_WriteData(0x10);
Lcd_WriteData(0x0E);
Lcd_WriteData(0x02);
Lcd_WriteData(0x03);
Lcd_WriteData(0x0E);
Lcd_WriteData(0x07);
Lcd_WriteData(0x02);
Lcd_WriteData(0x07);
Lcd_WriteData(0x0A);
Lcd_WriteData(0x12);
Lcd_WriteData(0x27);
Lcd_WriteData(0x37);
Lcd_WriteData(0x00);
Lcd_WriteData(0x0D);
Lcd_WriteData(0x0E);
Lcd_WriteData(0x10);
Lcd_WriteIndex(0xE1);
Lcd_WriteData(0x10);
Lcd_WriteData(0x0E);
Lcd_WriteData(0x03);
Lcd_WriteData(0x03);
Lcd_WriteData(0x0F);
Lcd_WriteData(0x06);
Lcd_WriteData(0x02);
Lcd_WriteData(0x08);
Lcd_WriteData(0x0A);
Lcd_WriteData(0x13);
Lcd_WriteData(0x26);
Lcd_WriteData(0x36);
Lcd_WriteData(0x00);
Lcd_WriteData(0x0D);
Lcd_WriteData(0x0E);
Lcd_WriteData(0x10);
Lcd_WriteIndex(0x3A); //颜色格式 16bit
Lcd_WriteData(0x05);
Lcd_WriteIndex(0x36);
Lcd_WriteData(0xA8); //BGR格式 0xA0:RGB格式
Lcd_WriteIndex(0x28); //Display OFF
Lcd_Clear(BLACK);
LCD_BL_SET;
Lcd_WriteIndex(0x29); //Display On
}
/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点
返回值:无
*************************************************/
void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end)
{
//根据屏幕调节偏移量
// Lcd_WriteIndex(0x2a);
// Lcd_WriteData(0x00);
// Lcd_WriteData(x_start);
// Lcd_WriteData(0x00);
// Lcd_WriteData(x_end);
Lcd_WriteIndex(0x2a);
Lcd_WriteData(0x00);
Lcd_WriteData(x_start+1);
Lcd_WriteData(0x00);
Lcd_WriteData(x_end+1);
// Lcd_WriteIndex(0x2b);
// Lcd_WriteData(0x00);
// Lcd_WriteData(y_start+0x18);
// Lcd_WriteData(0x00);
// Lcd_WriteData(y_end+0x18);
Lcd_WriteIndex(0x2b);
Lcd_WriteData(0x00);
Lcd_WriteData(y_start+0x1A);
Lcd_WriteData(0x00);
Lcd_WriteData(y_end+0x1A);
Lcd_WriteIndex(0x2c);
}
/*************************************************
函数名:LCD_Set_XY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(u16 x,u16 y)
{
Lcd_SetRegion(x,y,x,y);
}
/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:无
返回值:无
*************************************************/
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{
Lcd_SetRegion(x,y,x+1,y+1);
LCD_WriteData_16Bit(Data);
}
/*****************************************
函数功能:读TFT某一点的颜色
出口参数:color 点颜色值
******************************************/
unsigned int Lcd_ReadPoint(u16 x,u16 y)
{
unsigned int Data;
Lcd_SetXY(x,y);
//Lcd_ReadData();//丢掉无用字节
//Data=Lcd_ReadData();
Lcd_WriteData(Data);
return Data;
}
/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色COLOR
返回值:无
*************************************************/
void Lcd_Clear(u16 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);
}
}
/*************************************************
函数名:f_Lcd_ShowBmp_ColorValue
功能:指定位置显示图片
入口参数:
pbmp : 图片数组指针(像素点字节颜色值,高字节在前)
x0 : 图片显示起点x坐标
y0 : 图片显示起点y坐标
x_Len : 图片宽度
y_Len : 图片高度
返回值:无
*************************************************/
void f_Lcd_ShowBmp_ColorValue(const uint8_t * pbmp, uint8_t x0, uint8_t y0, uint8_t x_Len, uint8_t y_Len) {
uint8_t x1 = x0+x_Len;
uint8_t y1 = y0+y_Len;
uint16_t xy = (x_Len*y_Len) << 1;
uint16_t i = 0;
Lcd_SetRegion(x0, y0, x1-1, y1-1);
Lcd_WriteIndex(0x2C);
for(i=0;(i<<1)<xy;i++)
LCD_WriteData_16Bit((pbmp[i<<1]<<8) + pbmp[(i<<1)+1]);
}
/*************************************************
函数名:f_Lcd_ClearBlock
功能:在指定区域显示颜色
入口参数:
pbmp : 颜色值
x0 : 显示区域起点x坐标
y0 : 显示区域起点y坐标
x_Len : 显示区域宽度
y_Len : 显示区域高度
返回值:无
*************************************************/
void f_Lcd_ClearBlock(uint16_t Color, uint8_t x0, uint8_t y0, uint8_t x_Len, uint8_t y_Len) {
uint8_t x1 = x0+x_Len;
uint8_t y1 = y0+y_Len;
uint16_t xy = x_Len*y_Len;
uint16_t i = 0;
Lcd_SetRegion(x0, y0, x1-1, y1-1);
Lcd_WriteIndex(0x2C);
for(i=0;i<xy;i++)
LCD_WriteData_16Bit(Color);
}