正点原子学习小组
直播中

华仔stm32

3年用户 2891经验值
擅长:嵌入式技术
私信 关注
[资料]

【正点原子STM32精英V2开发板体验】学习使用LCD画点以及显示字符函数

这次试用开发板,准备不使用串口来反馈,采用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;

}

}

} 

}

有了画点以及字符串显示函数,以后就不需要接串口进查看信息的。下一篇将正式入手开发板实操。

更多回帖

发帖
×
20
完善资料,
赚取积分