修改程序后,LCD屏读不出,但是能够打印出 ID9341。
使用原子哥的例程做出的接口修改:
#define LCD_LED PCout(1) //LCD背光 PB1
#define LCD_CS_SET GPIOC->BSRR=1<<9 //片选端口 PC9
#define LCD_RS_SET GPIOC->BSRR=1<<8 //数据/命令 PC8
#define LCD_WR_SET GPIOC->BSRR=1<<7 //写数据 PC7
#define LCD_RD_SET GPIOC->BSRR=1<<6 //读数据 PC6
#define LCD_CS_CLR GPIOC->BRR=1<<9 //片选端口 PC9
#define LCD_RS_CLR GPIOC->BRR=1<<8 //数据/命令 PC8
#define LCD_WR_CLR GPIOC->BRR=1<<7 //写数据 PC7
#define LCD_RD_CLR GPIOC->BRR=1<<6 //读数据 PC6
//PD0~15,作为数据线
#define DATAOUT(x) GPIOD->ODR=x; //数据输出
#define DATAIN GPIOD->IDR; //数据输入
下面是寄存器修改:
u16 LCD_RD_DATA(void)
{
u16 t;
GPIOD->CRL=0X88888888; //PB0-7 上拉输入
GPIOD->CRH=0X88888888; //PB8-15 上拉输入
GPIOD->ODR=0X0000; //全部输出0
LCD_RS_SET;
LCD_CS_CLR;
//读取数据(读寄存器时,并不需要读2次)
LCD_RD_CLR;
if(lcddev.id==0X8989)delay_us(2);//FOR 8989,延时2us
LCD_RD_SET;
t=DATAIN;
LCD_CS_SET;
GPIOD->CRL=0X33333333; //PB0-7 上拉输出
GPIOD->CRH=0X33333333; //PB8-15 上拉输出
GPIOD->ODR=0XFFFF; //全部输出高
return t;
}
u16 LCD_ReadPoint(u16 x,u16 y)
{
u16 r,g,b;
if(x>=lcddev.width||y>=lcddev.height)return 0; //超过了范围,直接返回
LCD_SetCursor(x,y);
if(lcddev.id==0X9341||lcddev.id==0X6804)LCD_WR_REG(0X2E); //9341/6804发送读GRAM指令
else LCD_WR_REG(R34); //其他IC发送读GRAM指令
GPIOD->CRL=0X88888888; //PB0-7 上拉输入
GPIOD->CRH=0X88888888; //PB8-15 上拉输入
GPIOD->ODR=0XFFFF; //全部输出高
LCD_RS_SET;
LCD_CS_CLR;
//读取数据(读GRAM时,第一次为假读)
LCD_RD_CLR;
delay_us(1);//延时1us
LCD_RD_SET;
//dummy READ
LCD_RD_CLR;
delay_us(1);//延时1us
LCD_RD_SET;
r=DATAIN;
if(lcddev.id==0X9341)
{
LCD_RD_CLR;
LCD_RD_SET;
b=DATAIN;//读取蓝 {MOD}值
g=r&0XFF;//对于9341,第一次读取的是RG的值,R在前,G在后,各占8位
g<<=8;
}else if(lcddev.id==0X6804)
{
LCD_RD_CLR;
LCD_RD_SET;
r=DATAIN;//6804第二次读取的才是真实值
}
LCD_CS_SET;
GPIOD->CRL=0X33333333; //PB0-7 上拉输出
GPIOD->CRH=0X33333333; //PB8-15 上拉输出
GPIOD->ODR=0XFFFF; //全部输出高
if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0X8989||lcddev.id==0XB505)return r; //这几种IC直接返回颜 {MOD}值
else if(lcddev.id==0X9341)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11)); //ILI9341需要公式转换一下
else return LCD_BGR2RGB(r); //其他IC
}
//初始化lcd
//该初始化函数可以初始化各种ALIENTEK出品的LCD液晶屏
//本函数占用较大flash,用户可以根据自己的实际情况,删掉未用到的LCD初始化代码.以节省空间.
void LCD_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE); //使能PORTB,C时钟和AFIO时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//开启SWD,失能JTAG
//PB1(lcd_BL)背光
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; ///PB1复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
//PC6(lcd_RD),PC7(lcd_WR),PC8(lcd_RS),PC9(lcd_CS)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6; ///PORTC6~9复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //GPIOC
GPIO_SetBits(GPIOC,GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6);
//lcd数据引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // PORTD推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //GPIOD
GPIO_SetBits(GPIOD,GPIO_Pin_All);
delay_ms(50); // delay 50 ms
LCD_WriteReg(0x0000,0x0001);
delay_ms(50); // delay 50 ms
lcddev.id = LCD_ReadReg(0x0000);
if(lcddev.id<0XFF||lcddev.id==0XFFFF||lcddev.id==0X9300)//读到ID不正确,新增lcddev.id==0X9300判断,因为9341在未被复位的情况下会被读成9300
{
//尝试9341 ID的读取
LCD_WR_REG(0XD3);
LCD_RD_DATA(); //dummy read
LCD_RD_DATA(); //读到0X00
lcddev.id=LCD_RD_DATA(); //读取93
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //读取41
if(lcddev.id!=0X9341) //非9341,尝试是不是6804
{
LCD_WR_REG(0XBF);
LCD_RD_DATA(); //dummy read
LCD_RD_DATA(); //读回0X01
LCD_RD_DATA(); //读回0XD0
lcddev.id=LCD_RD_DATA();//这里读回0X68
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA();//这里读回0X04
if(lcddev.id!=0X6804) //也不是6804,尝试看看是不是NT35310
{
LCD_WR_REG(0XD4);
LCD_RD_DATA(); //dummy read
LCD_RD_DATA(); //读回0X01
lcddev.id=LCD_RD_DATA(); //读回0X53
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //这里读回0X10
if(lcddev.id!=0X5310) //也不是NT35310,尝试看看是不是NT35510
{
LCD_WR_REG(0XDA00);
LCD_RD_DATA(); //读回0X00
LCD_WR_REG(0XDB00);
lcddev.id=LCD_RD_DATA();//读回0X80
lcddev.id<<=8;
LCD_WR_REG(0XDC00);
lcddev.id|=LCD_RD_DATA();//读回0X00
if(lcddev.id==0x8000)lcddev.id=0x5510;//NT35510读回的ID是8000H,为方便区分,我们强制设置为5510
if(lcddev.id!=0X5510) //也不是NT5510,尝试看看是不是SSD1963
{
LCD_WR_REG(0XA1);
lcddev.id=LCD_RD_DATA();
lcddev.id=LCD_RD_DATA(); //读回0X57
lcddev.id<<=8;
lcddev.id|=LCD_RD_DATA(); //读回0X61
if(lcddev.id==0X5761)lcddev.id=0X1963;//SSD1963读回的ID是5761H,为方便区分,我们强制设置为1963
}
}
}
}
}
printf(" LCD ID:%x
",lcddev.id); //打印LCD ID
if(lcddev.id==0X9341) //9341初始化
{
LCD_WR_REG(0xCF);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0xC1);
LCD_WR_DATAX(0X30);
LCD_WR_REG(0xED);
LCD_WR_DATAX(0x64);
LCD_WR_DATAX(0x03);
LCD_WR_DATAX(0X12);
LCD_WR_DATAX(0X81);
LCD_WR_REG(0xE8);
LCD_WR_DATAX(0x85);
LCD_WR_DATAX(0x10);
LCD_WR_DATAX(0x7A);
LCD_WR_REG(0xCB);
LCD_WR_DATAX(0x39);
LCD_WR_DATAX(0x2C);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x34);
LCD_WR_DATAX(0x02);
LCD_WR_REG(0xF7);
LCD_WR_DATAX(0x20);
LCD_WR_REG(0xEA);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_REG(0xC0); //Power control
LCD_WR_DATAX(0x1B); //VRH[5:0]
LCD_WR_REG(0xC1); //Power control
LCD_WR_DATAX(0x01); //SAP[2:0];BT[3:0]
LCD_WR_REG(0xC5); //VCM control
LCD_WR_DATAX(0x30); //3F
LCD_WR_DATAX(0x30); //3C
LCD_WR_REG(0xC7); //VCM control2
LCD_WR_DATAX(0XB7);
LCD_WR_REG(0x36); // Memory Access Control
LCD_WR_DATAX(0x48);
LCD_WR_REG(0x3A);
LCD_WR_DATAX(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x1A);
LCD_WR_REG(0xB6); // Display Function Control
LCD_WR_DATAX(0x0A);
LCD_WR_DATAX(0xA2);
LCD_WR_REG(0xF2); // 3Gamma Function Disable
LCD_WR_DATAX(0x00);
LCD_WR_REG(0x26); //Gamma curve selected
LCD_WR_DATAX(0x01);
LCD_WR_REG(0xE0); //Set Gamma
LCD_WR_DATAX(0x0F);
LCD_WR_DATAX(0x2A);
LCD_WR_DATAX(0x28);
LCD_WR_DATAX(0x08);
LCD_WR_DATAX(0x0E);
LCD_WR_DATAX(0x08);
LCD_WR_DATAX(0x54);
LCD_WR_DATAX(0XA9);
LCD_WR_DATAX(0x43);
LCD_WR_DATAX(0x0A);
LCD_WR_DATAX(0x0F);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_REG(0XE1); //Set Gamma
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x15);
LCD_WR_DATAX(0x17);
LCD_WR_DATAX(0x07);
LCD_WR_DATAX(0x11);
LCD_WR_DATAX(0x06);
LCD_WR_DATAX(0x2B);
LCD_WR_DATAX(0x56);
LCD_WR_DATAX(0x3C);
LCD_WR_DATAX(0x05);
LCD_WR_DATAX(0x10);
LCD_WR_DATAX(0x0F);
LCD_WR_DATAX(0x3F);
LCD_WR_DATAX(0x3F);
LCD_WR_DATAX(0x0F);
LCD_WR_REG(0x2B);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x01);
LCD_WR_DATAX(0x3f);
LCD_WR_REG(0x2A);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0x00);
LCD_WR_DATAX(0xef);
LCD_WR_REG(0x11); //Exit Sleep
delay_ms(120);
LCD_WR_REG(0x29); //display on
}
LCD_Display_Dir(0); //默认为竖屏
LCD_LED=1; //点亮背光
LCD_Clear(WHITE);
}
请问各问大神是什么地方出错了。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
验证方法:
1,用仿真器单步跟踪。
2,每设置一个你修改过的IO,仿真器暂停(设断点),用万用表测IO电平,是否和预期 一致。
3,依照方法2检查所有改过的IO。
这样,你就知道哪里出问题了
一周热门 更多>