任务介绍
2025 Make Blocks第一期的任务包括嵌入式微控制器和HMI(人机接口),其实对于一个完整的应用,控制与人机交互的必不可少的,本次我们也是要完成这两方面的设计,这次6期最终想要完成的一个应用是有关热成像方面的,肯定是要有个主控的嵌入式芯片,并能正常的显示热成像,所以第一阶段的任务正好是我们要实现这个内容的必须模块,主控单元与交互单元。
模块功能介绍
由于本次的设计具有一定阶段性(共6期,12个主题),所以我们对于未使用的引脚暂时不进行处理,根据整个活动的不断进展,通过在上期模块基础上不断升级来添加任务主题。
本次任务的功能模块一共有两部分:
第一部分是主控单元,这里我们选择的是市场上非常成熟的嵌入式产品——STM32F103VCT6,其具有丰富的接口能够让我们可以更好的应对后面的内容扩展,通过搭建单片机最小系统使其能够正常工作,这里我们通过USB进行供电,在通过一个可控LED进行系统运行展示(例如blink,主要进行阶段性功能测试),主控单元还包括时钟电路,复位电路、SWD调试接口等等;
第二部分是人机交互模块,包括一个TFT显示屏以及一个多功能按键作为媒介。
模块硬件介绍
本次所使用的主要硬件是STM32F103VCT6,选择这个器件的主要原因是成熟可靠,带有FSMC功能,这个功能是我们本次驱动显示屏的主要接口;
显示屏采用的是8位并口驱动,通过FPC作进行连接;
交互控制部分使用的是六脚拨轮进行控制,这样我们就可以用一个器件实现三个输入;
显示部分除了显示屏外,还增加了一个三色灯作为状态显示;
其他硬件比如晶振采用的16M的外部金针,复位电路,下载接口使用的是1.27mm间距的插母等等
设计框图
设计框图主要是两个模块之间的交互关系,如下:
原理图和PCB模块介绍

原理图

PCB
本次属于第一阶段设计,主要功能是能实现主控单元的控制,以及交互单元的控制。为了单片机的正常运行本阶段通过USB进行供电,不过USB过来的是5V,单片机的供电要求是3.3V,所以在供电的地方还需要LDO进行转换。然后就是晶振电路、复位电路、调试电路等最小系统基本电路。USB接口进行了接口保护,增加了TVS等保护器件,同时供电引脚增加保险进行安全保护。
交互单元包括TFT接口以及TFT的背光控制,按键的输入等内容。
PCB设计过程中需要注意,首先是板子版型选择,一般可以直接是长方形或者其他规矩图形,我在长方形的基础上进行了扩展,主要是为了保护按键、USB口等突出器件,通过屏幕的安放合理放置FPC接口并以此为基准进行器件的布局,首先需要考虑的就是USB、按键、接口等器件的位置,注意相关器件不要干涉。然后就是布线的先后顺序了,先进行重要线路的布置,比如TFT的并口数据线、USB数据线、复位线等等,相对来说电源相关线不着急。接下来就是覆铜了,本次选择了中间位置进行覆铜操作,覆铜接地,通过打孔的方式对重要线路进行了保护。
本次设计增加了一个供电指示灯,当整个系统有电的时候电量,不受单片机的控制,还有一个三色灯,有单片机进行控制,用于验证单片机系统的可用性。本次选择的单片机为STM32F103VCT6,100pin,所以还有很多的引脚没有使用,目前暂时不处理。

3D效果图
软件调试
本次的软件调试主要是基础功能调试,看一下程序是否能够正常下载运行,然后实现一下TFT显示屏的控制,本次使用的调试软件是MDK,使用STM32CubeMX进行初始化代码的生成,我们这次用的是STM32F103,实际上用原先的基础库也是可以进行调试的。本次主要进行了两个方面的程序测试。
第一个就是最开始程序下载环节以及最基本的LED灯的控制(实际上就是GPIO输出的测试),主要验证一下程序是否能够正常运行,在while中实现三个灯的循环点亮:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOE, LED_R_Y_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, LED_B_R_Pin, GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOE, LED_B_R_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, LED_G_G_Pin, GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOE, LED_G_G_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOE, LED_R_Y_Pin, GPIO_PIN_RESET);
HAL_Delay(500);
}
接下来就是TFT屏幕的控制,这里我们用的了一个比较高级的功能——FSMC,需要先通过MX进行基本功能的配置:

配置其实并不复杂,主要是需要和我们使用的引脚关联对,接下来就是代码接口的适配了:
#define TFT_COMM_ADD *((volatile uint8_t *)0x60000000)
#define TFT_DATA_ADD *((volatile uint8_t *)0x60010000)
#define TFT_WR_COMM(cmd) {TFT_COMM_ADD = cmd;}
#define TFT_WR_DATA(data) {TFT_DATA_ADD = data;}
我们要做的就是命令和数据的发送,然后就要对屏幕进行初始化操作:
void App_tft_init(void)
{
// TFT_SPICS_RESET;
//------------------ST7789H ResetSequence-------------------------------------//
TFT_RESET_SET;
DelaySysTick_ms (10); //Delay 1ms
TFT_RESET_RESET;
DelaySysTick_ms (10); //Delay 1ms
TFT_RESET_SET;
DelaySysTick_ms (120); //Delay 120ms
// //--------------------End ST7789H ResetSequence ------------------------------//
TFT_WR_COMM(0x11); //Sleep out
DelaySysTick_ms (120); //Delay 120ms
TFT_WR_COMM (0xc1);
TFT_WR_DATA(0x02);
TFT_WR_DATA(0x02);
TFT_WR_DATA(0x02);
TFT_WR_COMM (0x04);
TFT_ID[0] = TFT_DATA_ADD;
TFT_ID[1] = TFT_DATA_ADD;
TFT_ID[2] = TFT_DATA_ADD;
TFT_ID[3] = TFT_DATA_ADD;
TFT_WR_COMM(0x36);
TFT_WR_DATA(0x00);
TFT_WR_COMM(0x3A);
TFT_WR_DATA(0x05);
TFT_WR_COMM(0x51);
TFT_WR_DATA(0x00);
//---ST7789V Frame rate setting------//
TFT_WR_COMM(0xb2);
TFT_WR_DATA(0x0c);
TFT_WR_DATA(0x0c);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0x33);
TFT_WR_DATA(0x33);
TFT_WR_COMM(0xb7);
TFT_WR_DATA(0x72);
TFT_WR_COMM(0xbb);
TFT_WR_DATA(0x1c);
TFT_WR_COMM(0xC0);
TFT_WR_DATA(0x2C);
TFT_WR_COMM(0xC2);
TFT_WR_DATA(0x01);
TFT_WR_COMM(0xC3);
TFT_WR_DATA(0x0b);
TFT_WR_COMM(0xC4);
TFT_WR_DATA(0x20);
TFT_WR_COMM(0xC6);
TFT_WR_DATA(0x0F);
TFT_WR_COMM(0xD0);
TFT_WR_DATA(0xA4);
TFT_WR_DATA(0xA1);
TFT_WR_COMM(0x3A);
TFT_WR_DATA(0x05);
//--------------------------------ST7789S gamma setting------------------------------
TFT_WR_COMM(0xe0);
TFT_WR_DATA(0xd0);
TFT_WR_DATA(0x06);
TFT_WR_DATA(0x0b);
TFT_WR_DATA(0x0a);
TFT_WR_DATA(0x09);
TFT_WR_DATA(0x06);
TFT_WR_DATA(0x2f);
TFT_WR_DATA(0x44);
TFT_WR_DATA(0x45);
TFT_WR_DATA(0x18);
TFT_WR_DATA(0x14);
TFT_WR_DATA(0x14);
TFT_WR_DATA(0x27);
TFT_WR_DATA(0x2d);
TFT_WR_COMM(0xe1);
TFT_WR_DATA(0xd0);
TFT_WR_DATA(0x06);
TFT_WR_DATA(0x0b);
TFT_WR_DATA(0x0a);
TFT_WR_DATA(0x09);
TFT_WR_DATA(0x05);
TFT_WR_DATA(0x2e);
TFT_WR_DATA(0x43);
TFT_WR_DATA(0x45);
TFT_WR_DATA(0x18);
TFT_WR_DATA(0x14);
TFT_WR_DATA(0x14);
TFT_WR_DATA(0x27);
TFT_WR_DATA(0x2d);
TFT_WR_COMM(0x21);
TFT_WR_COMM(0x35);
TFT_WR_DATA(0x00);
TFT_WR_COMM(0x44);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0x00);
TFT_WR_COMM(0x11);
DelaySysTick_ms (120);
TFT_WR_COMM(0x36);
TFT_WR_DATA(0x40); //0x08
X_offest = 0;
Y_offest = 0;
// TFT_WR_COMM(0x36);
// TFT_WR_DATA(0xC0);
// X_offest = 0;
// Y_offest = 80;
TFT_WR_COMM(0x29);
TFT_WR_COMM(0x2a);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0xEf); //EF
TFT_WR_COMM(0x2b);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0x00);
TFT_WR_DATA(0x01);
TFT_WR_DATA(0x3f);
TFT_WR_COMM(0x2C);
TFT_Clear(BLACK);
DelaySysTick_ms (20);
TFT_BL_SET;
Draw_ContinueChar16(48,60,"2025 Make Block",Acidblue_02,BLACK,0);
}
功能展示
心得体会
在阶段2的实现阶段时间上一个是对前面硬件设计电路的验证,也是软件设计的一个挑战,对应的功能根据一开始的硬件定义不断进行软件编程,也是一个非常有成就感的事情,不过遇到的问题也会更多,自定义设计的产品软件也是需要定制的,所有需要的时间也会长一点,不过这些也都是基础,后面的添加的功能都需要这两个模块进行展示,本次只是进行了基础功能的实现,主要是为了能够进行基本驱动,后续的应用就可以不断增加优化了,新的一期也已经出了,加油!