数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 12892|回复: 31

[Arduino] 分享一个RAV4和卡罗拉车机VFD屏的U8g2驱动(Arduino / STM32)

[复制链接]
发表于 2020-1-21 20:41:07 | 显示全部楼层 |阅读模式
2020/1/23更新:增加支持U8x8(请重新下载压缩文件)

先上两张卡罗拉VFD屏的效果图,是U8g2和U8x8自带的示例。(点击可查看大图)

U8g2 Logo:



U8x8 GraphicsTest:


Arduino

一、安装:
这里是已经修改好的u8g2库,版本是2.27.5,直接下载然后在Arduino里选“项目->加载库->添加.zip库”就能安装,记得先删掉原来的U8g2。
U8g2-2.27.5.zip

安装好库以后,像其他屏幕一样使用就行。

二、构造函数:
1页缓冲占用256Byte内存,2页缓冲占用512Byte内存,全缓冲卡罗拉的需要1792Byte、RAV4的需要2048Byte。对于有多个SPI口的Arduino板,可以使用带2ND符号的构造函数来使用第二个SPI。
  1. /* 卡罗拉 U8g2 SPI0 */
  2. U8G2_GP1287AI_256X50_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  3. U8G2_GP1287AI_256X50_2_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  4. U8G2_GP1287AI_256X50_F_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  5. /* 卡罗拉 U8g2 SPI1 */
  6. U8G2_GP1287AI_256X50_1_2ND_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  7. U8G2_GP1287AI_256X50_2_2ND_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  8. U8G2_GP1287AI_256X50_F_2ND_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);

  9. /* RAV4 U8g2 SPI0 */
  10. U8G2_RAV4_253X63_1_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  11. U8G2_RAV4_253X63_2_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  12. U8G2_RAV4_253X63_F_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  13. /* RAV4 U8g2 SPI1 */
  14. U8G2_RAV4_253X63_1_2ND_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  15. U8G2_RAV4_253X63_2_2ND_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);
  16. U8G2_RAV4_253X63_F_2ND_3W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* reset=*/ 9);

  17. /* 卡罗拉 U8x8 SPI0 */
  18. U8X8_GP1287AI_256X50_3W_HW_SPI u8x8( /* cs=*/ 10, /* reset=*/ 9);
  19. /* 卡罗拉 U8x8 SPI1 */
  20. U8X8_GP1287AI_256X50_2ND_3W_HW_SPI u8x8( /* cs=*/ 10, /* reset=*/ 9);

  21. /* RAV4 U8x8 SPI0 */
  22. U8X8_RAV4_253X63_3W_HW_SPI u8x8( /* cs=*/ 10, /* reset=*/ 9);
  23. /* RAV4 U8x8 SPI1*/
  24. U8X8_RAV4_253X63_2ND_3W_HW_SPI u8x8( /* cs=*/ 10, /* reset=*/ 9);
复制代码



三、亮度调节:
这两个型号的屏幕原本支持1024级亮度,但是U8g2最多只能输入255,所以setContrast()每增加1级的亮度实际是增加了4级的亮度。
  1. /* 亮度调节 */
  2. u8g2.setContrast(255);
复制代码



四、节能模式:

在退出节能模式时会自动有1毫秒延时,等待屏幕内部振荡器稳定。
  1. /* 进入节能模式 */
  2. u8g2.setPowerSave(1);

  3. /* 退出节能模式 */
  4. u8g2.setPowerSave(0);
复制代码



五、注意事项:
1、这两种屏幕的逻辑供电和所有io均为3.3V,如果用5V的Arduino板(UNO、Leonardo之类的)驱动的话需要加电平转换(因为默认是推挽输出,所以最好是使用转换芯片或三极管,也可以自己修改程序为开漏输出,然后用两个电阻做电平转换)。
2、高压使能(屏幕PCB上的SLEEP或HVEN测试点)在U8g2里没有去控制,自己用一个io口去控制就行,高电平是开启,低电平是关闭。在打开以后建议等700毫秒左右,待灯丝完全加热以后再发显示数据,不然显示内容会有从暗变亮的过程,视觉效果会不太好。

EX、Arduino自己修改库的操作步骤:
1、首先下载这个压缩包,然后解压一下,得到“src”文件夹
arduino_u8g2_vfd驱动.zip
2、将“src\追加\U8g2lib.h”里的内容全部添加到库中“U8g2\src\U8g2lib.h”的最后:
(点击可查看大图)


3、将“src\追加\U8x8lib.h”里的内容全部添加到库中“U8g2\src\U8x8lib.h”的最后:


4、用“src\修改\U8x8lib.cpp”里的相应内容替换库中“U8g2\src\U8x8lib.cpp”内相应的行:
(第一组)

(第二组)

(第三组)

(第四组)


5、将“src\clib\直接放入\u8x8_d_futaba_vfd.c”复制到库中“U8g2\src\clib”文件夹内:


6、将“src\clib\追加\u8g2.h”里的相应内容添加到库中“U8g2\src\clib\u8g2.h”文件的相应位置:

(第一组)

(第二组)


7、将“src\clib\追加”文件夹里剩余几个文件的内容添加到库中“U8g2\src\clib”文件内相同文件名文件的最后:
(u8g2_d_memory.c)

(u8g2_d_setup.c)

(u8x8.h)


8、最后将库中“U8g2\src\clib\u8g2.h”开头的 //#define U8G2_16BIT 注译去掉,变为#define U8G2_16BIT,启用16bit模式支持大尺寸屏幕。


STM32

一、移植U8g2:


这里是官方的移植和使用示例:
https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform
https://github.com/olikraus/u8g2/wiki/u8g2setupc


最后附件里也有移植好并添加了VFD驱动的整个Keil工程

移植比较简单在这里就不细说了,不用修改什么东西,只需要添加就行。在编译的时候出现Error: L6406E: No space in execution regions with .ANY xxxxxxx的话建议切换到version6的编译器(如果是GCC可以启用垃圾收集):


不想使用version6编译器的话就需要手动删掉不需要的函数和字体,详细方法网上都有,在删除时需要注意保留u8g2_d_memory.c内下面这三个:
  1. uint8_t *u8g2_m_32_8_1(uint8_t *page_cnt);
  2. uint8_t *u8g2_m_32_8_2(uint8_t *page_cnt);
  3. uint8_t *u8g2_m_32_8_f(uint8_t *page_cnt);
复制代码



最后还需要添加SPI和GPIO回调函数(直接加到main.c里或新建一个文件都行):
  1. /* SPI回调 */
  2. uint8_t u8x8_byte_hw_spi_futaba_vfd(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  3. {
  4.   uint8_t *data;
  5.   switch (msg)
  6.   {
  7.   case U8X8_MSG_BYTE_SEND: // 每次需要SPI发送数据时会进入这里,arg_ptr为数据指针,arg_int为数据大小
  8.     data = (uint8_t *)arg_ptr;
  9.     for (uint8_t i = 0; i < arg_int; i++)
  10.     {
  11.       while (LL_SPI_IsActiveFlag_TXE(SPI1) == RESET)
  12.       {
  13.         //__NOP();
  14.       }
  15.       LL_SPI_TransmitData8(SPI1, *data);
  16.       data += 1;
  17.     }
  18.     while (LL_SPI_IsActiveFlag_BSY(SPI1) == SET)
  19.     {
  20.       //__NOP();
  21.     }
  22.     break;
  23.   case U8X8_MSG_BYTE_START_TRANSFER:
  24.     LL_GPIO_ResetOutputPin(SPI1_CS_GPIO_Port, SPI1_CS_Pin);
  25.     break;
  26.   case U8X8_MSG_BYTE_END_TRANSFER:
  27.     LL_GPIO_SetOutputPin(SPI1_CS_GPIO_Port, SPI1_CS_Pin);
  28.     break;
  29.   default:
  30.     return 0;
  31.   }
  32.   return 1;
  33. }
  34. /* GPIO回调 */
  35. uint8_t u8x8_gpio_and_delay_futaba_vfd(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
  36. {
  37.   switch (msg)
  38.   {
  39.   case U8X8_MSG_GPIO_AND_DELAY_INIT:
  40.     LL_SPI_Enable(SPI1);
  41.     break;
  42.   case U8X8_MSG_DELAY_MILLI:
  43.     LL_mDelay(arg_int);
  44.     break;
  45.   case U8X8_MSG_GPIO_RESET:
  46.     if (arg_int)
  47.       LL_GPIO_SetOutputPin(RST_GPIO_Port, RST_Pin);
  48.     else
  49.       LL_GPIO_ResetOutputPin(RST_GPIO_Port, RST_Pin);
  50.     break;
  51.   default:
  52.     u8x8_SetGPIOResult(u8x8, 1);
  53.     break;
  54.   }
  55.   return 1;
  56. }
复制代码




二、添加VFD驱动:
1、首先下载这个压缩包,然后解压一下,得到“csrc”文件夹
stm32_u8g2_vfd驱动.zip
2、之后的步骤和“Arduino自己修改库”的 5 到 8 步是相同的

三、支持的Setup函数:
1页缓冲占用256Byte内存,2页缓冲占用512Byte内存,全缓冲卡罗拉的需要1792Byte、RAV4的需要2048Byte。
  1. /* 卡罗拉 U8g2 */
  2. u8g2_Setup_futaba_vfd_gp1287ai_256x50_1(&u8g2, U8G2_R0, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);
  3. u8g2_Setup_futaba_vfd_gp1287ai_256x50_2(&u8g2, U8G2_R0, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);
  4. u8g2_Setup_futaba_vfd_gp1287ai_256x50_f(&u8g2, U8G2_R0, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);

  5. /* RAV4 U8g2 */
  6. u8g2_Setup_futaba_vfd_rav4_253x63_1(&u8g2, U8G2_R0, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);
  7. u8g2_Setup_futaba_vfd_rav4_253x63_2(&u8g2, U8G2_R0, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);
  8. u8g2_Setup_futaba_vfd_rav4_253x63_f(&u8g2, U8G2_R0, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);

  9. /* 卡罗拉 U8x8 */
  10. u8x8_Setup(&u8x8, u8x8_d_futaba_vfd_gp1287ai_256x50, u8x8_cad_empty, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);

  11. /* RAV4 U8x8 */
  12. u8x8_Setup(&u8x8, u8x8_d_futaba_vfd_rav4_256x50, u8x8_cad_empty, u8x8_byte_hw_spi_futaba_vfd, u8x8_gpio_and_delay_futaba_vfd);
复制代码



四、亮度调节:这两个型号的屏幕原本支持1024级亮度,但是U8g2最多只能输入255,所以SetContrast()每增加1级的亮度实际是增加了4级的亮度。
  1. /* 亮度调节 */
  2. u8g2_SetContrast(&u8g2, 255);
复制代码



五、节能模式:
在退出节能模式时会自动有1毫秒延时,等待屏幕内部振荡器稳定。注意:在调用InitDisplay()之后默认状态为进入节能模式,需要手动使用SetPowerSave(0)退出(参见上面的官方使用示例)
  1. /* 进入节能模式 */
  2. u8g2_SetPowerSave(&u8g2, 1);

  3. /* 退出节能模式 */
  4. u8g2_SetPowerSave(&u8g2, 0);
复制代码




六、注意事项:
1、高压使能(屏幕PCB上的SLEEP或HVEN测试点)在U8g2里没有去控制,自己用一个io口去控制就行,高电平是开启,低电平是关闭。在打开以后建议等700毫秒左右,待灯丝完全加热以后再发显示数据,不然显示内容会有从暗变亮的过程,视觉效果会不太好。





附件:
1、卡罗拉的显示面板PCB测试点和逻辑分析仪数据:
2、RAV4的逻辑分析仪数据:
3、在103C8上移植好U8g2的Keil(V5.29)示例工程:



萌新第一次发帖,如果有什么问题欢迎指出~


补充内容 (2020-1-23 15:54):
2020/1/23更新:增加支持U8x8,链接地址:https://docs.qq.com/doc/DTlp1akJUVlFVQW5r(原贴不能编辑了,就在文档里更新了)





相关阅读:玩点不一样的!卡罗拉车机VFD屏实现灰度显示:
https://www.mydigit.cn/forum.php?mod=viewthread&tid=196643

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 2家元 +40 收起 理由
人艰不拆了 + 20
jpdd521 + 20 打赏萌新,好评x2

查看全部打赏

 楼主| 发表于 2020-2-12 21:24:17 | 显示全部楼层
深渫 发表于 2020-2-5 09:18
好东西!  谢谢分享!

请教大神几个问题:

你好,不好意思一直没有上线,关于第二个问题用专业术语的话我有点解释不来... 不过通俗地讲就是在程序开头调用
  1. u8g2_Setup_futaba_vfd_gp1287ai_256x50_1(&u8g2, U8G2_R0, ......);
复制代码

的时候,通过里面的
  1. u8g2_SetupDisplay(u8g2, u8x8_d_futaba_vfd_gp1287ai_256x50, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
复制代码


  1. u8x8_d_futaba_vfd_gp1287ai_256x50
复制代码

这个函数的指针放到了u8g2_t这个结构体里面的u8x8结构体里的display_cb里面,然后在需要的时候直接调用display_cb并传入相应的消息(msg)和参数(arg)就可以执行相应的功能。
比如
  1. void u8x8_InitDisplay(u8x8_t *u8x8)
  2. {
  3.   u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);  
  4. }
复制代码

翻译一下其实就是
  1. void u8x8_InitDisplay(u8x8_t *u8x8)
  2. {
  3.   u8x8_d_futaba_vfd_gp1287ai_256x50(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);  
  4. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-24 10:59:29 | 显示全部楼层
lhn1324 发表于 2020-2-22 20:46
楼主厉害。
我手上一个非标分辨率的SSD1322驱动的OLED,可以用标准分辨率的配置点亮,但显示的坐标就有便宜 ...

你好,是x方向的偏移吗,如果是的话你看下在u8x8_d_ssd1322.c里有一个u8x8_ssd1322_128x64_display_info或者是u8x8_ssd1322_256x64_display_info,可以修改一下里面的default_x_offset和flipmode_x_offset试试,它现在里面默认有一点偏移。
如果是y方向的话可能要在初始化序列里面或者是在U8X8_MSG_DISPLAY_DRAW_TILE里改,具体怎么弄还需要你自己摸索一下,因为我也不是太懂(尴尬)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-3 22:27:10 | 显示全部楼层
nonzhe 发表于 2020-4-29 08:29
楼主,1页缓冲占用256Byte内存,2页缓冲占用512Byte内存,这个什么意思?怎么算1页呢? ...

对于256x50的屏幕来说,竖着8个像素、横着256像素这是一页,就是8x256/8=256Byte。u8g2可以选择每次绘制几页的内容,如果是_1的选项的话每次只绘制一页的内容,然后发送到屏幕,接着的绘制下一页再发送,重复7次,这样就可以节省内存,只用256Byte。_2同理,每次绘制2页,重复4次,占用512byte。如果是_f的话就是直接绘制一整屏,也就是占用1792Byte内存,但是这样速度是最快的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-6 11:12:27 | 显示全部楼层
cqs16800 发表于 2020-8-6 09:29
大神,能发一下完整的代码和接线方法吗?我用的是arduino 2560板子,rav4屏

首先需要注意的是就是rav4屏的电源和io都是3.3v的,但是2560板子用usb供电时芯片是5v的,直接连上会出问题。所以要么加一个电平转换,要么把整个2560板都用3.3v供电,或者最少也要把rav4屏用3.3v供电,然后再通过阻值大一点的电阻把剩下的数据线和5v的2560板连起来。

之后你就按照上面腾讯文档里最开始的步骤把改过的u8g2库装上,之后用和其他的屏幕一模一样了,唯一不同就是最开始的构造函数用那个U8G2_RAV4_253X63_xxxxxx就可以了。

接线的话把rav4屏的SCK(SerialClock)和MOSI(SerialDATA)直接连到2560板子上的SPI0上,剩下的cs和reset的引脚位置可以在构造函数里改,默认是10和9。最后如果你不需要控制屏的电源的话屏上的sleep直接接到3.3V电源上就行,如果要在程序里控制电源的话就把sleep接到一个IO上,然后高电平是开低电平是关。
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-8-6 11:25:33 | 显示全部楼层
suwill 发表于 2020-7-20 21:53
大神搞过185a车机的屏么?有pcb引脚定义,有51的例程,我想用esp8266+u8g2点亮它,请赐教

...

不好意思没有弄过,我刚看了51的程序,好像不是太麻烦,有时间我再看看吧,说实话我有点忘了当时是怎么弄的了...

打赏

参与人数 1家元 +20 收起 理由
jpdd521 + 20 非常厉害,悄悄在这里给你加MMM。非常厉害.

查看全部打赏

回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-3 18:37:54 来自手机浏览器 | 显示全部楼层
Loser_Zhou 发表于 2020-11-28 02:10
没有M币,下不了板子上的点位图,头大

您在1楼的最后看一下,有一个腾讯文档的链接,打开以后在最后的附件里有卡罗拉屏的测试点图,不需要M币。RAV4的测试点和其他的一些我也是看论坛里另一位大佬的,所以就没有往附件里放,只放了逻辑分析仪的数据。帖子链接是这个:bbs.mydigit.cn/read.php?tid=1311983 如果没有账号的话用百度搜一下帖子的标题,有一个其他网站的,里面也有图。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-18 14:34:34 | 显示全部楼层
陈海生 发表于 2021-10-14 16:44
老板这个能把后面的VFD屏拆下来单独再做个板子吗,会不会很麻烦?

麻烦倒不是很麻烦,不过PCB尺寸超过10*10了,打板的话没办法0元购
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-25 11:36 , Processed in 0.218400 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表