【LCD】
问题:数据长度变短后,上次的长数据数据依然显示在末尾
解决:液晶一行可正常显示20个ASCII字符,可使用字符串空格的方式避免长数据对短数据的覆盖
LCD_DisplayStringLine(Line0, (unsigned char *)" hello lanqiao dasai");
// 解决字符串覆盖问题 (加空格)
LCD_DisplayStringLine(Line0, (unsigned char *)" www.xatu.edu.cn ");
【LCD】
问题:液晶格式化显示数据
解决:添加头文件"stdio.h",使用sprintf函数,利用%进行格式化输出
// 常用格式化类型:
%d 有符号十进制整数
%u 无符号十进制整数
%x 无符号十六进制数
%o 无符号八进制数
%e e指数科学计数法
%E E指数科学计数法
%s 字符串
%c 字符
%f 浮点数,默认显示6位小数
%.nf 浮点数,精确小数位数为n
%#x 无符号十六进制数加前缀0x
%#o 无符号八进制数加前缀0
%% 百分号
%5d 十进制整数,长度为5(右对齐,空格填充)
%05d 十进制整数,长度为5(右对齐,0填充)
%-5d 十进制整数,长度为5(左对齐,空格填充)
%+5d 十进制整数,长度为5(右对齐,空格填充,显示正负符号)
u8 display_buf[20];
// 格式化数据示例
sprintf((char *) display_buf, "%5dHz", 5000);
LCD_DisplayStringLine(Line3, display_buf);
sprintf((char *) display_buf, "%.5f", 3.1415926);
LCD_DisplayStringLine(Line4, display_buf);
sprintf((char *) display_buf, "%#X", 15);
LCD_DisplayStringLine(Line5, display_buf);
sprintf((char *) display_buf, "%o", 15);
LCD_DisplayStringLine(Line6, display_buf);
sprintf((char *) display_buf, "%+5d", -15);
LCD_DisplayStringLine(Line7, display_buf);
【LCD】
问题:精确控制字符显示位置
解决:液晶显示屏长320,宽240,共划分为10行,编号1~10(Line0~Line9),每行大小320*24像素,每个ASCII字符占16*24个像素(Fonts.h中已经定义,支持0x20到0x7E)
每行最多正常显示20个ASCII字符,共划分20列,编号1~20(0~19),整屏最多显示200字符
每一行的像素起点位置定义如下(lcd.h中可以找到)
#define Line0 0
#define Line1 24
#define Line2 48
#define Line3 72
#define Line4 96
#define Line5 120
#define Line6 144
#define Line7 168
#define Line8 192
#define Line9 216

可以使用LCD_DisplayChar()函数指定单个字符显示,参数依次为行参数、列像素参数、显示字符

对液晶每一行来说,液晶像素序号从右向左编号,依次为(左)319,318,317......0(右),指定列像素光标位置后,从当前像素位置开始向右写入字符,然后光标向右移动到一个下一像素位置
(可以理解为指定319,从319写到304;指定15,从15写到0),注意的是,如果指定的是0,写完0后,移动的下一位是319;如果指定大于319,比如330,依然会从319开始向右写
1个字符占用16*24个像素位置,先写一行像素的16个像素宽度,然后行像素位置加1,开始写下一行像素,直到24行全部写入,一个字符写入完成。
底层代码如下(在lcd.c中可以找到)
/*******************************************************************************
* Function Name : LCD_DrawChar
* Description : Draws a character on LCD.
* Input : - Xpos: the Line where to display the character shape.
* This parameter can be one of the following values:
* - Linex: where x can be 0..9
* - Ypos: start column address.
* - c: pointer to the character data.
* Output : None
* Return : None
*******************************************************************************/
void LCD_DrawChar(u8 Xpos, u16 Ypos, uc16 *c)
{
u32 index = 0, i = 0;
u8 Xaddress = 0;
Xaddress = Xpos;
LCD_SetCursor(Xaddress, Ypos);
for(index = 0; index < 24; index++)
{
LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */
for(i = 0; i < 16; i++)
{
if((c[index] & (1 << i)) == 0x00)
{
LCD_WriteRAM(BackColor);
}
else
{
LCD_WriteRAM(TextColor);
}
}
Xaddress++;
LCD_SetCursor(Xaddress, Ypos);
}
}
例如,图1中在第1行第7列显示字符‘D’,则行参数为Line0,列像素参数为319-16*6,显示字符为‘D’
LCD_DisplayChar(Line0, 319-16*6, 'D');
使用两种指定列像素方式显示一行字符示例:
u8 i = 0;
for(i=0; i<20; i++)
{
// 第一种显示方法
LCD_DisplayChar(Line1, 16*(20-i)-1, i+'0');
// 第二种显示方法
LCD_DisplayChar(Line2, 319-16*i, i+'0');
}
【LCD】
问题:高亮选中参数,或选中参数闪烁
解决:精确位置控制+背景颜色改变(LCD_SetBackColor、LCD_SetTextColor)
例如:在时钟参数调整中,要求在选择时、分、秒,分别高亮显示对应参数,示例程序中使用红色背景高亮显示
u8 upload_time[3] = {0, 1, 0};
H1 = upload_time[0] / 10;
H2 = upload_time[0] % 10;
M1 = upload_time[1] / 10;
M2 = upload_time[1] % 10;
S1 = upload_time[2] / 10;
S2 = upload_time[2] % 10;
u8 choose = 2;
u8 i = 6;
sprintf((char *)display_buf, " Setting ");
LCD_DisplayStringLine(Line3, display_buf);
if(choose == 1)
{
LCD_SetBackColor(Red);
LCD_SetTextColor(White);
}
LCD_DisplayChar(Line5, 319-16*(i+0), H1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+1), H2 + '0');
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayChar(Line5, 319-16*(i+2), '-');
if(choose == 2)
{
LCD_SetBackColor(Red);
LCD_SetTextColor(White);
}
LCD_DisplayChar(Line5, 319-16*(i+3), M1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+4), M2 + '0');
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayChar(Line5, 319-16*(i+5), '-');
if(choose == 3)
{
LCD_SetBackColor(Red);
LCD_SetTextColor(White);
}
LCD_DisplayChar(Line5, 319-16*(i+6), S1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+7), S2 + '0');
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);

选择参数闪烁的代码参考
u8 upload_time[3] = {0, 0, 0};
H1 = upload_time[0] / 10;
H2 = upload_time[0] % 10;
M1 = upload_time[1] / 10;
M2 = upload_time[1] % 10;
S1 = upload_time[2] / 10;
S2 = upload_time[2] % 10;
u8 choose = 1;
u8 i = 6;
u8 LCD_Blink = 0;
extern u8 Flag_200ms;
if(Flag_200ms)
{
Flag_200ms = 0;
LCD_Blink = ++LCD_Blink % 2;
}
sprintf((char *)display_buf, " Setting ");
LCD_DisplayStringLine(Line3, display_buf);
if(choose == 0)
{
LCD_DisplayChar(Line5, 319-16*(i+0), H1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+1), H2 + '0');
LCD_DisplayChar(Line5, 319-16*(i+2), '-');
LCD_DisplayChar(Line5, 319-16*(i+3), M1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+4), M2 + '0');
LCD_DisplayChar(Line5, 319-16*(i+5), '-');
LCD_DisplayChar(Line5, 319-16*(i+6), S1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+7), S2 + '0');
}
else if(choose == 1)
{
if(LCD_Blink == 0)
{
LCD_DisplayChar(Line5, 319-16*(i+0), H1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+1), H2 + '0');
}
else
{
LCD_DisplayChar(Line5, 319-16*(i+0), ' ');
LCD_DisplayChar(Line5, 319-16*(i+1), ' ');
}
LCD_DisplayChar(Line5, 319-16*(i+2), '-');
LCD_DisplayChar(Line5, 319-16*(i+3), M1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+4), M2 + '0');
LCD_DisplayChar(Line5, 319-16*(i+5), '-');
LCD_DisplayChar(Line5, 319-16*(i+6), S1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+7), S2 + '0');
}
else if(choose == 2)
{
LCD_DisplayChar(Line5, 319-16*(i+0), H1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+1), H2 + '0');
LCD_DisplayChar(Line5, 319-16*(i+2), '-');
if(LCD_Blink == 0)
{
LCD_DisplayChar(Line5, 319-16*(i+3), M1 + '0');
LCD_DisplayChar(Line5, 319-16*(i+4), M2 + '0');
}
else
{
LCD_DisplayChar(Line5, 319-16*(i+3), ' ');
LCD_DisplayChar(Line5, 319-1