潘多拉开发板有个小屏幕,并且提供了屏幕的驱动,所以我一直想着把这个屏幕用起来,最后把tshell输出到串口的内容最终也输出到屏幕上 最终成果如下
实现的过程如下
1.使能lcd
即打开 Enalbe LCD ,下面的Enalbe LCD_console 是我自己加的
2.测试lcd屏幕
在打开后lcd后,rt-studio 会提供一个 样例让你输出(自动添加到applitcations 下面),测试一下lcd是否可以正常使用
3.实现的思路
我这边有两种思路
1.在rt_kprintf 中将lcd中的内容输出到串口后,再输出到屏幕上
2.由第一种思路扩展,rt-thread中提供串口的接受和发送的回调函数,我们设置rt_kprintf使用串口的发送回调函数,在发送数据后,将数据打印在屏幕上
最终我选择了第一个方案,因为潘多拉串口没有实现发送的回调函数,以下是具体实现
3.1首先在 rtthread/src/kservice.c 中的rt_kprintf中添加如下
#ifdef BSP_USING_LCD_CONSOLE
if(lcd_show_flag){
shell_show_lcd(rt_log_buf);
}
#endif
其中#ifdef BSP_USING_LCD_CONSOLE 是我添加的lcd控制,lcd_show_flag 为1时,调用shell_show_lcd,这个函数会将串口发送的内容打印到屏幕上,为什么有了BSP_USING_LCD_CONSOLE ,还要加个lcd_show_flag来控制呢?
因为在开始rt_kprintf第一次被调用的时候,spi还没有被初始化,直接调用会导致报错,所以我在main中定义lcd_show_flag,并且调用main运行后,将lcd_show_flag置1。
3.2实现调用shell_show_lcd
#ifdef BSP_USING_LCD_CONSOLE
int lcd_x = LCD_START,lcd_y = LCD_START,size_font=16;
void shell_show_lcd(char *rt_log_buf){
char str[2] ={0};
if(rt_strcmp(rt_log_buf, "\x1b[2J\x1b[H")==0){
lcd_x = LCD_START,lcd_y = LCD_START;
lcd_clear(WHITE);
return ;
}
while(*rt_log_buf){
str[0] = *rt_log_buf;
//handle '\n'
if(str[0] == '\n'){
lcd_y = lcd_y + size_font - 1;
lcd_x = LCD_START;
rt_log_buf++;
//clear next line
if (lcd_y + size_font < LCD_H - size_font)
{
lcd_show_string(0, lcd_y + size_font , size_font, " ");
}
continue;
}
//handle '\r'
if(str[0] == '\r'){
lcd_x = LCD_START;
rt_log_buf++;
continue;
}
//hand del and backspace
if (str[0] == 0x7f || str[0] == 0x08){
lcd_x = lcd_x - (size_font/2 - 1);
if (lcd_x < LCD_START)
{
lcd_x = LCD_W - size_font / 2;
lcd_y -= size_font;
}
lcd_show_string(lcd_x, lcd_y , size_font, " ");
rt_log_buf++;
continue;
}
if (lcd_x > LCD_W - size_font / 2)
{
lcd_x =LCD_START;
lcd_y += size_font;
}
if (lcd_y > LCD_H - size_font)
{
lcd_y = lcd_x = LCD_START;
lcd_show_string(0, 0 , size_font, " ");
}
lcd_show_string(lcd_x, lcd_y , size_font, str);
lcd_x = lcd_x + size_font/2 - 1;
rt_log_buf++;
}
}
#endif
不到一百行代码,非常简单,我们逐步看一下
首先我们看最重要的一个函数
lcdshow_string,这个官方提供的,其函数原型如下
**x y 时你要输出的位置,size时字符的大小,fmt则是要输出的字符,其中size时限定16 24 32 的,其他的尺寸会报错
第2行 定义 x,y,以及字体大小font
第7-11行 处理clear指令,clear指令发送后,会输出”\x1b[2J\x1b[H”,我们在读到这串代码将屏幕清空,并将xy置0
第16-27行,处理\n,主要在处理完\n后我清空了下一行,主要时屏幕太小,很容易挤满,看不清输出到哪里了
第30-34行,处理 \r ,清楚当前行,重置x
第36-44行,处理 del 和 backspace ,计算回退的位置,并且用空格来填充
第52-61行,判断下一个字符是否会超过xy的边界值
第63-65行,输出字符,将x自增,并且继续处理下一个字符
以上就是我实现的过程。
原作者:KIMI_7569