OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7102|回复: 2

求助帖:TFT屏显示异常(代码求助)

[复制链接]

9

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2012-11-19
在线时间
2 小时
发表于 2013-7-9 12:42:52 | 显示全部楼层 |阅读模式
用的是旗舰的板子,硬件没问题,下载历程验证过。
显示的位置,颜色没问题,但是字符不对,用的也是历程上的font.h文件,tft驱动9325。
正确显示的话:
第一行:字符串”THIS is char show“
第二行:不断加1的数字显示
第三行:库里的字符(不断变化的)
另有错误图片,附件
求教代码,感觉是写字符的函数有问题???

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "FONT.h"

//战舰版得IO由FSMC控制,下位Mini型端口设置

u16 F_COLOR,B_COLOR;

//////////////////////LCD与FSMC的匹配///////////////////////////////////////////////////  
//-----------------LCD端口定义---------------- 
#define LCD_LED PBout(0) //LCD背光      B0      
//LCD地址结构体
typedef struct
{
u16 LCD_REG;
u16 LCD_RAM;
} LCD_TypeDef;
//使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A10作为数据命令区分线 
//注意设置时STM32内部会右移一位对其! 111110=0X3E     
#define LCD_BASE        ((u32)(0x6C000000 | 0x000007FE))
#define LCD             ((LCD_TypeDef *) LCD_BASE)
//////////////////////////////////////////////////////////////////////////////////
void LCD_WR_REG(u16 regval)
{
LCD->LCD_REG=regval;//写入要写的寄存器号
}

void LCD_WR_DATA(u16 data)
{
LCD->LCD_RAM=data;//写入数据
}

//写寄存器
void LCD_WriteReg(u8 LCD_Reg,u16 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}

//读LCD数据
u16 LCD_RD_DATA(void)
{
return LCD->LCD_RAM;
}

//读寄存器
u16 LCD_ReadReg(u8 LCD_Reg)
{
LCD_WR_REG(LCD_Reg);//读取的寄存器号
delay_us(5);
return LCD_RD_DATA();//返回读到的数值
}

void LCD_Init(void)
  
RCC->AHBENR|=1<<8;       //使能FSMC时钟   
   RCC->APB2ENR|=1<<3;      //使能PORTB时钟
RCC->APB2ENR|=1<<5;      //使能PORTD时钟
RCC->APB2ENR|=1<<6;      //使能PORTE时钟
  RCC->APB2ENR|=1<<8;      //使能PORTG时钟  
GPIOB->CRL&=0XFFFFFFF0;//PB0 推挽输出 背光
GPIOB->CRL|=0X00000003;    
//PORTD复用推挽输出 
GPIOD->CRH&=0X00FFF000;
GPIOD->CRH|=0XBB000BBB; 
GPIOD->CRL&=0XFF00FF00;
GPIOD->CRL|=0X00BB00BB;     
//PORTE复用推挽输出 
GPIOE->CRH&=0X00000000;
GPIOE->CRH|=0XBBBBBBBB; 
GPIOE->CRL&=0X0FFFFFFF;
GPIOE->CRL|=0XB0000000;             
//PORTG12复用推挽输出 A0         
GPIOG->CRH&=0XFFF0FFFF;
GPIOG->CRH|=0X000B0000; 
GPIOG->CRL&=0XFFFFFFF0;//PG0->RS
GPIOG->CRL|=0X0000000B; 

//寄存器清零
//bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
//这里我们使用NE4 ,也就对应BTCR[6],[7]。     
FSMC_Bank1->BTCR[6]=0X00000000;
FSMC_Bank1->BTCR[7]=0X00000000;
FSMC_Bank1E->BWTR[6]=0X00000000;
//操作BCR寄存器 使用异步模式
FSMC_Bank1->BTCR[6]|=1<<12; //存储器写使能
FSMC_Bank1->BTCR[6]|=1<<14; //读写使用不同的时序
FSMC_Bank1->BTCR[6]|=1<<4;  //存储器数据宽度为16bit      
//操作BTR寄存器
//读时序控制寄存器      
FSMC_Bank1->BTCR[7]|=0<<28; //模式A        
FSMC_Bank1->BTCR[7]|=1<<0;  //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns    
//因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。
FSMC_Bank1->BTCR[7]|=0XF<<8;   //数据保存时间为16个HCLK    
//写时序控制寄存器  
FSMC_Bank1E->BWTR[6]|=0<<28;  //模式A        
FSMC_Bank1E->BWTR[6]|=0<<0; //地址建立时间(ADDSET)为1个HCLK 
  //4个HCLK(HCLK=72M)因为液晶驱动IC的写信号脉宽,最少也得50ns。72M/4=24M=55ns    
FSMC_Bank1E->BWTR[6]|=3<<8;  //数据保存时间为4个HCLK
//使能BANK1,区域4
FSMC_Bank1->BTCR[6]|=1<<0; //使能BANK1,区域4
//TFT ID 9325
LCD_WriteReg(0x00E5,0x78F0); 
LCD_WriteReg(0x0001,0x0100); 
LCD_WriteReg(0x0002,0x0700); 
LCD_WriteReg(0x0003,0x1030); 
LCD_WriteReg(0x0004,0x0000); 
LCD_WriteReg(0x0008,0x0202);  
LCD_WriteReg(0x0009,0x0000);
LCD_WriteReg(0x000A,0x0000); 
LCD_WriteReg(0x000C,0x0000); 
LCD_WriteReg(0x000D,0x0000);
LCD_WriteReg(0x000F,0x0000);
//power on sequence VGHVGL
LCD_WriteReg(0x0010,0x0000);   
LCD_WriteReg(0x0011,0x0007);  
LCD_WriteReg(0x0012,0x0000);  
LCD_WriteReg(0x0013,0x0000); 
LCD_WriteReg(0x0007,0x0000); 
//vgh 
LCD_WriteReg(0x0010,0x1690);   
LCD_WriteReg(0x0011,0x0227);
//delayms(100);
//vregiout 
LCD_WriteReg(0x0012,0x009D); //0x001b
//delayms(100); 
//vom amplitude
LCD_WriteReg(0x0013,0x1900);
//delayms(100); 
//vom H
LCD_WriteReg(0x0029,0x0025); 
LCD_WriteReg(0x002B,0x000D); 
//gamma
LCD_WriteReg(0x0030,0x0007);
LCD_WriteReg(0x0031,0x0303);
LCD_WriteReg(0x0032,0x0003);// 0006
LCD_WriteReg(0x0035,0x0206);
LCD_WriteReg(0x0036,0x0008);
LCD_WriteReg(0x0037,0x0406); 
LCD_WriteReg(0x0038,0x0304);//0200
LCD_WriteReg(0x0039,0x0007); 
LCD_WriteReg(0x003C,0x0602);// 0504
LCD_WriteReg(0x003D,0x0008); 
//ram
LCD_WriteReg(0x0050,0x0000); 
LCD_WriteReg(0x0051,0x00EF);
LCD_WriteReg(0x0052,0x0000); 
LCD_WriteReg(0x0053,0x013F);  
LCD_WriteReg(0x0060,0xA700); 
LCD_WriteReg(0x0061,0x0001); 
LCD_WriteReg(0x006A,0x0000); 
//
LCD_WriteReg(0x0080,0x0000); 
LCD_WriteReg(0x0081,0x0000); 
LCD_WriteReg(0x0082,0x0000); 
LCD_WriteReg(0x0083,0x0000); 
LCD_WriteReg(0x0084,0x0000); 
LCD_WriteReg(0x0085,0x0000); 
//
LCD_WriteReg(0x0090,0x0010); 
LCD_WriteReg(0x0092,0x0600); 
LCD_WriteReg(0x0007,0x0133);
LCD_WriteReg(0x00,0x0022);//
LCD_LED = 1;   
 
}
/*加强版函数*/
//设置一种颜色的函数,BGR型显示
u16 color(u8 R,u8 G,u8 B)
{
    u16 CRGB,RGB0,RGB1,RGB2,RGB3,RGB4;

RGB0 = B;

    RGB1 = G;
RGB2 = RGB1<<5;

RGB3 = R;
RGB4 = RGB3<<11;

CRGB = RGB0|RGB2|RGB4;

return CRGB;
}
//画点函数(HEX命令0x xxxx,会随LCD更改而改变)
void DrawPoint(u16 x,u16 y)
{
    LCD_WriteReg(0x0020,x);//X
LCD_WriteReg(0x0021,y);//Y
LCD_WR_REG(0x22);

LCD_WR_DATA(F_COLOR);  //颜色设置:F_COLOR???前景色
}
//黑板擦程序,背景色清屏
void clear_lcd()
{
u16 i,j;

LCD_WriteReg(0x0020,0x00);//X
LCD_WriteReg(0x0021,0x00);//Y
LCD_WR_REG(0x22);

//先横向再纵向扫描
for(i=0;i<320;i++)
{
    for(j=0;j<240;j++)
{
    LCD_WR_DATA(B_COLOR);
}
}
}
////////////////////*写字符函数*///////////////////////////////
/* 从每个字模的第一个Bit开始,从左到右,从上到下,每个bit里的0填充上背景色,1填充上前景色
 * (这样写字时占用的内存大大减小,1个点只要用1个bit储存)
 * 不能用于存储图片,每个点都必须用16位表达
 * 已知横纵方向上起始4个点,可以框出一个框,向里面丢数据。从左到右,从上到下,从底位开始。  
 */
void SHOW_char(u8 Page,u8 List,u8 onechar)
{
     u8 i,j;
 u16 temp1,temp2,temp3,temp4;
 temp1 = onechar-' ';//得出所表达字符在字库中的位置
 temp3 = F_COLOR;    //先临时定义一个变量作为前景色
/*1608型,只显示一个字符*/
 LCD_WriteReg(0x0050,List*8);//设定框的起始X坐标
 LCD_WriteReg(0x0051,(List*8)+7);//设定框的终止X坐标
 LCD_WriteReg(0x0052,Page*16);//设定框的起始Y坐标
 LCD_WriteReg(0x0053,(Page*16)+15);//设定框的起始Y坐标

 /*取框的起始坐标*/
 LCD_WriteReg(0x0020,List*8);
 LCD_WriteReg(0x0021,Page*16);

 LCD_WR_REG(0x22);//开始刷屏
 for(i=0;i<16;i++)
 {
  temp4 = asc2_1608[temp1];//取出字模
for(j=0;j<8;j++)
{
temp2 = temp4;//红字的3行
temp2 &= 0x01; //对每一位进行0,1区分
temp4>>=1;
if(temp2==0)
{
F_COLOR = B_COLOR;
}
else
 {
  F_COLOR = temp3;
 }
 LCD_WR_DATA(F_COLOR);
}
 }
 F_COLOR=temp3;
 //最后一定要释放窗口
 LCD_WriteReg(0x0050,0);
 LCD_WriteReg(0x0051,239);
 LCD_WriteReg(0x0052,0);
 LCD_WriteReg(0x0053,319);
}
/*无背景色显示*/
//返回此点颜色,ID9325
u16 LCD_ReadPoint(u16 x,u16 y)
{
    u16 t;
LCD_WriteReg(0x0020,x);
LCD_WriteReg(0x0021,y);
LCD_WR_REG(0x22); //ID9325,所以发送读GRAM地址
delay_us(2);      
//dummy read???
if(LCD->LCD_RAM)t=0;
delay_us(2);
t=LCD->LCD_RAM;
return t;   
}
//透明背景色的显示字符函数
void SHOW_char_NBC(u8 Page,u8 List,u8 onechar)
{
     u8 i,j;
 u16 temp1,temp2,temp3,temp4;

 temp1 = onechar-' ';//空格
 temp3 = F_COLOR;
 for(i=0;i<16;i++)
 {
     temp4 = asc2_1608[temp1];
 for(j=0;j<8;j++)
 {
     temp2 = temp4;
 temp2 &= 0x01;
 temp4>>=1;
 if(temp2==0)
 {
    
F_COLOR = LCD_ReadPoint((List*8)+j,(Page*16)+i); 
 }
 else
 {
    F_COLOR = temp3;
 }

 LCD_WriteReg(0x0020,List*8+j);
 LCD_WriteReg(0x0021,Page*16+i);
 LCD_WR_REG(0x22);

 LCD_WR_DATA(F_COLOR);
 }
 }
 F_COLOR = temp3;
// 是否用填充???
// LCD_WriteReg(0x0050,0);
// LCD_WriteReg(0x0051,239);
// LCD_WriteReg(0x0052,0);
// LCD_WriteReg(0x0053,319);
}
/*补充函数*/
//显示一串字符
void linechar_1608t(u8 Page,u8 List,u8 *pd)
{
     u8 temp;
 while((*pd)!='\0')
 {
       temp = *pd;
   SHOW_char_NBC(Page,List,temp);
   pd++;
   List=List+1;
 }
}
//粉笔擦:用背景色刷出N个字符位
void Clear_Line(u8 page,u8 list,u8 N)
{
     u8 i;
 for(i=0;i<N;i++)
 {
     SHOW_char(page,list,' ');
 list=list+1;
 }
}
//显示数字串
void count_show(u8 Page,u8 List,u16 input)
{
     u16 temp0,temp1,temp2,temp3,temp4,A,B;
 //分离成独立的位码
 temp0 = input/10000;

 A = input%10000;
 temp1 = A/1000;

 B = A%1000;
 temp2 = B/100;

 A = B%100;
 temp3 = A/10;

 B = A%10;
 temp4 = B;

 //去首位的0
 if(temp0!=0)
 {
    SHOW_char_NBC(Page,List,'0'+temp0);
List=List+1;
 }
 if((temp1!=0)|(temp0!=0))
 {
    SHOW_char_NBC(Page,List,'0'+temp1);
List=List+1;
 }
 if((temp2!=0)|(temp1!=0)|(temp0!=0))
 {
    SHOW_char_NBC(Page,List,'0'+temp2);
List=List+1;
 }
 if((temp3!=0)|(temp2!=0)|(temp1!=0)|(temp0!=0))
 {
    SHOW_char_NBC(Page,List,'0'+temp3);
List=List+1;
 }
 SHOW_char_NBC(Page,List,'0'+temp4);
  
}
// 从原子的例程学到,写0x0001到TFT屏的0x0000号寄存器,然后等50毫秒,再读一下寄存器0x0000.就会读到屏的型号.
int main(void)
{
    u8 k=' ';    
u16 i=0;
Stm32_Clock_Init(9);
delay_init(72);
uart_init(72,9600);
LCD_Init();

B_COLOR = color(7,14,7);
clear_lcd();
// LCD_WriteReg(0x0007,0x0);
// LCD_WriteReg(0x0007,0x173); //26万色显示开启
while(1)
    {
 //B_COLOR = color(7,14,7);
 //clear_lcd();
 
 //B_COLOR = color(30,0,0);
 F_COLOR = color(0,60,0);
 linechar_1608t(3,6,"This is char show\0");
 
 count_show(5,12,i);

 F_COLOR = color(0,60,0);
 SHOW_char(9,14,k);

 k=k+1;
 i=i+1;
 if(k-' '>=95)k=' ';
 if(i==50000)i=0;

 delay_ms(50); 
 
 B_COLOR = color(7,14,7);
 SHOW_char(9,14,' ');
 Clear_Line(3,6,18);
 Clear_Line(5,12,5);
 delay_ms(50);  
}
}



 

     

二战了!!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2012-11-19
在线时间
2 小时
 楼主| 发表于 2013-7-9 12:44:34 | 显示全部楼层
怎么不能发图片和附件???
二战了!!!
回复 支持 反对

使用道具 举报

9

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2012-11-19
在线时间
2 小时
 楼主| 发表于 2013-7-9 15:31:01 | 显示全部楼层
问题解决了,应该用mini版的font.h文件,横向的字库,旗舰版是纵向的
二战了!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-18 02:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表