STM32F767 Nucleo之RT-GUI实验
STM32F767 Nucleo是ST官方出的开发板,板子上引出了大量的管脚便于评估。板子上还有一个带串口功能的ST Link调试器,用于对767芯片进行调试,一些基础功能的评估在这一块板子上就能搞定,不需要额外的开发工具了。
我在这块板子上用rt-gui实现了一个计算器,屏幕数据通过USB摄像头来显示,鼠标和键盘数据通过自定义USB HID设备传送给开发板。PC端显示程序运行后效果如下:
PC端是一个简单的Qt程序,一边读取摄像头数据进行显示,一边将鼠标和键盘事件通过HID设备发送给开发板。这个程序的源代码在这里。如果有多个摄像头,可以用PageDown和PageUp按键进行切换。开发板上的程序在这里,采用rt-gui制作界面,用F767的jpeg硬核进行图片压缩,通过开发板的USB接口发送到PC端。
设计过程
F767 Nucleo板提供的资源如下:
这块板子已经具备了全速USB接口和以太网接口。为了在这块板子上运行rt-gui并显示出来,我用USB摄像头的方式来显示屏幕数据。767芯片内置了JPEG压缩硬核,可以将屏幕数据先压缩后再通过USB以摄像头数据的形式发送到PC进行显示,降低带宽要求。
整个工程的设计思路如下
从左至右看,要做的主要功能是rt-gui和rt-thread,为了便于开发调试,我还需要SWD进行在线调试。
rt-gui的输入部分通过自定义USB HID设备来做,把电脑鼠标的点击事件和键盘事件通过HID接口发送到板子上。rt-gui的显示部分用USB摄像头UVC(USB Video Class)来做,将rt-gui的图像数据用摄像头的方式发送给PC。rt-gui绘制屏幕数据先进行JPEG压缩然后再发送,减轻全速USB接口的压力。
767有512K的RAM,我准备使用320×240的分辨率,颜色用RGB565格式,这样模拟屏幕需要320x240x2=150K字节的内存。
rt-thread在cortex-m7上有移植好的代码,拿过来用就行了。用一个LED指示工作状态,一个LED用来指示摄像头是否为打开状态。finsh通过板子上的ST Link串口进行交互。
从右往左看,这块板子提供了USB接口,JPEG硬件编解码,足够大的内存,有LED指示灯,板子上的STLink为我们提供了SWD调试功能和串口功能。基本满足了上面的功能需求。
两边都能对上,把需要的功能在CubeMX中进行初始化。CubeMX是ST针对他家的芯片做的一个图形化初始化应用程序,用来生成初始化代码很方便,这个也是官方以后主推的方式。
在CubeMX中配置好要用的外设后,就可以生成我们的工程基础文件了。在CubeMX的中间件(middleware)中,并没有我们想要的USB UVC+HID的复合设备,这里先选一个Audio设备来修改。因为Audio和Video读起来和写起来比较相近,估计改起来也不会太难。
其实这里选Audio设备是因为他和Video设备类似,都是用同步传输模式传输数据。实际在修改的过程中,如果是一个全新的设备类,用什么设备来做模板差别都不大,因为USB规范中不同的设备类操作差异很大。
做好了准备后就是移植rtthread代码到CubeMX生成的工程中,这里我建议把CubeMX生成的工程修改成rtthread的,因为cube生成的代码少于rtthread 的。如何整合可以在这里了解。
在GitHub上的rtthread的主线中,rt-gui部分没有widget的代码。在realboard-lpc4088工程中有widget的代码,为了方便开发,我fork了一个rtthread的主线,在里面添加了realboard中widget的代码。添加了widget的rtt代码在这里。计算器的按键我用图片做的,为了降低内存开销,我在rt-gui的框架下定义了一种新的图片格式image_mem。这种格式完全不占用内存,只占用Flash空间,显示时直接通过blit_line绘制到屏幕上。
为了方便在Qt中调试UI部分的效果,我在scons的工具中添加了生成qt工程文件的功能,目前通过scons只能生成Qt工程文件,还不能调用gcc对代码进行Qt风格的编译。
STM32F767的JPEG硬核只能对YUV,CMYK和GrayScale的颜色格式进行编解码,不能对通常的RGB格式直接进行。为了将RGB颜色空间转换成JPEG硬核支持的格式,ST提供了转换库。为了减少转换时间,我针对这个应用写了个特殊的转换函数,速度比通用库快一些。
完成了这些准备工作后,计算器程序看起来就很简单了。界面部分模拟的液晶屏用了一个自定义的LCD widget,按钮直接贴图,有抬起和按下两种效果。计算部分直接用双精度浮点数做内置数据类型,因为767片子内置了双精度的浮点数计算单元,直接用double型代码会非常简单。液晶屏显示8位有效数字,double可以保证15位有效数字,完全够用了。
C语言nucleortthreadSTM32
近期文章
近期评论
- Jaceeshen发表在《自己动手设计电路板-输出加工文件》
- feelingcode发表在《TeenyUSB问题反馈》
- jczheng发表在《USB Packet Viewer问题反馈》
- liuzq71发表在《STM32F767 Nucleo之RT-GUI实验》
- xtoolbox发表在《TeenyUSB问题反馈》
10 Responses
CZM says:
您好!
我想做一个PC(QT)和 STM32F767 通信的程序,上位机采用QT编写一个简单的界面,可以发送数据到767,请问有没有相关的资料。
非常感谢!
2018-10-01 at 22:35
xtoolbox says:
你好,你的767和上位机之间通过什么方式通讯,如果是i串口的话,Qt方面需要看关于Qt串口编程相关的资料,767方面需要串口操作的例程。
STM32的CubeMX可以直接生成能用串口程序,Qt这边也有很多的串口例程
2018-10-03 at 18:34
CZM says:
你好,767和上位机之间通过USB通讯,主要是需要这方面的例子。谢谢!
2018-10-18 at 19:18
xtoolbox says:
你好,关于767通过USB与PC机通讯,上位机程序可以参考
https://github.com/xtoolbox/teenyusb/tree/master/pc_test_tool
767中的固件可以参考
https://github.com/xtoolbox/teenyusb/tree/master/usb_stack
2018-12-05 at 15:42
liuzq71 says:
请问博主:这个程序的 UVC功能完整实现了么?
也想在stm32F7/H7上实现 UVC。谢谢
2020-03-01 at 11:12
xtoolbox says:
UVC只实现了很小一部分子集,只能传输固定帧率的jpeg图片数据。
2020-03-03 at 13:10
liuzq71 says:
stm32F676ZI-NUCLEO开发板插上电脑已经识别出了相机,但运行qcamera.exe时显示:
“HID device not found!
Input simulation not work”
是什么原因?谢谢
另外能给我你的QQ号么?
2020-04-03 at 15:15
liuzq71 says:
xtoolbox你好,
上面的这个问题已经找到原因是因为usbd_desc.c中的USBD_PID_FS被我改动了:
#define USBD_PID_FS 22336 + 1,
目前的问题是我想编译qt_camera但编译不过去,我用的是qt5.12.7,能给我你的QQ号么?谢
2020-04-04 at 07:08
xtoolbox says:
软件会通过VID和PID来查找设备,修改了PID会导致搜索失败,因此找不到HID设备。
2020-04-10 at 15:35
liuzq71 says:
你好,
在这个程序中的usbd_video.c的USBD_DataIn()函数中将JPEG图像数据发给上位机的,具体是:USBD_LL_Transmit(pdev, VIDEO_IN_EP, hvideo->video_buffer+hvideo->current_length, len);
想请教一下:在整个固件程序中,是哪里的一段代码将JPEG数据填充到hvideo->video_buffer这个内存地址上的?我没能找到,谢谢指出
2021-12-04 at 12:41