用的是旗舰的板子,硬件没问题,下载历程验证过。
显示的位置,颜色没问题,但是字符不对,用的也是历程上的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);
}
}
|