这次试用开发板,准备不使用串口来反馈,采用LCD屏来显示。LCD屏在初始化硬件后,最常见的就是画点,所有的显示都是基于这个函数来展开的(注:这是初学阶段,如果要加快显示速度,需要用到一次性写入buff)。
要画点,首选要定位到坐标,函数下如:
/**
* [url=home.php?mod=space&uid=2666770]@Brief[/url] 设置光标位置(对 RGB 屏无效)
* [url=home.php?mod=space&uid=3142012]@param[/url] x,y: 坐标
* @retval 无
*/
void lcd_set_cursor(uint16_t x, uint16_t y)
{
if (lcddev.id == 0X1963)
{
if (lcddev.dir == 0)/* 竖屏模式, x 坐标需要变换 */
{
x = lcddev.width - 1 - x;
lcd_wr_regno(lcddev.setxcmd);
lcd_wr_data(0);
lcd_wr_data(0);
lcd_wr_data(x >> 8);
lcd_wr_data(x & 0XFF);
}
else
/* 横屏模式 */
{
lcd_wr_regno(lcddev.setxcmd);
lcd_wr_data(x >> 8);
lcd_wr_data(x & 0XFF);
lcd_wr_data((lcddev.width - 1) >> 8);
lcd_wr_data((lcddev.width - 1) & 0XFF);
}
lcd_wr_regno(lcddev.setycmd);
lcd_wr_data(y >> 8);
lcd_wr_data(y & 0XFF);
lcd_wr_data((lcddev.height - 1) >> 8);
lcd_wr_data((lcddev.height - 1) & 0XFF);
}
else if (lcddev.id == 0X5510)
{
lcd_wr_regno(lcddev.setxcmd);
lcd_wr_data(x >> 8);
lcd_wr_regno(lcddev.setxcmd + 1);
lcd_wr_data(x & 0XFF);
lcd_wr_regno(lcddev.setycmd);
lcd_wr_data(y >> 8);
lcd_wr_regno(lcddev.setycmd + 1);
lcd_wr_data(y & 0XFF);
}
else/* 9341/5310/7789 等 设置坐标 */
{
lcd_wr_regno(lcddev.setxcmd);
lcd_wr_data(x >> 8);
lcd_wr_data(x & 0XFF);
lcd_wr_regno(lcddev.setycmd);
lcd_wr_data(y >> 8);
lcd_wr_data(y & 0XFF);
}
}
实现将 LCD 的当前操作点设置到指定坐标(x,y)后,我们就可以住这个点进行像素填充了:
/**
* @brief 画点
* @param x,y: 坐标
* @param color: 点的颜色(32 位颜色,方便兼容 LTDC)
* @retval 无
*/
void lcd_draw_point(uint16_t x, uint16_t y, uint32_t color)
{
lcd_set_cursor(x, y);/* 设置光标位置 */
lcd_write_ram_prepare();/* 开始写入 GRAM */
LCD->LCD_RAM = color;
}
就是先设置坐标,然后往坐标写颜色。lcd_draw_point 函数虽然简单,但是至关重要,其他几乎所有上层函数,都是通过调用这个函数实现的。
字符显示函数 lcd_show_char,该函数同前面 OLED 模块的字符显示函数
差不多,但是这里的字符显示函数多了 1 个功能,就是可以以叠加方式显示,或者以非叠加方
式显示。叠加方式显示多用于在显示的图片上再显示字符。非叠加方式一般用于普通的显示。
该函数实现代码如下:
/**
* @brief 在指定位置显示一个字符
* @param x,y : 坐标
* @param chr : 要显示的字符:" "--->"~"
* @param size : 字体大小 12/16/24/32
* @param mode : 叠加方式(1); 非叠加方式(0);
* @retval 无
*/
void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size,
uint8_t mode, uint16_t color)
{
uint8_t temp, t1, t;
uint16_t y0 = y;
uint8_t csize = 0;
uint8_t *pfont = 0;
/* 得到字体一个字符对应点阵集所占的字节数 */
csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
/* 得到偏移后的值(ASCII 字库是从空格开始取模,所以-' '就是对应字符的字库) */
chr = chr - ' ';
switch (size)
{
case 12:
pfont = (uint8_t *)asc2_1206[chr];/* 调用 1206 字体 */
break;
case 16:
pfont = (uint8_t *)asc2_1608[chr];/* 调用 1608 字体 */
break;
case 24:
pfont = (uint8_t *)asc2_2412[chr];/* 调用 2412 字体 */
break;
case 32:
pfont = (uint8_t *)asc2_3216[chr];/* 调用 3216 字体 */
break;
default:
return ;
}
for (t = 0; t < csize; t++)
{
temp = pfont[t];
/* 获取字符的点阵数据 */
for (t1 = 0; t1 < 8; t1++)
/* 一个字节 8 个点 */
{
if (temp & 0x80)
/* 有效点,需要显示 */
{
lcd_draw_point(x, y, color);
/* 画点出来,要显示这个点 */
}
else if (mode == 0)
/* 无效点,不显示 */
{
/* 画背景色,相当于这个点不显示(注意背景色由全局变量控制) */
lcd_draw_point(x, y, g_back_color);
}
temp <<= 1;
/* 移位, 以便获取下一个位的状态 */
y++;
if (y >= lcddev.height)return;/* 超区域了 */
if ((y - y0) == size)/* 显示完一列了? */
{
y = y0; /* y 坐标复位 */
x++;
/* x 坐标递增 */
if (x >= lcddev.width)return;/* x 坐标超区域了 */
break;
}
}
}
}
有了画点以及字符串显示函数,以后就不需要接串口进查看信息的。下一篇将正式入手开发板实操。
更多回帖