STM32+天马3.2寸TFT(HX8357),模组可以正常显示并切换纯 {MOD}图片,但是没法显示字符及其它彩图

2019-10-12 14:03发布

原子哥:现在使用miniSTM32+天马3.2寸TFT(HX8357),模组可以正常显示并切换纯 {MOD}图片,但是没法显示字符及其它彩图,请问是哪里出问题了呢?
#include "lcd.h"
#include "stdlib.h"
#include "font.h"
#include "usart.h"
#include "delay.h"         

//LCD的画笔颜 {MOD}和背景 {MOD}          
u16 POINT_COLOR=0x0000;        //画笔颜 {MOD}
u16 BACK_COLOR=0xFFFF;  //背景 {MOD}

//管理LCD重要参数
//默认为竖屏
_lcd_dev lcddev;
                                                     
//写寄存器函数
//data:寄存器值
void LCD_WR_REG(u16 data)
{
        LCD_RS_CLR;//写地址
//        delay_ms(10);
        LCD_CS_CLR;
//        delay_ms(10);
        DATAOUT(data);
        LCD_WR_CLR;
//        delay_ms(10);
        LCD_WR_SET;
//    delay_ms(10);
        LCD_CS_SET;   
}
//写数据函数
//可以替代LCD_WR_DATAX宏,拿时间换空间.
//data:寄存器值
void LCD_WR_DATAX(u16 data)
{
        LCD_RS_SET;
//                delay_ms(10);
        LCD_CS_CLR;
//                delay_ms(10);
        DATAOUT(data);
        LCD_WR_CLR;
//                delay_ms(10);
        LCD_WR_SET;
//                delay_ms(10);
        LCD_CS_SET;
}
//读LCD数据
//返回值:读到的值
u16 LCD_RD_DATA(void)
{                                                                                  
        u16 t;
        GPIOB->CRL=0X88888888; //PB0-7  上拉输入
        GPIOB->CRH=0X88888888; //PB8-15 上拉输入
        GPIOB->ODR=0X0000;     //全部输出0

        LCD_RS_SET;
//                delay_ms(10);
        LCD_CS_CLR;
//                delay_ms(10);
        //读取数据(读寄存器时,并不需要读2次)
        LCD_RD_CLR;                          
        t=DATAIN;  
        LCD_RD_SET;
//                delay_ms(100);
        LCD_CS_SET;

        GPIOB->CRL=0X33333333; //PB0-7  上拉输出
        GPIOB->CRH=0X33333333; //PB8-15 上拉输出
        GPIOB->ODR=0XFFFF;    //全部输出高
        return t;  
}
//写寄存器
//LCD_Reg:寄存器编号
//LCD_RegValue:要写入的值
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue)
{       
        LCD_WR_REG(LCD_Reg);  
        LCD_WR_DATA(LCD_RegValue);                             
}   
//读寄存器
//LCD_Reg:寄存器编号
//返回值:读到的值
u16 LCD_ReadReg(u16 LCD_Reg)
{                                                                                  
        LCD_WR_REG(LCD_Reg);  //写入要读的寄存器号  
        return LCD_RD_DATA();
}
//开始写GRAM
void LCD_WriteRAM_Prepare(void)
{
        LCD_WR_REG(lcddev.wramcmd);
}
//LCD写GRAM
//RGB_Code:颜 {MOD}值
void LCD_WriteRAM(u16 RGB_Code)
{                                                            
        LCD_WR_DATA(RGB_Code);//写十六位GRAM
}
         
//LCD开启显示
void LCD_DisplayOn(void)
{       
        LCD_WR_REG(0X29);        //开启显示

}         
//LCD关闭显示
void LCD_DisplayOff(void)
{          
        LCD_WR_REG(0X28);        //关闭显示
}   
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
                                    
                LCD_WR_REG(lcddev.setxcmd);
                LCD_WR_DATA(Xpos>>8);
                LCD_WR_DATA(Xpos&0XFF);         
                LCD_WR_REG(lcddev.setycmd);
                LCD_WR_DATA(Ypos>>8);
                LCD_WR_DATA(Ypos&0XFF);
       
}
//设置LCD的自动扫描方向
//注意:其他函数可能会受到此函数设置的影响(尤其是9341/6804这两个奇葩),
//所以,一般设置为L2R_U2D即可,如果设置为其他扫描方式,可能导致显示不正常.
//dir:0~7,代表8个方向(具体定义见lcd.h)
//9320/9325/9328/4531/4535/1505/b505/8989/5408/9341/5310/5510等IC已经实际测试                     
void LCD_Scan_Dir(u8 dir)
{
        u16 regval=0;
        u16 dirreg=0;
        u16 temp;  
                switch(dir)
                {
                        case L2R_U2D://从左到右,从上到下
                                regval|=(0<<7)|(0<<6)|(0<<5);
                                break;
                        case L2R_D2U://从左到右,从下到上
                                regval|=(1<<7)|(0<<6)|(0<<5);
                                break;
                        case R2L_U2D://从右到左,从上到下
                                regval|=(0<<7)|(1<<6)|(0<<5);
                                break;
                        case R2L_D2U://从右到左,从下到上
                                regval|=(1<<7)|(1<<6)|(0<<5);
                                break;         
                        case U2D_L2R://从上到下,从左到右
                                regval|=(0<<7)|(0<<6)|(1<<5);
                                break;
                        case U2D_R2L://从上到下,从右到左
                                regval|=(0<<7)|(1<<6)|(1<<5);
                                break;
                        case D2U_L2R://从下到上,从左到右
                                regval|=(1<<7)|(0<<6)|(1<<5);
                                break;
                        case D2U_R2L://从下到上,从右到左
                                regval|=(1<<7)|(1<<6)|(1<<5);
                                break;         
                }               
                        LCD_WriteReg(dirreg,regval);
}  
//画点
//x,y:坐标
//POINT_COLOR:此点的颜 {MOD}
void LCD_DrawPoint(u16 x,u16 y)
{
        LCD_SetCursor(x,y);                //设置光标位置
        LCD_WriteRAM_Prepare();        //开始写入GRAM
        LCD_WR_DATA(POINT_COLOR);
}           
//快速画点
//x,y:坐标
//color:颜 {MOD}
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)
{          

        LCD_WR_REG(lcddev.setxcmd);
        LCD_WR_DATA(x>>8);
        LCD_WR_DATA(x&0XFF);         
        LCD_WR_REG(lcddev.setycmd);
        LCD_WR_DATA(y>>8);
        LCD_WR_DATA(y&0XFF);

        LCD_RS_CLR;
        LCD_CS_CLR;
        DATAOUT(lcddev.wramcmd);//写指令  
        LCD_WR_CLR;
        LCD_WR_SET;
        LCD_CS_SET;
        LCD_WR_DATA(color);                //写数据
}
//设置LCD显示方向
//dir:0,竖屏;1,横屏
void LCD_Display_Dir(u8 dir)
{
        if(dir==0)                        //竖屏
        {
                lcddev.dir=0;        //竖屏
                lcddev.width=320;
                lcddev.height=480;
                lcddev.wramcmd=0X2C;
                lcddev.setxcmd=0X2A;
                lcddev.setycmd=0X2B;           

        }else                                 //横屏
        {                                         
                lcddev.dir=1;        //横屏
                lcddev.width=320;
                lcddev.height=480;
                lcddev.wramcmd=0X2C;
                lcddev.setxcmd=0X2A;
                lcddev.setycmd=0X2B;           
        }
        LCD_Scan_Dir(DFT_SCAN_DIR);        //默认扫描方向
}         
//设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
//sx,sy:窗口起始坐标(左上角)
//width,height:窗口宽度和高度,必须大于0!!
//窗体大小:width*height.
//68042,横屏时不支持窗口设置!!
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)
{   
        u8 hsareg,heareg,vsareg,veareg;
        u16 hsaval,heaval,vsaval,veaval;
        width=sx+width-1;
        height=sy+height-1;

        LCD_WR_REG(lcddev.setxcmd);
        LCD_WR_DATA(sx>>8);
        LCD_WR_DATA(sx&0XFF);         
        LCD_WR_DATA(width>>8);
        LCD_WR_DATA(width&0XFF);  
        LCD_WR_REG(lcddev.setycmd);
        LCD_WR_DATA(sy>>8);
        LCD_WR_DATA(sy&0XFF);
        LCD_WR_DATA(height>>8);
        LCD_WR_DATA(height&0XFF);
                        if(lcddev.dir==1)//横屏
                {
                        //窗口值
                        hsaval=sy;                               
                        heaval=height;
                        vsaval=lcddev.width-width-1;
                        veaval=lcddev.width-sx-1;                               
                }else
                {
                        hsaval=sx;                               
                        heaval=width;
                        vsaval=sy;
                        veaval=height;
                }
                hsareg=0X50;heareg=0X51;//水平方向窗口寄存器
                vsareg=0X52;veareg=0X53;//垂直方向窗口寄存器         
        //设置寄存器值
        LCD_WriteReg(hsareg,hsaval);
        LCD_WriteReg(heareg,heaval);
        LCD_WriteReg(vsareg,vsaval);
        LCD_WriteReg(veareg,veaval);               
        LCD_SetCursor(sx,sy);        //设置光标位置
       
}
//初始化lcd
//该初始化函数可以初始化各种ALIENTEK出品的LCD液晶屏
//本函数占用较大flash,用户可以根据自己的实际情况,删掉未用到的LCD初始化代码.以节省空间.
void LCD_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能PORTB,C时钟和AFIO时钟
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//开启SWD,失能JTAG
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6;           ///PORTC6~10复用推挽输出
        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_10|GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;        //  PORTB推挽输出
        GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB

        GPIO_SetBits(GPIOB,GPIO_Pin_All);

        delay_ms(500); // delay 50 ms
        LCD_WriteReg(0x0000,0x0001);
        delay_ms(500); // delay 50 ms
    lcddev.id = LCD_ReadReg(0x0000);        
                LCD_WR_REG(0XDB);                                          
                LCD_RD_DATA();                       //读到0X00
                lcddev.id|=LCD_RD_DATA();          //读取41                                      

if(lcddev.id!=0X9341)        //9341初始化
{       

        LCD_WR_REG(0xB0);//{setc, [107], W,0x0B0}
        LCD_WR_DATAX(0x00);//{setp, [104], W,0x000}
       
        LCD_WR_REG(0xB3);
        LCD_WR_DATAX(0x02);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
       
        LCD_WR_REG(0xB4);
        LCD_WR_DATAX(0x00);
       
        LCD_WR_REG(0xC0);
        LCD_WR_DATAX(0x13);//
        LCD_WR_DATAX(0x3B);//480
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x03);//02
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x01);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x43);
       
        LCD_WR_REG(0xC1);
        LCD_WR_DATAX(0x08);
        LCD_WR_DATAX(0x12);//CLOCK
        LCD_WR_DATAX(0x08);
        LCD_WR_DATAX(0x08);
       
        LCD_WR_REG(0xC4);
        LCD_WR_DATAX(0x11);
        LCD_WR_DATAX(0x07);
        LCD_WR_DATAX(0x03);
        LCD_WR_DATAX(0x03);
       
        LCD_WR_REG(0xC8);//GAMMA
        LCD_WR_DATAX(0x04);
        LCD_WR_DATAX(0x09);
        LCD_WR_DATAX(0x16);
        LCD_WR_DATAX(0x5A);
        LCD_WR_DATAX(0x02);
        LCD_WR_DATAX(0x0A);
        LCD_WR_DATAX(0x16);
        LCD_WR_DATAX(0x05);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x32);
        LCD_WR_DATAX(0x05);
        LCD_WR_DATAX(0x16);
        LCD_WR_DATAX(0x0A);
        LCD_WR_DATAX(0x53);//43/55
        LCD_WR_DATAX(0x08);
        LCD_WR_DATAX(0x16);
        LCD_WR_DATAX(0x09);
        LCD_WR_DATAX(0x04);
        LCD_WR_DATAX(0x32);
        LCD_WR_DATAX(0x00);
       
        LCD_WR_REG(0x2A);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x01);
        LCD_WR_DATAX(0x3F);//320
       
        LCD_WR_REG(0x2B);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x01);
        LCD_WR_DATAX(0xDF);//480
       
        LCD_WR_REG(0x35);
        LCD_WR_DATAX(0x00);
       
        LCD_WR_REG(0x3A);
        LCD_WR_DATAX(0x55);
       
        LCD_WR_REG(0x44);
        LCD_WR_DATAX(0x00);
        LCD_WR_DATAX(0x01);
       
        LCD_WR_REG(0x2C);
        LCD_WR_REG(0x11);
       
        delay_ms(150);
       
        LCD_WR_REG(0xD0);
        LCD_WR_DATAX(0x07);
        LCD_WR_DATAX(0x07);
        LCD_WR_DATAX(0x1E);
        LCD_WR_DATAX(0x0703);
       
        LCD_WR_REG(0xD1);
        LCD_WR_DATAX(0x03);
        LCD_WR_DATAX(0x52);//VCM
        LCD_WR_DATAX(0x10);//VDV
       
        LCD_WR_REG(0xD2);
        LCD_WR_DATAX(0x03);
        LCD_WR_DATAX(0x24);
       
        LCD_WR_REG(0xB0);//{setc, [107], W,0x0B0}
        LCD_WR_DATAX(0x00);//{setp, [104], W,0x000}
        LCD_WR_REG(0x11); //Exit Sleep
        delay_ms(120);
        LCD_WR_REG(0x29); //display on       
        delay_ms(10);       
        LCD_Display_Dir(0);                         //默认为竖屏  
        }
}         
@正点原子
      
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。