Visual Studio是一款非常出色的编程工具,其出色的代码高亮以及便捷的调试工具大大提高了程序员的开发效率。在性能上,VS可以说是完全碾压Keil或IAR。
对于嵌入式编程,有一款软件Visual GDB,配合VS,便于开发嵌入式设备,相当方便。包括ESP,STM32甚至树莓派等设备都可以通过这个插件用VS进行编程。本文通过建立STM32 HAL库工程以及移植一款128*128的TFT LCD来了解该插件的用法及HAL库的简单应用。
软件:Visual Studio 2017 + Visual GDB
平台:STM32F042 Nucleo-32开发板
库:HAL库文件
功能:Nucleo板载资源使用+1.44寸TFT移植
在库的选择上,由于我们用的是STM32F042K6,因此我们有如下选择:
标准库 |
HAL库 |
mbed |
标准库在stm32f1和f4系列有丰富的教程,而mbed作为主打物联网方向对底层屏蔽相当多,接近arduino的风格,同时资料也不算多。而HAL库作为硬件抽象层,在ST官方自F7之后仅支持HAL库开发,号称效率比标准库高。本着学(wan)习(wan)的态度,故选择HAL库作为本次实验的库版本。
关于HAL库ST官方的STM32 CubeMax 工具可以方便生成工程模板,可以通过该软件生成模板后选择VS开发,网上也有例程。本人仅用该软件下载HAL库,提取其中的对应板子STM32F042 Nucleo-32的BSP资源进行使用。若无此需求,通过GDB可直接生成工程模板无需其他软件。同时mbed也可直接由VS新建。
Visual GDB官网:https://visualgdb.com/
*本文不再累述如何配置,参照官网教程即可。
参考官网教程:https://visualgdb.com/tutorials/arm/texane-stlink/
新建项目时选择左侧的 Visual GDB,选择 Embedded Project Wizard,然后填好名称、路径。注意更改名称时,解决方案名称也会一并修改,但是若只改变解决方案名称时,名称不会一起修改。
选择型号,我的单片机型号为STM32F042K6,按如图选择即可。若无此型号可以点击右方进行下载。
我们选择HAL库例程。这个例程为LED闪烁,可以从ST官网下载Nucleo的电路图来进行配置。
最后,点击完成,建立好工程。注意ST-Link驱动是否安好,可以通过GDB进行下载安装。JTAG同理。由于Nucleo本身自带ST-Link,故无需外部连接。
点开LEDBlink.cpp 即可看到main函数。
由于Nucleo为官方的Demo,因此板载资源也有官方的测试程序。
选择我们在Cube里安装Packages的路径,\Packages\STM32Cube_FW_F0_V1.9.0\Drivers\BSP\STM32F0xx_Nucleo_32 找到对应板子的BSP文件夹,里面有.c和.h文件,将整个文件夹复制到刚才建好的目录下,准备添加这些文件。
添加H文件路径。在工程中,选择 项目 -> xxx属性 此处xxx一定为项目名称,若未出现xxx则点一下工程内部文件再去尝试。
找到如图位置,编辑。
新建 -> 选择 -> 添加 即可。
最后,在资源中添加已有文件,并将头文件包含,即可调用官方BSP资源了。
淘宝购买的 QDtech_1.44串口模块_ST7735 ,配套资料丰富,包括C51,Arduino以及STM32教程。不过其STM32例程为STM32F103版本,使用标准库开发。通过移植该例程来适配我们的设备。
移植之前,先讨论速度问题。
F103主频72Mhz,F042主频48Mhz,差别较大,慢了很多。因此,在us级别的延时,F042受限严重。若采用滴答定时器每1us产生一次中断,速度将大大降低。而在移植屏幕的过程中,并未使用微秒级别的延时,故采用HAL库本身毫秒级别的延时替换原使用的延时即可。
#define delay_ms HAL_Delay
另外,由于会重复包含头文件,我们需要提前先将屏幕的头文件修改好,格式可以如下:、
#ifndef __XXX_H
#define __XXX_H
//Your Code
#endif
此外,由于在VS中,我们用的实际上为C++,在链接的过程使用到.c文件,若未经处理,则很容易报错:
undefined reference to ......
因此我们在包含头文件时要如下处理:
extern “C”{
#include “OOXX.h”
}
当然,参照VS例程里面,我们也可以这样做,以更好的适应.c或.cpp环境:
#ifdef __cplusplus
extern "C" {
#endif
//Your Code
#ifdef __cplusplus
}
#endif
处理好之后,根据添加BSP资源的经验,如此移植屏幕的库。不过需要注意修改GPIO以及其初始化函数,改为HAL库的函数,包括头文件也需改为HAL库的头文件。由于修改的软件模拟的SPI,因此还要修改对应的GPIO引脚,保证板子可以驱动屏幕。我的GPIO修改如下:
#define LCD_GPIO_PORT GPIOB
#define LCD_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define LCD_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
#define TFT_GPIO_CLK_ENABLE(__INDEX__) do {LCD_GPIO_CLK_ENABLE(); } while(0)
#define TFT_GPIO_CLK_DISABLE(__INDEX__) LCD_GPIO_CLK_DISABLE()
#define LCD_CTRL GPIOB //定义TFT数据端口
#define LCD_LED GPIO_PIN_0 //D3 --->> TFT --BL
#define LCD_RS GPIO_PIN_1 //D6 --->> TFT --RS/DC
#define LCD_CS GPIO_PIN_4 //D12 --->> TFT --CS/CE
#define LCD_RST GPIO_PIN_5 //D11 --->> TFT --RST
#define LCD_SCL GPIO_PIN_6 //D5 --->> TFT --SCL/SCK
#define LCD_SDA GPIO_PIN_7 //D4 --->> TFT --SDA/DIN
其他修改想见附件,不再一一列举。
最后罗列下main函数。
#include
#include
#include
#include
#include "stm32f0xx_nucleo_32.h"
#include "sys.h"
#include "QDTFT_demo.h"
#include "Lcd_Driver.h"
#include "GUI.h"
//#include "Picture.h"
#ifdef __cplusplus
extern "C"
#endif
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
int main(void)
{
int cnt = 0;
char Num[3];
HAL_Init();
Lcd_Init(); //LCD初始化
LCD_LED_SET; //通过IO控制背光亮
BSP_LED_Init(LED3);//BSP初始化
Lcd_Clear(RED);
for (;;)
{
BSP_LED_Toggle(LED3);
cnt++;
//sprintf(Num,"%d",cnt);
//Gui_DrawFont_GBK16(0,20,BLUE,RED,(u8*)Num);
QDTFT_Test_Demo(); //测试
}
}
可以将 QDTFT_Test_Demo(); 函数注释掉,把累加显示解注释观察速度问题。因为容量有限无法同时运行。
在这个移植中,FLASH占用相当大,32K能用到近90%。因此实用性并不高。由于本人能力有限无法优化的更完美。同时该屏幕最少只需4根线即可驱动。
对于VS,还有很多快捷键。
运行: F5
单步调试: F10
注释: 先CTRL+K,然后CTRL+C
取消注释: 先CTRL+K,然后CTRL+U
https://www.cnblogs.com/herenzhiming/articles/5067879.html
https://blog.csdn.net/u011511601/article/details/71698563
https://blog.csdn.net/super828/article/details/79600206
HAL库相关资料文章
https://blog.csdn.net/buchunjiedexin/article/details/50405351
https://blog.csdn.net/zcshoucsdn/article/details/54613202
https://blog.csdn.net/zcshoucsdn/article/details/55213616
附件:过段时间共享