求助一下各位大神,用STC8H的SPI功能调试LCD屏幕,初始化完成后会保持花屏,没有清屏。
示波器抓波形清屏程序是在写入数据的。
下图为波形,蓝线为SCL即时钟,紫色是SDA即发送数据。
搜索了下相关,有说是清屏时序问题的。
整体函数
#include<stc8h.h>
#include<intrins.h>
#define ESPI 0x02
typedef unsigned char u8;
sfr IE2=0xAF;//close SPI中断
sfr SPSTAT=0xCD;
sfr SPCTL=0xCE;
sfr SPDAT=0xCF;
sfr P_SW1=0xA2;
sfr P_SW2=0xBA;
sfr P0M0 = 0x94;
sfr P0M1 = 0x93;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P2M0 = 0x96;
sfr P2M1 = 0x95;
sfr P3M0 = 0xB2;
sfr P3M1 = 0xB1;
sfr P4M0 = 0xB4;
sfr P4M1 = 0xB3;
sfr P5M0 = 0xCA;
sfr P5M1 = 0xC9;
sbit LCD_PIN_SCK=P1^5;
sbit LCD_PIN_SDA=P1^3;
sbit LCD_PIN_CSX=P1^2;
sbit LCD_PIN_RESX=P3^4;
sbit LCD_PIN_DCX=P3^5;
int timems=0;
unsigned char i;
unsigned short a=0;
unsigned short b=0;
int J = 0;
void Delay1ms(unsigned int c) //延时1ms约
{
unsigned char a, b;
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=150;a>0;a--);
}
}
}
void delaynms(unsigned int di) //lcd用的延时
{
unsigned char da,db;
for (;di>0;di--)
{
for(da=0;da<10;da++)
{
for(db=0;db<10;db++);
}
}
}
void SPI_Isr() interrupt 9 //SPI中断,用于SPDAT写完一条数据清0,和改片选
{
SPSTAT=0xc0; //清中断标志
LCD_PIN_CSX=1;
LCD_PIN_DCX=!LCD_PIN_DCX;
//P10=!P10;
}
void LCD_WR_DATA(u8 i)//data函数,写数据函数
{
LCD_PIN_DCX=1;
LCD_PIN_CSX=0;
SPDAT=i;
//LCD_PIN_CSX=1;
}
void LCD_WR_REG(u8 i)//register函数,写命令函数
{
LCD_PIN_DCX=0;
LCD_PIN_CSX=0;
SPDAT=i;
//LCD_PIN_CSX=1;
}
void lcd_st7735s_init() //LCD屏幕初始化
{
LCD_WR_REG(0x11); //Sleep out
Delay1ms(120);
LCD_WR_REG(0xB1);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_REG(0xB2);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_REG(0xB3);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_REG(0xB4);
LCD_WR_DATA(0x03);
LCD_WR_REG(0xC0);
LCD_WR_DATA(0x28);
LCD_WR_DATA(0x08);
LCD_WR_DATA(0x04);
LCD_WR_REG(0xC1);
LCD_WR_DATA(0XC0);
LCD_WR_REG(0xC2);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xC3);
LCD_WR_DATA(0x8D);
LCD_WR_DATA(0x2A);
LCD_WR_REG(0xC4);
LCD_WR_DATA(0x8D);
LCD_WR_DATA(0xEE);
LCD_WR_REG(0xC5);
LCD_WR_DATA(0x1A);
LCD_WR_REG(0x36);
LCD_WR_DATA(0xC0);
LCD_WR_REG(0xE0);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x22);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x30);
LCD_WR_DATA(0x25);
LCD_WR_DATA(0x2A);
LCD_WR_DATA(0x28);
LCD_WR_DATA(0x26);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x3A);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x03);
LCD_WR_DATA(0x13);
LCD_WR_REG(0xE1);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x16);
LCD_WR_DATA(0x06);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x2D);
LCD_WR_DATA(0x26);
LCD_WR_DATA(0x23);
LCD_WR_DATA(0x27);
LCD_WR_DATA(0x27);
LCD_WR_DATA(0x25);
LCD_WR_DATA(0x2D);
LCD_WR_DATA(0x3B);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x13);
LCD_WR_REG(0x3A);
LCD_WR_DATA(0x05);
LCD_WR_REG(0x29);
}
void lcd_set_address(u8 x1, u8 y1, u8 x2, u8 y2)//框选要写入的点数范围
{
LCD_WR_REG(0x2A);
LCD_WR_DATA(x1>>8);
LCD_WR_DATA(x1&0xFF);
LCD_WR_DATA(x2>>8);
LCD_WR_DATA(x2&0xFF);
LCD_WR_REG(0x2B);
LCD_WR_DATA(y1>>8);
LCD_WR_DATA(y1&0xFF);
LCD_WR_DATA(y2>>8);
LCD_WR_DATA(y2&0xFF);
delaynms(50);
LCD_WR_REG(0x2C);
}
void lcd_clear(u8 colorA,u8 colorB)//清屏函数
{
delaynms(50);
lcd_set_address(0, 0, 100, 100);
for(a= 0; a< 100;a++)
{
for (b = 0; b < 100; b++)
{
LCD_WR_DATA(colorA);
delaynms(40);
LCD_WR_DATA(colorB);
delaynms(40);
}
}
}
//以下为主函数入口
void main()
{
P_SW2|=0x80; //使能访问XFR
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x04; P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x30; P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P_SW1=0x00;
SPCTL = 0xD0; //使能SPI主机模式
SPSTAT = 0xc0; //清中断标志
IE2 = ESPI; //使能SPI中断
EA = 1;
LCD_PIN_RESX=1;//复位
Delay1ms(10);
LCD_PIN_RESX=0;
Delay1ms(20);
LCD_PIN_RESX=1;
Delay1ms(20);//复位
lcd_st7735s_init();//初始化
lcd_clear(0xFF,0xE0);//清屏
while(1);
}
清屏函数
void lcd_clear(u8 colorA,u8 colorB)
{
delaynms(50);
lcd_set_address(0, 0, 100, 100);
for(a= 0; a< 100;a++)
{
for (b = 0; b < 100; b++)
{
LCD_WR_DATA(colorA);
delaynms(40);
LCD_WR_DATA(colorB);
delaynms(40);
}
}
}
框选函数
void lcd_set_address(u8 x1, u8 y1, u8 x2, u8 y2)
{
LCD_WR_REG(0x2A);
LCD_WR_DATA(x1>>8);
LCD_WR_DATA(x1&0xFF);
LCD_WR_DATA(x2>>8);
LCD_WR_DATA(x2&0xFF);
LCD_WR_REG(0x2B);
LCD_WR_DATA(y1>>8);
LCD_WR_DATA(y1&0xFF);
LCD_WR_DATA(y2>>8);
LCD_WR_DATA(y2&0xFF);
delaynms(50);
LCD_WR_REG(0x2C);
}
初始化函数
void lcd_st7735s_init()
{
LCD_WR_REG(0x11); //Sleep out
Delay1ms(120);
LCD_WR_REG(0xB1);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_REG(0xB2);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_REG(0xB3);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0x3C);
LCD_WR_REG(0xB4);
LCD_WR_DATA(0x03);
LCD_WR_REG(0xC0);
LCD_WR_DATA(0x28);
LCD_WR_DATA(0x08);
LCD_WR_DATA(0x04);
LCD_WR_REG(0xC1);
LCD_WR_DATA(0XC0);
LCD_WR_REG(0xC2);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xC3);
LCD_WR_DATA(0x8D);
LCD_WR_DATA(0x2A);
LCD_WR_REG(0xC4);
LCD_WR_DATA(0x8D);
LCD_WR_DATA(0xEE);
LCD_WR_REG(0xC5);
LCD_WR_DATA(0x1A);
LCD_WR_REG(0x36);
LCD_WR_DATA(0xC0);
LCD_WR_REG(0xE0);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x22);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x30);
LCD_WR_DATA(0x25);
LCD_WR_DATA(0x2A);
LCD_WR_DATA(0x28);
LCD_WR_DATA(0x26);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x3A);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x03);
LCD_WR_DATA(0x13);
LCD_WR_REG(0xE1);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x16);
LCD_WR_DATA(0x06);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x2D);
LCD_WR_DATA(0x26);
LCD_WR_DATA(0x23);
LCD_WR_DATA(0x27);
LCD_WR_DATA(0x27);
LCD_WR_DATA(0x25);
LCD_WR_DATA(0x2D);
LCD_WR_DATA(0x3B);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x13);
LCD_WR_REG(0x3A);
LCD_WR_DATA(0x05);
LCD_WR_REG(0x29);
}
写命令数据的SDA输出函数(PIN1.3)
void SPI_Isr() interrupt 9
{
SPSTAT=0xc0; //清中断标志
LCD_PIN_CSX=1;
LCD_PIN_DCX=!LCD_PIN_DCX;
//P10=!P10;
}
void LCD_WR_DATA(u8 i)//data函数
{
LCD_PIN_DCX=1;
LCD_PIN_CSX=0;
SPDAT=i;
//LCD_PIN_CSX=1;
}
void LCD_WR_REG(u8 i)//register函数
{
LCD_PIN_DCX=0;
LCD_PIN_CSX=0;
SPDAT=i;
//LCD_PIN_CSX=1;
}