33 }
上面的程序会出现问题,原因是因为我们画点时对其余的位全部填0处理了,造成对原来的信息的破坏。所以我们要读出要写的那个地址原来的数据,再进行加工,写回去就可以解决问题了。
改进后的代码:
01 void lcd_set_dot(unsigned char x, unsigned char y) 02 {
03 unsigned char x_byet, x_bit; //在横坐标的哪一个字节,哪一个位 04 unsigned char y_ping, y_bit; //在纵坐标的哪一屏,哪一行
05 unsigned char tmph, tmpl; / /定义两个临时变量,用于存放读出来的数据 06 x &= 0x7F; //不太理解,不要行吗??????????、、?、、??
07 y &= 0x3F;
08 x_byte = x / 16; //算出它在哪一个字节(地址),注意一个地址是16位的
10 x_bit = x&0x0F; //算出它在哪一个位
11 Y_ping = y /32; //确定它在上半屏还是下半屏, 0:上半屏 1:下半屏
14 y_bit = y&0x3F; //y_bit确定它是在第几行
15 lcd_write_cmd(EXTEND_SET); //扩展指令集 16 lcd_write_cmd(DRAW_OFF); //绘图显示关闭
17 lcd_write_cmd(0x80 + y_bit); //先写垂直地址(最高位必须为1) 19
23 lcd_read_data(); //先空读一次?????????????这样做对吗??????? 24 tmph = lcd_read_data(); //读高位
25 tmpl = lcd_read_data(); //读低位
26 lcd_write_cmd(0x80 + y_bit); //读操作会改变AC,所以重新设置一次
lcd_write_cmd(0x80 + x_byte + 8 * y_ping); //水平坐标, 下半屏的水平坐标起始地址为0x88 , (+8*y_byte)就是用来确定在上半屏还是下半屏
27 lcd_write_cmd(0x80 + x_byte + 8 * y_ping);
28 if (x_bit < 8) //如果x_bit位数小于8 29 { 30
lcd_write_data(tmph | (0x01 << (7 - x_bit))); //写高字节。因为坐标是从左向右的,GDRAM高位在左,底位在右
32 lcd_write_data(tmpl); //原低位数据送回 33 } 34 else 35 {
36 lcd_write_data(tmph); //原高位数据送回
37 lcd_write_data(tmpl | (0x01 << (15 - x_bit))); 38 }
39 lcd_write_cmd(DRAW_ON); //打开绘图显示
40 lcd_write_cmd(BASIC_SET); //回到基本指令集,毕竟ST7920是以字符为主的
41 return ; 42 }
画点函数到此就完成了,剩下的事情就是对函数的优化了。例如对入口参数的检查,对乘除法的优化等等。
12864(绘图显示)画完一屏重画会出现花屏现象,解决办法 1.花屏原因:
带中文字库的LCD,使用图形模式时,应对所有GDRAM写0x00才算清屏,清屏命令是对使用自带字库显示时用的,对于画图不适用。 2.GDRAM清屏程序:
void LCD12864_DisplayCLR() {
uchar i, j, k ;
LCD12864_IfBusy();//忙标检测
LCD12864_WriteRom(0x34);//打开扩展指令集,8位数据传输
lcd_write_cmd(DRAW_OFF); //绘图显示关闭
for( i = 0 ; i < 2 ; i++ )//分上下两屏写 {
for( j = 0 ; j < 32 ; j++ ) {
LCD12864_IfBusy();
LCD12864_WriteRom( 0x80 + j ) ;//写Y坐标 Delay_50us(1);
if( i == 0 ) //写X坐标 {
LCD12864_WriteRom( 0x80 ) ; Delay_50us(1); }
else //写下半屏 {
LCD12864_WriteRom( 0x88 ) ; Delay_50us(1); }
for( k = 0 ; k < 16 ; k++ ) //写一整行数据 {
LCD12864_IfBusy();
LCD12864_WriteData(0x00);//写高字节 LCD12864_WriteData(0x00);//写低字节 Delay_50us(1); } } }
LCD12864_WriteRom(0x36);//打开扩展指令集,绘图显示开 LCD12864_WriteRom( 0x30 ) ;//关闭扩展指令集 }
如何在GDRAM写字!!!------用取模软件就行了,这里只是简单的说说方法!!!
—
从“壁画”记事到“甲骨文”---- 在GDRAM中写字就可把字当作图形显示!
四、关于CGRAM的使用:
CGRAM为使用者提供图像定义(造字)功能,可以提供四组16*16点的自定义图像空间,注意:网上说ST7920芯片同屏幕不能显示4个以上自定义汉字(用CGRAM)。显示CGRAM字型:将16位元资料写入DDRAM中,一共有0000H,0002H,0004H,0006H四种编码
操作步骤:
1>设置为扩充指令集;
2>设置SR=O(设定CGRAM地址的前提),允许设定CGRAM地址; 3>设置为基本指令集;
4>循环执行以下操作写入16个字节数据(设定CGRAM的存储地址;写入自定义数据);
5>设置DDRAM地址 6>写入显示CGRAM显示码
也就是说只有后六位是CGRAM的地址范围是00 0000(0x00)-11 1111(0x3F),整个字节也就是0x40-0x7F,这就是CGRAM地址的范围,在进行设置CGRAM字库的过程中,进行的有如下三句操作,也就是在设置CGRAM地址时是在SR=0有效时进行的,SR=0,也就表
明是对CGRAM地址的设置,依此来区分是设置的DDRAM地址或CGRAM地址; LcdWcom(0x34); //再次设置为8位并行口,扩展指令集 LcdWcom(0x02); //SR=0,允许设置CGRAM地址
LcdWcom(0x30); //恢复设置为8位并行口,基本指令集
你写入的数据编码分为三种:一种是一个字节的HCGROM,也就是字符;一种是两字节的CGROM,也就是内部的中文汉字字库;最后一种就是两字节的CGRAM,也就是你自己造的字库;
具体的编码是这样的:
如果你第一个字节写入DDRAM的内容在0x02-0x7F之间,那么就会认为你要写入的是HCGROM编码;
如果你第一个字节写入DDRAM的内容不在0x02-0x7F之间,在0xA1之上的,那就认为是CGROM编码,接收第二个字节,然后组合在一块显示出汉字;
如果你第一个字节写入DDRAM的内容不属于以上的范围那自然就是CGRAM编码了,接收第二个字节,然后组合在一块显示出自造的16*16的字符;
另外还对CGRAM的编码有详细的规定,只能是0x0000,0x0002,0x0004,0x0006四种编码,对应的是CGRAM中你写入的0x40-0x7F范围的数据,0x40-0x7f正好是4个16*16(每个地址两个字节数据2*8)的数据。
所以你调用的时候,像显示汉字一样,先写入所要显示的地址位置,然后写入两个字节的CGRAM编码即可(对应下面的显示程序),至于为什么定义0x0000,0x0002,0x0004,0x0006对应为CGRAM里面相应自造字的编码,这我也还不明白,我想我们也没有必要了解的这么深。