X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
DigiKey得捷技术专区
[作品提交] 3D打印机控制器项目
caxfan
2022-11-5 20:45
楼主
# 3D打印机控制器项目 ##作品简介 基于开源3D打印机系统Smoothieware V2.0移植到STM32F7508-DK的项目。硬件采用STM32F7508-DK作为主控制器及UI显示,ESP32作为WIFI设备通过USART进行通讯的3D打印机控制系统。具有高度模块化,可根据需求改变附件实现CNC,激光雕刻,绘图等多种功能。 ###系统框图
###程序框架
##各部分功能说明 ###硬件 1.STM32F7508-DK探索板是为基于STMicroelectronics Arm® Cortex®-M7内核的STM32F750N8H6微控制器而设计的一个完整的演示和开发平台。该微控制器具有 - 四个I2C、六个具有三个复用单工I2S的SPI、SDMMC、四个USART、四个UART、两个CAN、三个12位ADC、两个12位DAC、两个SAI、8到14位的数字相机模块接口、 - 内部320+16+4-Kb的SRAM和64-Kb的闪存、 - USB OTG HS和FS、以太网MAC、FMC接口、Quad-SPI接口、SWD调试支持。 板上的全系列硬件特性可帮助用户评估几乎所有外设 - USB OTG HS和FS、 - 10/100-Mbit以太网、 - microSD™卡、 - USART、 - 带音频输入和输出插孔的SAI立体声音频DAC、 - ST-MEMS数字麦克风、 - SDRAM(美光128Mb的MT48LC4M32B2,能够使用8MB)、 - Quad-SPI闪存(美光16MB的N25Q128A)、 - 带电容式多点触摸板的4.3英寸彩色LCD-TFT(480X272)、 - SPDIF RCA输入等)和开发其应用。 - Arduino™ Uno V3连接器可轻松连接用于用户特定应用的扩展板或子板。 - 集成的ST-LINK/V2-1提供了用于STM32的嵌入式在线调试器和编程器。
!
! 2.ESP32-S3 是一款低功耗的 MCU 系统级芯片 (SoC),支持 2.4 GHz Wi-Fi 和低功耗蓝牙 (Bluetooth® LE) 双模无线通信。芯片集成了 Xtensa® 32 位 LX7 双核处理器、超低功耗协处理器、Wi-Fi 基带、蓝牙基带、RF 模块以及外设。芯片的功能框图如下图所示。
###软件 #### Smoothie简介 Smoothie原平台是使用STM32H745芯片基于FreeRTOS嵌入式操作系统的GCC平台软件,包含FatFS文件系统,PID温度控制,开源,高度模块化,高性能G代码解释器和用面向对象的C++编写的CNC,3D打印机,激光切割控制器。具有可伸缩灵活配置,可靠,易维护的特点。
#### FreeRTOS简介 FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。
#### LVGL简介 LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素,美丽的视觉效果和低内存占用。LVGL的项目作者是来自匈牙利首都布达佩斯的 Gábor Kiss-Vámosi 。Kiss 在2016年将其并发布在 GitHub 上。当时叫 LittlevGL而不是LVGL,后来作者统一修改为 LVGL。 像一般的开源项目的那样,它是作为一个人的项目开始的。 从那时起,陆续有近 100 名贡献者参与了项目开发,使得 LVGL 逐渐成为最受欢迎的嵌入式图形库之一。
由于STM32F7508N芯片内部FLASH只有区区的64KB,而且内置RAM只有320K,对于项目来说,两者都不够,必须使用外部FLASH及外部SDRAM。本来尝试过混合模式,对于单单FreeRTOS+LVGL还可以成功,但是增加Smooth模块后内置FLASH空间就不够了,估计是C++的支持运行库太大。只能采用Bootloader加APP方式,Bootloader放在内部FLASH,APP放在外置FLASH中。不过这种方式在开发中也遇到好几个大坑,足足耽误了一个月时间,还好最终还是成功了。 ###启动程序 由于STM32F7508-DK采用的芯片STM32F750N8H6属于STMicroelectronics Arm® Cortex®-M7内核,内置FLASH只有64K,所以启动程序必须精简,提供必要的功能。故需要使用QSPI,SDRAM模块 #### QSPI QSPI 即 Quad SPI,是一种专用的通信接口,连接单、双或四(条数据线)SPI FLASH 存储 器。STM32F7 具有 QSPI 接口,支持如下三种工作模式:间接模式,状态轮询模式,内存映射模式。 QSPI启动后,需要设置内存映射模式 ``` /** *
@brief
Initializes and configure the QSPI interface. * @retval QSPI memory status */ uint32_t QSPI_Startup(void) { QSPIHandle.Instance = QUADSPI; /* Call the DeInit function to reset the driver */ if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK) { return MEMORY_ERROR; } /* System level initialization */ QSPI_MspInit(); /* sCommand initialize common parameter */ sCommand.AddressMode = QSPI_ADDRESS_NONE; sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; sCommand.DataMode = QSPI_DATA_NONE; sCommand.DummyCycles = 0; sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; sCommand.AddressSize = QSPI_ADDRESS_24_BITS; /* sConfig initialize common parameter */ sConfig.MatchMode = QSPI_MATCH_MODE_AND; sConfig.StatusBytesSize = 1; sConfig.Interval = 0x10; sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; /* QSPI initialization */ /* QSPI freq = SYSCLK /(1 + ClockPrescaler) = 216 MHz/(1+1) = 108 Mhz */ QSPIHandle.Init.ClockPrescaler = 1; /* QSPI freq = 216 MHz/(1+1) = 108 Mhz */ QSPIHandle.Init.FifoThreshold = 4; QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; QSPIHandle.Init.FlashSize = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1; QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE; /* Min 30ns for nonRead */ QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1; QSPIHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE; if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK) { return MEMORY_ERROR; } /* QSPI memory reset */ if (QSPI_ResetMemory(&QSPIHandle)) { return MEMORY_ERROR; } #if (CODE_AREA == USE_QSPI) /* Put QSPI memory in QPI mode */ if( QSPI_EnterMemory_QPI( &QSPIHandle )!=MEMORY_OK ) { return MEMORY_ERROR; } /* Configuration of the dummy cycles on QSPI memory side */ if (QSPI_DummyCyclesCfg(&QSPIHandle) != MEMORY_OK) { return MEMORY_ERROR; } /* Enable MemoryMapped mode */ if( QSPI_EnableMemoryMappedMode( &QSPIHandle ) != MEMORY_OK ) { return MEMORY_ERROR; } #elif (BINARY_AREA == USE_SPI_NOR) if (QSPI_Copy(APPLICATION_ADDRESS, BINARY_BASE_OFFSET, BINARY_SIZE) != MEMORY_OK) { return MEMORY_ERROR; } if (QSPI_Shutdown() != MEMORY_OK) { return MEMORY_ERROR; } #endif /* (CODE_AREA == USE_QSPI) */ return MEMORY_OK; } static uint32_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi) { /* Send command RESET command in SPI mode */ /* Initialize the reset enable command */ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; sCommand.Instruction = RESET_ENABLE_CMD; sCommand.DataMode = QSPI_DATA_NONE; /* Send the command */ if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return MEMORY_ERROR; } /* Send the reset memory command */ sCommand.Instruction = RESET_MEMORY_CMD; if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { return MEMORY_ERROR; } return MEMORY_OK; } static uint32_t QSPI_EnableMemoryMappedMode(QSPI_HandleTypeDef *hqspi) { QSPI_MemoryMappedTypeDef s_mem_mapped_cfg; /* Configure the command for the read instruction */ sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES; sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD; sCommand.AddressMode = QSPI_ADDRESS_4_LINES; sCommand.DataMode = QSPI_DATA_4_LINES; sCommand.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD; /* Configure the memory mapped mode */ s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE; s_mem_mapped_cfg.TimeOutPeriod = 0; if (HAL_QSPI_MemoryMapped(hqspi, &sCommand, &s_mem_mapped_cfg) != HAL_OK) { return MEMORY_ERROR; } return MEMORY_OK; } ``` ####SDRAM 通过 STM32F750 的 FMC 接口驱动美光MT48LC4M32B2,容量16MB,但是由于FMC接口引脚原因,只能使用8MB。 ``` /** * @briefInitializes the SDRAM device. * @retval SDRAM status */ uint32_t SDRAM_Startup(void) { SDRAM_HandleTypeDef sdramHandle; FMC_SDRAM_TimingTypeDefTiming; FMC_SDRAM_CommandTypeDef Command; __IO uint32_t tmpmrd = 0; /* SDRAM device configuration */ sdramHandle.Instance = FMC_SDRAM_DEVICE; /* Timing configuration for 100Mhz as SDRAM clock frequency (System clock is up to 200Mhz) */ Timing.LoadToActiveDelay = 2; Timing.ExitSelfRefreshDelay = 7; Timing.SelfRefreshTime = 4; Timing.RowCycleDelay = 7; Timing.WriteRecoveryTime = 3; Timing.RPDelay = 2; Timing.RCDDelay = 2; sdramHandle.Init.SDBank = FMC_SDRAM_BANK1; sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; sdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; sdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH; sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; sdramHandle.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; sdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD; sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; /* SDRAM controller initialization */ SDRAM_MspInit(); if (HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK) { return MEMORY_ERROR; } /* SDRAM initialization sequence */ /* Step 1: Configure a clock configuration enable command */ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); /* Step 2: Insert 100 us minimum delay */ /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ HAL_Delay(1); /* Step 3: Configure a PALL (precharge all) command */ Command.CommandMode = FMC_SDRAM_CMD_PALL; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); /* Step 4: Configure an Auto Refresh command */ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 8; Command.ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); /* Step 5: Program the external memory mode register */ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |\ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |\ SDRAM_MODEREG_CAS_LATENCY_2 |\ SDRAM_MODEREG_OPERATING_MODE_STANDARD |\ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = tmpmrd; /* Send the command */ HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); /* Step 6: Set the refresh rate counter */ /* Set the device refresh rate */ HAL_SDRAM_ProgramRefreshRate(&sdramHandle, REFRESH_COUNT); return MEMORY_OK; } ``` ####程序入口 配置好外置FLASH和SDRAM后,进行初始化后,设置APP的堆栈指针,和Reset\_Handler地址 然后跳入APP执行程序,完成BOOT引导过程。 ``` /** * @briefMain program * @paramNone * @retval None */ int main(void) { /* Configure MPU to allow non aligned access */ MPU_Config(); /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* STM32F7xx HAL library initialization: - Configure the Flash ART accelerator on ITCM interface - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 200 MHz */ /* Configure the Systick to generate an interrupt each 1 msec */ SystemClock_Config(); /*##-1- Configure Required Memory #########################################*/ if(Memory_Startup() != MEMORY_OK) { Error_Handler(); } /* Disable CPU L1 cache before jumping to the QSPI code execution */ CPU_CACHE_Disable(); /* Disable Systick interrupt */ DISABLE_INT(); HAL_RCC_DeInit(); SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; for (int i = 0; i < 8; i++) { NVIC->ICER
=0xFFFFFFFF; NVIC->ICPR
=0xFFFFFFFF; } ENABLE_INT(); __set_CONTROL(0); /* Initialize user application's Stack Pointer & Jump to user application */ JumpToApplication = (pFunction) (*(__IO uint32_t*) (APPLICATION_ADDRESS + 4)); __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); JumpToApplication(); /* We should never get here as execution is now on user application */ while(1) { } } ``` ###主程序 ## 框架概述 由于STM32F750的硬件限制,需要将主程序放在外置FLASH。所以程序可使用BOOT+APP程序模式,BOOT程序在芯片内置FLASH启动后,加载外置FLASH,SDRAM驱动程序,跳转到主程序的Reset_Handler入口函数,所以主程序的入口偏移地址必须和BOOT程序的跳转指针地址一致。 主程序在外置FLASH上运行,而且需要使用外部SDRAM,同时还有使用内部RAM,最好采用分散文件管理内存布局。 ``` ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x90000000 0x0800000 { ; load region size_region ER_IROM1 0x90000000 0x0800000 {; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) *(Veneer$$Code) .ANY (+RO) } RW_IRAM1 0x20000000 0x00050000 {; RW data *.o(registmodules) ;*.o(.dtram_bss) *.o(.data*) *.o(.bss.*) *.o(.bss) *.o(.dtcm_bss) .ANY (+RW +ZI) } RW_SRAM1 0xC0000000 0x00100000 { *.o(.lvgl_bss) } RW_SRAM2 0xC0100000 0x00100000 { *.o(.sram_bss) ;*.o(.sram_1_bss) *.o(.first_data) } RW_ITCM 0x00000000 0x00010000 { ; ITCM *.o(.ramfunctions) } ARM_LIB_HEAP ImageLimit(RW_IRAM1) EMPTY 0x20040000-ImageLimit(RW_IRAM1) { } ARM_LIB_STACK 0x20050000 EMPTY -0x10000 { } } ``` 程序入口地址需要修改成LR_IROM1地址即0x90000000。 ``` #define VECT_TAB_BASE_ADDRESS QSPI_BASE static void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; /** Configure LSE Drive Capability */ HAL_PWR_EnableBkUpAccess(); /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; // #if (DATA_AREA == USE_EXTERNAL_SDRAM) || (CODE_AREA == USE_EXTERNAL_SDRAM) RCC_OscInitStruct.PLL.PLLN = 360; // #else // RCC_OscInitStruct.PLL.PLLN = 432; // #endif RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 8; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Activate the Over-Drive mode */ if (HAL_PWREx_EnableOverDrive() != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK) { Error_Handler(); } RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_CLK48; PeriphClkInitStruct.PLLSAI.PLLSAIN = 384; PeriphClkInitStruct.PLLSAI.PLLSAIR = 5; PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2; PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV8; PeriphClkInitStruct.PLLSAIDivQ = 1; PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2; PeriphClkInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI; PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLLSAIP; PeriphClkInitStruct.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_CLK48; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ __HAL_RCC_SYSCFG_CLK_ENABLE(); /* Enables the I/O Compensation Cell */ HAL_EnableCompensationCell(); } // called from main, but it is HAL so we put it here void main_system_setup() { //MPU_Config(); // Enable the CPU Cache CPU_CACHE_Enable(); // stm32h7xx HAL library initialization if (HAL_Init() != HAL_OK) { Error_Handler(); } // Configure the system clock to 200 MHz SystemClock_Config(); } int main(int argc, char *argv[]) { // 设置时钟和缓存等(在 HAL 中) main_system_setup(); setup_memory_pool(); Board_LED_Init(); // led 4 表示启动阶段 1 开始 Board_LED_Set(0, true); std::ios_base::sync_with_stdio(false); benchmark_timer_init(); setup_xprintf(); if(setup_uart() < 0) { printf("FATAL: UART setup failed\n"); } if(rtc_init() != 1) { printf("ERROR: Failed to init RTC\n"); } // 启动启动线程,该线程将成为执行所有传入命令的命令线程 xTaskCreate(led_startup, "LedThread", 256, NULL, (tskIDLE_PRIORITY + DISP_PRI), (TaskHandle_t *)NULL); xTaskCreate(lvglui_startup, "LvglThread", 2048, NULL, (tskIDLE_PRIORITY + DISP_PRI), (TaskHandle_t *)&LVGLTask_Handler); xTaskCreate(smoothie_startup, "CommandThread", 8192, NULL, (tskIDLE_PRIORITY + CMDTHRD_PRI), (TaskHandle_t *)&CommTask_Handler); /* 启动调度程序 */ vTaskStartScheduler(); while (1) { } // 永远不要到这里 return 1; } ``` ##界面 界面采用LVGL,实现功能界面的切换,包括按钮,开关等控件实现对3D打印机功能的调用完成打印任务。除界面外,还需要实现触摸功能,显示功能。 ###显示功能接口 STM32F7508-DK采用的是ROCKTECH带电容式触摸屏的4.3英寸480x272彩色LCD-TFT,型号RK043FN48H-CT672B,需要驱动LCD-TFT 控制器 (LTDC),同时要使LVGL接口进行对接。 ``` /** * Initialize your display here */ void tft_init(void) { /* There is only one display on STM32 */ if(our_disp != NULL) abort(); /* LCD Initialization */ LCD_Init(); /* LCD Initialization */ LCD_LayerRgb565Init((uint32_t)my_fb); /* Enable the LCD */ LCD_DisplayOn(); DMA_Config(); /*----------------------------- * Create a buffer for drawing *----------------------------*/ /* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row*/ static lv_disp_draw_buf_t disp_buf_1; static lv_color_t buf1_1[TFT_HOR_RES * TFT_VER_RES]__attribute__((section(".lvgl_bss"), aligned(32))); static lv_color_t buf1_2[TFT_HOR_RES * TFT_VER_RES]__attribute__((section(".lvgl_bss"), aligned(32))); lv_disp_draw_buf_init(&disp_buf_1, buf1_1, buf1_2, TFT_HOR_RES * TFT_VER_RES); /*Initialize the display buffer*/ /*----------------------------------- * Register the display in LittlevGL *----------------------------------*/ lv_disp_drv_init(&disp_drv); /*Basic initialization*/ /*Set up the functions to access to your display*/ /*Set the resolution of the display*/ disp_drv.hor_res = 480; disp_drv.ver_res = 272; /*Used to copy the buffer's content to the display*/ disp_drv.flush_cb = ex_disp_flush; disp_drv.clean_dcache_cb = ex_disp_clean_dcache; /*Set a display buffer*/ disp_drv.draw_buf = &disp_buf_1; /*Finally register the driver*/ our_disp = lv_disp_drv_register(&disp_drv); } /** * @brief Configure LCD pins, and peripheral clocks. */ static void LCD_MspInit(void) { GPIO_InitTypeDef gpio_init_structure; /* Enable the LTDC and DMA2D clocks */ __HAL_RCC_LTDC_CLK_ENABLE(); __HAL_RCC_DMA2D_CLK_ENABLE(); /* Enable GPIOs clock */ __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOI_CLK_ENABLE(); __HAL_RCC_GPIOJ_CLK_ENABLE(); __HAL_RCC_GPIOK_CLK_ENABLE(); LCD_DISP_GPIO_CLK_ENABLE(); LCD_BL_CTRL_GPIO_CLK_ENABLE(); /*** LTDC Pins configuration ***/ /* GPIOE configuration */ gpio_init_structure.Pin = GPIO_PIN_4; gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Pull = GPIO_NOPULL; gpio_init_structure.Speed = GPIO_SPEED_FAST; gpio_init_structure.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOE, &gpio_init_structure); /* GPIOG configuration */ gpio_init_structure.Pin = GPIO_PIN_12; gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Alternate = GPIO_AF9_LTDC; HAL_GPIO_Init(GPIOG, &gpio_init_structure); /* GPIOI LTDC alternate configuration */ gpio_init_structure.Pin = GPIO_PIN_9 | GPIO_PIN_10 | \ GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOI, &gpio_init_structure); /* GPIOJ configuration */ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \ GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | \ GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \ GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOJ, &gpio_init_structure); /* GPIOK configuration */ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | \ GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Alternate = GPIO_AF14_LTDC; HAL_GPIO_Init(GPIOK, &gpio_init_structure); /* LCD_DISP GPIO configuration */ gpio_init_structure.Pin = LCD_DISP_PIN; /* LCD_DISP pin has to be manually controlled */ gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(LCD_DISP_GPIO_PORT, &gpio_init_structure); /* LCD_BL_CTRL GPIO configuration */ gpio_init_structure.Pin = LCD_BL_CTRL_PIN;/* LCD_BL_CTRL pin has to be manually controlled */ gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure); } /** * @brief Configure LTDC PLL. */ static void LCD_ClockConfig(void) { static RCC_PeriphCLKInitTypeDefperiph_clk_init_struct; /* RK043FN48H LCD clock configuration */ /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */ /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/5 = 38.4 Mhz */ /* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6Mhz */ periph_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_LTDC; periph_clk_init_struct.PLLSAI.PLLSAIN = 192; periph_clk_init_struct.PLLSAI.PLLSAIR = RK043FN48H_FREQUENCY_DIVIDER; periph_clk_init_struct.PLLSAIDivR = RCC_PLLSAIDIVR_4; HAL_RCCEx_PeriphCLKConfig(&periph_clk_init_struct); } /** * @briefInitializes the LCD. * @retval LCD state */ static uint8_t LCD_Init(void) { /* Select the used LCD */ /* The RK043FN48H LCD 480x272 is selected */ /* Timing Configuration */ hLtdcHandler.Init.HorizontalSync = (RK043FN48H_HSYNC - 1); hLtdcHandler.Init.VerticalSync = (RK043FN48H_VSYNC - 1); hLtdcHandler.Init.AccumulatedHBP = (RK043FN48H_HSYNC + RK043FN48H_HBP - 1); hLtdcHandler.Init.AccumulatedVBP = (RK043FN48H_VSYNC + RK043FN48H_VBP - 1); hLtdcHandler.Init.AccumulatedActiveH = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP - 1); hLtdcHandler.Init.AccumulatedActiveW = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP - 1); hLtdcHandler.Init.TotalHeigh = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP + RK043FN48H_VFP - 1); hLtdcHandler.Init.TotalWidth = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP + RK043FN48H_HFP - 1); /* LCD clock configuration */ LCD_ClockConfig(); /* Initialize the LCD pixel width and pixel height */ hLtdcHandler.LayerCfg->ImageWidth= RK043FN48H_WIDTH; hLtdcHandler.LayerCfg->ImageHeight = RK043FN48H_HEIGHT; /* Background value */ hLtdcHandler.Init.Backcolor.Blue = 0; hLtdcHandler.Init.Backcolor.Green = 0; hLtdcHandler.Init.Backcolor.Red = 0; /* Polarity */ hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL; hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL; hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL; hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC; hLtdcHandler.Instance = LTDC; if(HAL_LTDC_GetState(&hLtdcHandler) == HAL_LTDC_STATE_RESET) { /* Initialize the LCD Msp: this __weak function can be rewritten by the application */ LCD_MspInit(); } HAL_LTDC_Init(&hLtdcHandler); /* Assert display enable LCD_DISP pin */ HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET); /* Assert backlight LCD_BL_CTRL pin */ HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET); uint32_t i; for(i = 0; i < (TFT_HOR_RES * TFT_VER_RES) ; i++) { my_fb
= 0; } return LCD_OK; } static void LCD_LayerRgb565Init(uint32_t FB_Address) { LTDC_LayerCfgTypeDeflayer_cfg; /* Layer Init */ layer_cfg.WindowX0 = 0; layer_cfg.WindowX1 = TFT_HOR_RES; layer_cfg.WindowY0 = 0; layer_cfg.WindowY1 = TFT_VER_RES; #if LV_COLOR_DEPTH == 16 layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888; #else #error Unsupported color depth (see tft.c) #endif layer_cfg.FBStartAdress = FB_Address; layer_cfg.Alpha = 255; layer_cfg.Alpha0 = 0; layer_cfg.Backcolor.Blue = 0; layer_cfg.Backcolor.Green = 0; layer_cfg.Backcolor.Red = 0; layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; layer_cfg.ImageWidth = TFT_HOR_RES; layer_cfg.ImageHeight = TFT_VER_RES; HAL_LTDC_ConfigLayer(&hLtdcHandler, &layer_cfg, 0); } static void LCD_DisplayOn(void) { /* Display On */ __HAL_LTDC_ENABLE(&hLtdcHandler); HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET); /* Assert LCD_DISP pin */ HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET);/* Assert LCD_BL_CTRL pin */ } static void DMA_Config(void) { /*## -1- Enable DMA2 clock #################################################*/ __HAL_RCC_DMA2_CLK_ENABLE(); /*##-2- Select the DMA functional Parameters ###############################*/ DmaHandle.Init.Channel = CPY_BUF_DMA_CHANNEL; /* DMA_CHANNEL_0 */ DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; /* M2M transfer mode */ DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; /* Peripheral increment mode Enable */ DmaHandle.Init.MemInc = DMA_MINC_ENABLE; /* Memory increment mode Enable */ DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* Peripheral data alignment : 16bit */ DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; /* memory data alignment : 16bit */ DmaHandle.Init.Mode = DMA_NORMAL; /* Normal DMA mode */ DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; /* priority level : high */ DmaHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; /* FIFO mode enabled */ DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; /* FIFO threshold: 1/4 full */ DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; /* Memory burst */ DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Peripheral burst */ /*##-3- Select the DMA instance to be used for the transfer : DMA2_Stream0 #*/ DmaHandle.Instance = CPY_BUF_DMA_STREAM; /*##-4- Initialize the DMA stream ##########################################*/ if(HAL_DMA_Init(&DmaHandle) != HAL_OK) { while(1) { } } /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */ HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, DMA_TransferComplete); HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, DMA_TransferError); /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/ NVIC_SetPriority(CPY_BUF_DMA_STREAM_IRQ, 7); NVIC_EnableIRQ(CPY_BUF_DMA_STREAM_IRQ); } ``` ###触摸功能 ``` /** * Initialize your input devices here */ void touchpad_init(void) { BSP_TS_Init(TFT_HOR_RES, TFT_VER_RES); static lv_indev_drv_t indev_drv; /*Descriptor of an input device driver*/ lv_indev_drv_init(&indev_drv); /*Basic initialization*/ indev_drv.type = LV_INDEV_TYPE_POINTER; /*The touchpad is pointer type device*/ indev_drv.read_cb = touchpad_read; lv_indev_drv_register(&indev_drv); } /** * Read an input device * @param indev_id id of the input device to read * @param x put the x coordinate here * @param y put the y coordinate here *
@return
true: the device is pressed, false: released */ static void touchpad_read(lv_indev_drv_t *indev, lv_indev_data_t *data) { /* Read your touchpad */ static int16_t last_x = 0; static int16_t last_y = 0; //BSP_LED_Toggle(LED1); BSP_TS_GetState(&TS_State); if(TS_State.touchDetected) { data->point.x = TS_State.touchX[0]; data->point.y = TS_State.touchY[0]; last_x = data->point.x; last_y = data->point.y; data->state = LV_INDEV_STATE_PRESSED; } else { data->point.x = last_x; data->point.y = last_y; data->state = LV_INDEV_STATE_RELEASED; } } ``` ####界面 ``` void ui_init(void) { lv_disp_t * dispp = lv_disp_get_default(); lv_theme_t * theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT); lv_disp_set_theme(dispp, theme); ui_Screen_1_Print_screen_init(); ui_Screen_2_Move_screen_init(); ui_Screen_3_Setting_screen_init(); lv_disp_load_scr(ui_Screen_1_Print); } ///////////////////// SCREENS //////////////////// void ui_Screen_1_Print_screen_init(void) { // ui_Screen_1_Print ui_Screen_1_Print = lv_obj_create(NULL); lv_obj_set_style_bg_color(ui_Screen_1_Print, lv_color_hex(0x191D26), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Screen_1_Print, 255, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Background ui_Background = lv_img_create(ui_Screen_1_Print); lv_img_set_src(ui_Background, &ui_img_3d_printer_bg_png); lv_obj_set_width(ui_Background, 480); lv_obj_set_height(ui_Background, 272); lv_obj_set_x(ui_Background, 0); lv_obj_set_y(ui_Background, 0); lv_obj_set_align(ui_Background, LV_ALIGN_CENTER); lv_obj_add_flag(ui_Background, LV_OBJ_FLAG_ADV_HITTEST); // ui_Panel_Header ui_Panel_Header = lv_obj_create(ui_Screen_1_Print); lv_obj_set_width(ui_Panel_Header, 400); lv_obj_set_height(ui_Panel_Header, 22); lv_obj_set_x(ui_Panel_Header, -18); lv_obj_set_y(ui_Panel_Header, 0); lv_obj_set_align(ui_Panel_Header, LV_ALIGN_TOP_RIGHT); lv_obj_clear_flag(ui_Panel_Header, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_Panel_Header, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Panel_Header, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Panel_Header, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Panel_Header, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_Panel_Header, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Header ui_Label_Header = lv_label_create(ui_Panel_Header); lv_obj_set_width(ui_Label_Header, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Header, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Header, 0); lv_obj_set_y(ui_Label_Header, 0); lv_obj_set_align(ui_Label_Header, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Header, "The #ffffff squareline.gcode# word file is being printed"); lv_label_set_recolor(ui_Label_Header, "true"); lv_obj_set_style_text_color(ui_Label_Header, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Header, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Header, &lv_font_montserrat_10, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_IMG_Wifi ui_IMG_Wifi = lv_img_create(ui_Panel_Header); lv_img_set_src(ui_IMG_Wifi, &ui_img_icn_wifi_png); lv_obj_set_width(ui_IMG_Wifi, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_Wifi, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_Wifi, 0); lv_obj_set_y(ui_IMG_Wifi, 0); lv_obj_set_align(ui_IMG_Wifi, LV_ALIGN_RIGHT_MID); lv_obj_add_flag(ui_IMG_Wifi, LV_OBJ_FLAG_ADV_HITTEST); // ui_IMG_PC ui_IMG_PC = lv_img_create(ui_Panel_Header); lv_img_set_src(ui_IMG_PC, &ui_img_icn_pc_png); lv_obj_set_width(ui_IMG_PC, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_PC, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_PC, -25); lv_obj_set_y(ui_IMG_PC, 0); lv_obj_set_align(ui_IMG_PC, LV_ALIGN_RIGHT_MID); lv_obj_add_flag(ui_IMG_PC, LV_OBJ_FLAG_ADV_HITTEST); // ui_IMG_USB ui_IMG_USB = lv_img_create(ui_Panel_Header); lv_img_set_src(ui_IMG_USB, &ui_img_icn_usb_png); lv_obj_set_width(ui_IMG_USB, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_USB, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_USB, -50); lv_obj_set_y(ui_IMG_USB, 0); lv_obj_set_align(ui_IMG_USB, LV_ALIGN_RIGHT_MID); lv_obj_add_flag(ui_IMG_USB, LV_OBJ_FLAG_ADV_HITTEST); // ui_BTN_Menu_Print_S1 ui_BTN_Menu_Print_S1 = lv_img_create(ui_Screen_1_Print); lv_img_set_src(ui_BTN_Menu_Print_S1, &ui_img_btn_print_png); lv_obj_set_width(ui_BTN_Menu_Print_S1, 47); lv_obj_set_height(ui_BTN_Menu_Print_S1, 91); lv_obj_set_x(ui_BTN_Menu_Print_S1, 0); lv_obj_set_y(ui_BTN_Menu_Print_S1, 0); lv_obj_add_flag(ui_BTN_Menu_Print_S1, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_clear_flag(ui_BTN_Menu_Print_S1, LV_OBJ_FLAG_SCROLLABLE); // ui_BTN_Menu_Move_S1 ui_BTN_Menu_Move_S1 = lv_img_create(ui_Screen_1_Print); lv_img_set_src(ui_BTN_Menu_Move_S1, &ui_img_btn_move_png); lv_obj_set_width(ui_BTN_Menu_Move_S1, 47); lv_obj_set_height(ui_BTN_Menu_Move_S1, 91); lv_obj_set_x(ui_BTN_Menu_Move_S1, 0); lv_obj_set_y(ui_BTN_Menu_Move_S1, 0); lv_obj_set_align(ui_BTN_Menu_Move_S1, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_BTN_Menu_Move_S1, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_clear_flag(ui_BTN_Menu_Move_S1, LV_OBJ_FLAG_SCROLLABLE); lv_obj_add_event_cb(ui_BTN_Menu_Move_S1, ui_event_BTN_Menu_Move_S1, LV_EVENT_ALL, NULL); lv_obj_set_style_opa(ui_BTN_Menu_Move_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_BTN_Menu_Setting_S1 ui_BTN_Menu_Setting_S1 = lv_img_create(ui_Screen_1_Print); lv_img_set_src(ui_BTN_Menu_Setting_S1, &ui_img_btn_setting_png); lv_obj_set_width(ui_BTN_Menu_Setting_S1, 47); lv_obj_set_height(ui_BTN_Menu_Setting_S1, 90); lv_obj_set_x(ui_BTN_Menu_Setting_S1, 0); lv_obj_set_y(ui_BTN_Menu_Setting_S1, 0); lv_obj_set_align(ui_BTN_Menu_Setting_S1, LV_ALIGN_BOTTOM_LEFT); lv_obj_add_flag(ui_BTN_Menu_Setting_S1, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_clear_flag(ui_BTN_Menu_Setting_S1, LV_OBJ_FLAG_SCROLLABLE); lv_obj_add_event_cb(ui_BTN_Menu_Setting_S1, ui_event_BTN_Menu_Setting_S1, LV_EVENT_ALL, NULL); lv_obj_set_style_opa(ui_BTN_Menu_Setting_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_S1_Content_Panel ui_S1_Content_Panel = lv_obj_create(ui_Screen_1_Print); lv_obj_set_width(ui_S1_Content_Panel, 432); lv_obj_set_height(ui_S1_Content_Panel, 245); lv_obj_set_x(ui_S1_Content_Panel, 0); lv_obj_set_y(ui_S1_Content_Panel, 0); lv_obj_set_align(ui_S1_Content_Panel, LV_ALIGN_BOTTOM_RIGHT); lv_obj_clear_flag(ui_S1_Content_Panel, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_S1_Content_Panel, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_S1_Content_Panel, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_S1_Content_Panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Slider_Print_View ui_Slider_Print_View = lv_slider_create(ui_S1_Content_Panel); lv_slider_set_range(ui_Slider_Print_View, 0, 100); lv_slider_set_value(ui_Slider_Print_View, 70, LV_ANIM_OFF); if(lv_slider_get_mode(ui_Slider_Print_View) == LV_SLIDER_MODE_RANGE) lv_slider_set_left_value(ui_Slider_Print_View, 0, LV_ANIM_OFF); lv_obj_set_width(ui_Slider_Print_View, 199); lv_obj_set_height(ui_Slider_Print_View, 225); lv_obj_set_x(ui_Slider_Print_View, 0); lv_obj_set_y(ui_Slider_Print_View, -6); lv_obj_set_align(ui_Slider_Print_View, LV_ALIGN_LEFT_MID); lv_obj_add_event_cb(ui_Slider_Print_View, ui_event_Slider_Print_View, LV_EVENT_ALL, NULL); lv_obj_set_style_radius(ui_Slider_Print_View, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_color(ui_Slider_Print_View, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Slider_Print_View, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Slider_Print_View, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Slider_Print_View, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_img_src(ui_Slider_Print_View, &ui_img_print_view_bg_png, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_radius(ui_Slider_Print_View, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT); lv_obj_set_style_bg_color(ui_Slider_Print_View, lv_color_hex(0xFFFFFF), LV_PART_INDICATOR | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Slider_Print_View, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Slider_Print_View, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Slider_Print_View, 255, LV_PART_INDICATOR | LV_STATE_DEFAULT); lv_obj_set_style_bg_img_src(ui_Slider_Print_View, &ui_img_print_view_front_png, LV_PART_INDICATOR | LV_STATE_DEFAULT); lv_obj_set_style_bg_color(ui_Slider_Print_View, lv_color_hex(0xFFFFFF), LV_PART_KNOB | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Slider_Print_View, 0, LV_PART_KNOB | LV_STATE_DEFAULT); // ui_Number_Print ui_Number_Print = lv_label_create(ui_Slider_Print_View); lv_obj_set_width(ui_Number_Print, LV_SIZE_CONTENT); lv_obj_set_height(ui_Number_Print, LV_SIZE_CONTENT); lv_obj_set_x(ui_Number_Print, 0); lv_obj_set_y(ui_Number_Print, -20); lv_obj_set_align(ui_Number_Print, LV_ALIGN_BOTTOM_MID); lv_label_set_text(ui_Number_Print, "70%"); lv_obj_set_style_text_color(ui_Number_Print, lv_color_hex(0x00D2FF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Number_Print, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Number_Print, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Display_Time_S1 ui_Display_Time_S1 = lv_obj_create(ui_S1_Content_Panel); lv_obj_set_width(ui_Display_Time_S1, 210); lv_obj_set_height(ui_Display_Time_S1, 45); lv_obj_set_x(ui_Display_Time_S1, -16); lv_obj_set_y(ui_Display_Time_S1, 17); lv_obj_set_align(ui_Display_Time_S1, LV_ALIGN_TOP_RIGHT); lv_obj_clear_flag(ui_Display_Time_S1, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_Display_Time_S1, lv_color_hex(0x191D26), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Display_Time_S1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Display_Time_S1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_Display_Time_S1, lv_color_hex(0x414B62), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_opa(ui_Display_Time_S1, 100, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_width(ui_Display_Time_S1, 4, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_pad(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_Display_Time_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_DT1 ui_DT1 = lv_obj_create(ui_Display_Time_S1); lv_obj_set_width(ui_DT1, lv_pct(50)); lv_obj_set_height(ui_DT1, lv_pct(100)); lv_obj_set_x(ui_DT1, 0); lv_obj_set_y(ui_DT1, 0); lv_obj_set_align(ui_DT1, LV_ALIGN_LEFT_MID); lv_obj_clear_flag(ui_DT1, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_DT1, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_DT1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_DT1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_DT1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_DT1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_DT1, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_DT1, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_DT1, 12, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_DT1, 12, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Printing_Time_1 ui_Label_Printing_Time_1 = lv_label_create(ui_DT1); lv_obj_set_width(ui_Label_Printing_Time_1, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Printing_Time_1, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Printing_Time_1, 0); lv_obj_set_y(ui_Label_Printing_Time_1, -7); lv_obj_set_align(ui_Label_Printing_Time_1, LV_ALIGN_TOP_MID); lv_label_set_text(ui_Label_Printing_Time_1, "Printing Time"); lv_label_set_recolor(ui_Label_Printing_Time_1, "true"); lv_obj_set_style_text_color(ui_Label_Printing_Time_1, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Printing_Time_1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Printing_Time_1, &lv_font_montserrat_10, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_IMG_Tine_1 ui_IMG_Tine_1 = lv_img_create(ui_DT1); lv_img_set_src(ui_IMG_Tine_1, &ui_img_icn_time_1_png); lv_obj_set_width(ui_IMG_Tine_1, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_Tine_1, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_Tine_1, 5); lv_obj_set_y(ui_IMG_Tine_1, 6); lv_obj_set_align(ui_IMG_Tine_1, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_IMG_Tine_1, LV_OBJ_FLAG_ADV_HITTEST); // ui_Label_Time_1 ui_Label_Time_1 = lv_label_create(ui_DT1); lv_obj_set_width(ui_Label_Time_1, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Time_1, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Time_1, 35); lv_obj_set_y(ui_Label_Time_1, 7); lv_obj_set_align(ui_Label_Time_1, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Time_1, "10:52"); lv_obj_set_style_text_color(ui_Label_Time_1, lv_color_hex(0xDBE6FF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Time_1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Time_1, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Panel3 ui_Panel3 = lv_obj_create(ui_Display_Time_S1); lv_obj_set_width(ui_Panel3, 2); lv_obj_set_height(ui_Panel3, 28); lv_obj_set_x(ui_Panel3, 0); lv_obj_set_y(ui_Panel3, 0); lv_obj_set_align(ui_Panel3, LV_ALIGN_CENTER); lv_obj_set_style_bg_color(ui_Panel3, lv_color_hex(0x3A3F4B), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Panel3, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Panel3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Panel3, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_Panel3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_DT2 ui_DT2 = lv_obj_create(ui_Display_Time_S1); lv_obj_set_width(ui_DT2, lv_pct(50)); lv_obj_set_height(ui_DT2, lv_pct(100)); lv_obj_set_x(ui_DT2, 0); lv_obj_set_y(ui_DT2, 0); lv_obj_set_align(ui_DT2, LV_ALIGN_RIGHT_MID); lv_obj_clear_flag(ui_DT2, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_DT2, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_DT2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_DT2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_DT2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_DT2, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_DT2, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_DT2, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_DT2, 12, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_DT2, 12, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Printing_Time_2 ui_Label_Printing_Time_2 = lv_label_create(ui_DT2); lv_obj_set_width(ui_Label_Printing_Time_2, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Printing_Time_2, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Printing_Time_2, 0); lv_obj_set_y(ui_Label_Printing_Time_2, -6); lv_obj_set_align(ui_Label_Printing_Time_2, LV_ALIGN_TOP_MID); lv_label_set_text(ui_Label_Printing_Time_2, "Printing Time"); lv_label_set_recolor(ui_Label_Printing_Time_2, "true"); lv_obj_set_style_text_color(ui_Label_Printing_Time_2, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Printing_Time_2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Printing_Time_2, &lv_font_montserrat_10, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_IMG_Tine_2 ui_IMG_Tine_2 = lv_img_create(ui_DT2); lv_img_set_src(ui_IMG_Tine_2, &ui_img_icn_time_2_png); lv_obj_set_width(ui_IMG_Tine_2, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_Tine_2, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_Tine_2, 11); lv_obj_set_y(ui_IMG_Tine_2, 7); lv_obj_set_align(ui_IMG_Tine_2, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_IMG_Tine_2, LV_OBJ_FLAG_ADV_HITTEST); // ui_Label_Time_2 ui_Label_Time_2 = lv_label_create(ui_DT2); lv_obj_set_width(ui_Label_Time_2, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Time_2, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Time_2, 36); lv_obj_set_y(ui_Label_Time_2, 8); lv_obj_set_align(ui_Label_Time_2, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Time_2, "08:25"); lv_obj_set_style_text_color(ui_Label_Time_2, lv_color_hex(0xDBE6FF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Time_2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Time_2, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Display_Heat_S1 ui_Display_Heat_S1 = lv_obj_create(ui_S1_Content_Panel); lv_obj_set_width(ui_Display_Heat_S1, 210); lv_obj_set_height(ui_Display_Heat_S1, 45); lv_obj_set_x(ui_Display_Heat_S1, -16); lv_obj_set_y(ui_Display_Heat_S1, 74); lv_obj_set_align(ui_Display_Heat_S1, LV_ALIGN_TOP_RIGHT); lv_obj_clear_flag(ui_Display_Heat_S1, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_Display_Heat_S1, lv_color_hex(0x191D26), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Display_Heat_S1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Display_Heat_S1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_color(ui_Display_Heat_S1, lv_color_hex(0x414B62), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_opa(ui_Display_Heat_S1, 100, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_width(ui_Display_Heat_S1, 4, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_outline_pad(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_Display_Heat_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_DT3 ui_DT3 = lv_obj_create(ui_Display_Heat_S1); lv_obj_set_width(ui_DT3, lv_pct(50)); lv_obj_set_height(ui_DT3, lv_pct(100)); lv_obj_set_x(ui_DT3, 0); lv_obj_set_y(ui_DT3, 0); lv_obj_set_align(ui_DT3, LV_ALIGN_LEFT_MID); lv_obj_clear_flag(ui_DT3, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_DT3, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_DT3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_DT3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_DT3, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_DT3, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_DT3, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_DT3, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_DT3, 12, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_DT3, 12, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Printing_Head_Temp ui_Label_Printing_Head_Temp = lv_label_create(ui_DT3); lv_obj_set_width(ui_Label_Printing_Head_Temp, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Printing_Head_Temp, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Printing_Head_Temp, 0); lv_obj_set_y(ui_Label_Printing_Head_Temp, -6); lv_obj_set_align(ui_Label_Printing_Head_Temp, LV_ALIGN_TOP_MID); lv_label_set_text(ui_Label_Printing_Head_Temp, "Head Temp."); lv_label_set_recolor(ui_Label_Printing_Head_Temp, "true"); lv_obj_set_style_text_color(ui_Label_Printing_Head_Temp, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Printing_Head_Temp, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Printing_Head_Temp, &lv_font_montserrat_10, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_IMG_Head ui_IMG_Head = lv_img_create(ui_DT3); lv_img_set_src(ui_IMG_Head, &ui_img_icn_head_png); lv_obj_set_width(ui_IMG_Head, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_Head, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_Head, 7); lv_obj_set_y(ui_IMG_Head, 9); lv_obj_set_align(ui_IMG_Head, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_IMG_Head, LV_OBJ_FLAG_ADV_HITTEST); // ui_Label_Head_Temp ui_Label_Head_Temp = lv_label_create(ui_DT3); lv_obj_set_width(ui_Label_Head_Temp, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Head_Temp, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Head_Temp, 22); lv_obj_set_y(ui_Label_Head_Temp, 7); lv_obj_set_align(ui_Label_Head_Temp, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Head_Temp, "195°"); lv_obj_set_style_text_color(ui_Label_Head_Temp, lv_color_hex(0xDBE6FF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Head_Temp, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Head_Temp, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Printing_Head_Temp_2 ui_Label_Printing_Head_Temp_2 = lv_label_create(ui_DT3); lv_obj_set_width(ui_Label_Printing_Head_Temp_2, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Printing_Head_Temp_2, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Printing_Head_Temp_2, 55); lv_obj_set_y(ui_Label_Printing_Head_Temp_2, 7); lv_obj_set_align(ui_Label_Printing_Head_Temp_2, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Printing_Head_Temp_2, "/ 195°"); lv_label_set_recolor(ui_Label_Printing_Head_Temp_2, "true"); lv_obj_set_style_text_color(ui_Label_Printing_Head_Temp_2, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Printing_Head_Temp_2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Printing_Head_Temp_2, &ui_font_Small_Font, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Panel1 ui_Panel1 = lv_obj_create(ui_Display_Heat_S1); lv_obj_set_width(ui_Panel1, 2); lv_obj_set_height(ui_Panel1, 28); lv_obj_set_x(ui_Panel1, 0); lv_obj_set_y(ui_Panel1, 0); lv_obj_set_align(ui_Panel1, LV_ALIGN_CENTER); lv_obj_set_style_bg_color(ui_Panel1, lv_color_hex(0x3A3F4B), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Panel1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Panel1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Panel1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_Panel1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_DT3_copy ui_DT3_copy = lv_obj_create(ui_Display_Heat_S1); lv_obj_set_width(ui_DT3_copy, lv_pct(50)); lv_obj_set_height(ui_DT3_copy, lv_pct(100)); lv_obj_set_x(ui_DT3_copy, 0); lv_obj_set_y(ui_DT3_copy, 0); lv_obj_set_align(ui_DT3_copy, LV_ALIGN_RIGHT_MID); lv_obj_clear_flag(ui_DT3_copy, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_DT3_copy, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_DT3_copy, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_DT3_copy, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_DT3_copy, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_DT3_copy, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_DT3_copy, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_DT3_copy, 6, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_DT3_copy, 12, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_DT3_copy, 12, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Printing_Bed_Temp ui_Label_Printing_Bed_Temp = lv_label_create(ui_DT3_copy); lv_obj_set_width(ui_Label_Printing_Bed_Temp, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Printing_Bed_Temp, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Printing_Bed_Temp, 0); lv_obj_set_y(ui_Label_Printing_Bed_Temp, -5); lv_obj_set_align(ui_Label_Printing_Bed_Temp, LV_ALIGN_TOP_MID); lv_label_set_text(ui_Label_Printing_Bed_Temp, "Bed Temp."); lv_label_set_recolor(ui_Label_Printing_Bed_Temp, "true"); lv_obj_set_style_text_color(ui_Label_Printing_Bed_Temp, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Printing_Bed_Temp, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Printing_Bed_Temp, &lv_font_montserrat_10, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_IMG_Head1 ui_IMG_Head1 = lv_img_create(ui_DT3_copy); lv_img_set_src(ui_IMG_Head1, &ui_img_icn_bed_png); lv_obj_set_width(ui_IMG_Head1, LV_SIZE_CONTENT); lv_obj_set_height(ui_IMG_Head1, LV_SIZE_CONTENT); lv_obj_set_x(ui_IMG_Head1, 10); lv_obj_set_y(ui_IMG_Head1, 10); lv_obj_set_align(ui_IMG_Head1, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_IMG_Head1, LV_OBJ_FLAG_ADV_HITTEST); // ui_Label_Bed_Temp ui_Label_Bed_Temp = lv_label_create(ui_DT3_copy); lv_obj_set_width(ui_Label_Bed_Temp, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Bed_Temp, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Bed_Temp, 32); lv_obj_set_y(ui_Label_Bed_Temp, 7); lv_obj_set_align(ui_Label_Bed_Temp, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Bed_Temp, "65°"); lv_obj_set_style_text_color(ui_Label_Bed_Temp, lv_color_hex(0xDBE6FF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Bed_Temp, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Bed_Temp, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Label_Printing_Bed_Temp1 ui_Label_Printing_Bed_Temp1 = lv_label_create(ui_DT3_copy); lv_obj_set_width(ui_Label_Printing_Bed_Temp1, LV_SIZE_CONTENT); lv_obj_set_height(ui_Label_Printing_Bed_Temp1, LV_SIZE_CONTENT); lv_obj_set_x(ui_Label_Printing_Bed_Temp1, 59); lv_obj_set_y(ui_Label_Printing_Bed_Temp1, 7); lv_obj_set_align(ui_Label_Printing_Bed_Temp1, LV_ALIGN_LEFT_MID); lv_label_set_text(ui_Label_Printing_Bed_Temp1, "/ 65°"); lv_label_set_recolor(ui_Label_Printing_Bed_Temp1, "true"); lv_obj_set_style_text_color(ui_Label_Printing_Bed_Temp1, lv_color_hex(0x9098AA), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label_Printing_Bed_Temp1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_font(ui_Label_Printing_Bed_Temp1, &ui_font_Small_Font, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_Panel_Buttons_S1 ui_Panel_Buttons_S1 = lv_obj_create(ui_S1_Content_Panel); lv_obj_set_width(ui_Panel_Buttons_S1, 228); lv_obj_set_height(ui_Panel_Buttons_S1, 114); lv_obj_set_x(ui_Panel_Buttons_S1, 0); lv_obj_set_y(ui_Panel_Buttons_S1, 0); lv_obj_set_align(ui_Panel_Buttons_S1, LV_ALIGN_BOTTOM_RIGHT); lv_obj_clear_flag(ui_Panel_Buttons_S1, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(ui_Panel_Buttons_S1, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_Panel_Buttons_S1, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_border_width(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_left(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_right(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_top(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_pad_bottom(ui_Panel_Buttons_S1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_BTN_Pause ui_BTN_Pause = lv_img_create(ui_Panel_Buttons_S1); lv_img_set_src(ui_BTN_Pause, &ui_img_btn_print_down_png); lv_obj_set_width(ui_BTN_Pause, LV_SIZE_CONTENT); lv_obj_set_height(ui_BTN_Pause, LV_SIZE_CONTENT); lv_obj_set_x(ui_BTN_Pause, 10); lv_obj_set_y(ui_BTN_Pause, 0); lv_obj_set_align(ui_BTN_Pause, LV_ALIGN_LEFT_MID); lv_obj_add_flag(ui_BTN_Pause, LV_OBJ_FLAG_ADV_HITTEST); // ui_BTN_Pause_Top ui_BTN_Pause_Top = lv_img_create(ui_BTN_Pause); lv_img_set_src(ui_BTN_Pause_Top, &ui_img_btn_print_top_off_png); lv_obj_set_width(ui_BTN_Pause_Top, LV_SIZE_CONTENT); lv_obj_set_height(ui_BTN_Pause_Top, LV_SIZE_CONTENT); lv_obj_set_x(ui_BTN_Pause_Top, 0); lv_obj_set_y(ui_BTN_Pause_Top, 0); lv_obj_set_align(ui_BTN_Pause_Top, LV_ALIGN_CENTER); lv_obj_add_flag(ui_BTN_Pause_Top, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CHECKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_set_style_radius(ui_BTN_Pause_Top, 18, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_BTN_Pause_Top, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_BTN_Pause_Top, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_shadow_color(ui_BTN_Pause_Top, lv_color_hex(0x00D2FF), LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_opa(ui_BTN_Pause_Top, 255, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_width(ui_BTN_Pause_Top, 12, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_spread(ui_BTN_Pause_Top, 5, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_ofs_x(ui_BTN_Pause_Top, 0, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_ofs_y(ui_BTN_Pause_Top, 0, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_color(ui_BTN_Pause_Top, lv_color_hex(0x00D2FF), LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_opa(ui_BTN_Pause_Top, 255, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_width(ui_BTN_Pause_Top, 10, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_spread(ui_BTN_Pause_Top, 5, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_ofs_x(ui_BTN_Pause_Top, 0, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_ofs_y(ui_BTN_Pause_Top, 0, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_img_recolor(ui_BTN_Pause_Top, lv_color_hex(0x67799B), LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_img_recolor_opa(ui_BTN_Pause_Top, 255, LV_PART_MAIN | LV_STATE_PRESSED); // ui_Image_Pause ui_Image_Pause = lv_img_create(ui_BTN_Pause_Top); lv_img_set_src(ui_Image_Pause, &ui_img_icn_pause_png); lv_obj_set_width(ui_Image_Pause, LV_SIZE_CONTENT); lv_obj_set_height(ui_Image_Pause, LV_SIZE_CONTENT); lv_obj_set_x(ui_Image_Pause, 0); lv_obj_set_y(ui_Image_Pause, 0); lv_obj_set_align(ui_Image_Pause, LV_ALIGN_CENTER); lv_obj_add_flag(ui_Image_Pause, LV_OBJ_FLAG_ADV_HITTEST); lv_obj_set_style_img_recolor(ui_Image_Pause, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_img_recolor_opa(ui_Image_Pause, 0, LV_PART_MAIN | LV_STATE_DEFAULT); // ui_BTN_Cancel ui_BTN_Cancel = lv_img_create(ui_Panel_Buttons_S1); lv_img_set_src(ui_BTN_Cancel, &ui_img_btn_print_down_png); lv_obj_set_width(ui_BTN_Cancel, LV_SIZE_CONTENT); lv_obj_set_height(ui_BTN_Cancel, LV_SIZE_CONTENT); lv_obj_set_x(ui_BTN_Cancel, -18); lv_obj_set_y(ui_BTN_Cancel, 0); lv_obj_set_align(ui_BTN_Cancel, LV_ALIGN_RIGHT_MID); lv_obj_add_flag(ui_BTN_Cancel, LV_OBJ_FLAG_ADV_HITTEST); // ui_BTN_Cancel_Top ui_BTN_Cancel_Top = lv_img_create(ui_BTN_Cancel); lv_img_set_src(ui_BTN_Cancel_Top, &ui_img_btn_print_top_off_png); lv_obj_set_width(ui_BTN_Cancel_Top, LV_SIZE_CONTENT); lv_obj_set_height(ui_BTN_Cancel_Top, LV_SIZE_CONTENT); lv_obj_set_x(ui_BTN_Cancel_Top, 0); lv_obj_set_y(ui_BTN_Cancel_Top, 0); lv_obj_set_align(ui_BTN_Cancel_Top, LV_ALIGN_CENTER); lv_obj_add_flag(ui_BTN_Cancel_Top, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_ADV_HITTEST); lv_obj_add_event_cb(ui_BTN_Cancel_Top, ui_event_BTN_Cancel_Top, LV_EVENT_ALL, NULL); lv_obj_set_style_radius(ui_BTN_Cancel_Top, 18, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_main_stop(ui_BTN_Cancel_Top, 0, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_bg_grad_stop(ui_BTN_Cancel_Top, 255, LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_shadow_color(ui_BTN_Cancel_Top, lv_color_hex(0x00D2FF), LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_opa(ui_BTN_Cancel_Top, 255, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_width(ui_BTN_Cancel_Top, 12, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_spread(ui_BTN_Cancel_Top, 5, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_ofs_x(ui_BTN_Cancel_Top, 0, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_ofs_y(ui_BTN_Cancel_Top, 0, LV_PART_MAIN | LV_STATE_CHECKED); lv_obj_set_style_shadow_color(ui_BTN_Cancel_Top, lv_color_hex(0x00D2FF), LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_opa(ui_BTN_Cancel_Top, 255, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_width(ui_BTN_Cancel_Top, 12, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_shadow_spread(ui_BTN_Cancel_Top, 5, LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_img_recolor(ui_BTN_Cancel_Top, lv_color_hex(0x67799B), LV_PART_MAIN | LV_STATE_PRESSED); lv_obj_set_style_img_recolor_opa(ui_BTN_Cancel_Top, 255, LV_PART_MAIN | LV_STATE_PRESSED); // ui_Image_Cancel ui_Image_Cancel = lv_img_create(ui_BTN_Cancel_Top); lv_img_set_src(ui_Image_Cancel, &ui_img_icn_stop_png); lv_obj_set_width(ui_Image_Cancel, LV_SIZE_CONTENT); lv_obj_set_height(ui_Image_Cancel, LV_SIZE_CONTENT); lv_obj_set_x(ui_Image_Cancel, 0); lv_obj_set_y(ui_Image_Cancel, 0); lv_obj_set_align(ui_Image_Cancel, LV_ALIGN_CENTER); lv_obj_add_flag(ui_Image_Cancel, LV_OBJ_FLAG_ADV_HITTEST); lv_obj_set_style_img_recolor(ui_Image_Cancel, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_img_recolor_opa(ui_Image_Cancel, 0, LV_PART_MAIN | LV_STATE_DEFAULT); } ``` 3D打印机控制器基本功能是通过解释G代码程序,生成各种命令序列,控制打印机的XYZ(笛卡尔型)或ABC(Delta型)等等的步进电机进行移动,还要控制挤出机温度,通过PID算法,调节加热器保持温度稳定。高级功能需要通过网络接口,WIFI接口,USB设备等实现文件传输,远程控制,甚至云操作。 整体结构是在FreeRTOS平台基础上,创建LVGL和Command进程分别对应界面和主功能。在命令进程中根据SD卡的配置文件,解析并配置各功能模块,分配引脚,初始化参数。完成后根据用户的操作开启命令子进程完成业务,退出时回收资源。LVGL界面进程则通过用户触摸LCD,动画反馈操作,并通过消息命令队列与命令进程进行通讯,类似于Windows系统的消息,最终实现用户需要的功能。 由于平台的差异性需要移植的模块有SD,ADC,USART,PWM,TIM等等,特别是SD模块基于FATFS而Smooth采用的是标准文件系统,需要对接底层函数,网上介绍资料很少,通过不断调试找到方案,重写_sys_open等函数。 ###SD模块 驱动 ``` /** *@brief 初始化 SD MSP. *@param HSD SD 句柄 *@retval 无 */ static void SD_MspInit(SD_HandleTypeDef *hsd) { GPIO_InitTypeDef gpio_init_structure; if(hsd == &hsd_sdmmc[0]) { /* 启用 SDIO 时钟 */ __HAL_RCC_SDMMC1_CLK_ENABLE(); /* 启用 DMA 时钟 */ __HAL_RCC_DMA2_CLK_ENABLE(); /* 启用 GPIO 时钟 */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /* 常见 GPIO 配置 */ gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Pull = GPIO_NOPULL; gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; // GPIO_SPEED_FREQ_VERY_HIGH; /* D0(PC8), D1(PC9), D2(PC10), D3(PC11), CK(PC12), CMD(PD2) */ /* 常见 GPIO 配置 */ gpio_init_structure.Alternate = GPIO_AF12_SDMMC1; /* GPIOC 配置 */ gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; HAL_GPIO_Init(GPIOC, &gpio_init_structure); /* GPIOD 配置 */ gpio_init_structure.Pin = GPIO_PIN_2; HAL_GPIO_Init(GPIOD, &gpio_init_structure); allocate_hal_pin(GPIOC, GPIO_PIN_8); allocate_hal_pin(GPIOC, GPIO_PIN_9); allocate_hal_pin(GPIOC, GPIO_PIN_10); allocate_hal_pin(GPIOC, GPIO_PIN_11); allocate_hal_pin(GPIOC, GPIO_PIN_12); allocate_hal_pin(GPIOD, GPIO_PIN_2); __HAL_RCC_SDMMC1_FORCE_RESET(); __HAL_RCC_SDMMC1_RELEASE_RESET(); /* SDIO 中断的 NVIC 配置 */ NVIC_SetPriority(SDMMC1_IRQn, BSP_SD_IT_PRIORITY); NVIC_EnableIRQ(SDMMC1_IRQn); /* 配置 DMA Rx 参数 */ dma_rx_handle.Instance = DMA2_Stream3; dma_rx_handle.Init.Channel = DMA_CHANNEL_4; dma_rx_handle.Init.Direction = DMA_PERIPH_TO_MEMORY; dma_rx_handle.Init.PeriphInc = DMA_PINC_DISABLE; dma_rx_handle.Init.MemInc = DMA_MINC_ENABLE; dma_rx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; dma_rx_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; dma_rx_handle.Init.Mode = DMA_PFCTRL; dma_rx_handle.Init.Priority = DMA_PRIORITY_VERY_HIGH; dma_rx_handle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; dma_rx_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; dma_rx_handle.Init.MemBurst = DMA_MBURST_INC4; dma_rx_handle.Init.PeriphBurst = DMA_PBURST_INC4; /* Associate the DMA handle */ __HAL_LINKDMA(hsd, hdmarx, dma_rx_handle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dma_rx_handle); /* 配置 the DMA stream */ HAL_DMA_Init(&dma_rx_handle); /* 配置 DMA Tx parameters */ dma_tx_handle.Instance = DMA2_Stream6; dma_tx_handle.Init.Channel = DMA_CHANNEL_4; dma_tx_handle.Init.Direction = DMA_MEMORY_TO_PERIPH; dma_tx_handle.Init.PeriphInc = DMA_PINC_DISABLE; dma_tx_handle.Init.MemInc = DMA_MINC_ENABLE; dma_tx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; dma_tx_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; dma_tx_handle.Init.Mode = DMA_PFCTRL; dma_tx_handle.Init.Priority = DMA_PRIORITY_VERY_HIGH; dma_tx_handle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; dma_tx_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; dma_tx_handle.Init.MemBurst = DMA_MBURST_INC4; dma_tx_handle.Init.PeriphBurst = DMA_PBURST_INC4; /* Associate the DMA handle */ __HAL_LINKDMA(hsd, hdmatx, dma_tx_handle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dma_tx_handle); /* 配置 the DMA stream */ HAL_DMA_Init(&dma_tx_handle); /* NVIC configuration for DMA transfer complete interrupt */ NVIC_SetPriority(DMA2_Stream3_IRQn, BSP_SD_IT_PRIORITY+1); NVIC_EnableIRQ(DMA2_Stream3_IRQn); /* NVIC configuration for DMA transfer complete interrupt */ NVIC_SetPriority(DMA2_Stream6_IRQn, BSP_SD_IT_PRIORITY+1); NVIC_EnableIRQ(DMA2_Stream6_IRQn); } } /** *@brief DeInitializes SD MSP. *@param HSD SD 句柄 *@retval 无 */ static void SD_MspDeInit(SD_HandleTypeDef *hsd) { GPIO_InitTypeDef gpio_init_structure; if(hsd == &hsd_sdmmc[0]) { /* Disable NVIC for DMA transfer complete interrupts */ HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn); HAL_NVIC_DisableIRQ(DMA2_Stream6_IRQn); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dma_rx_handle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dma_tx_handle); /* 禁用 NVIC 以进行 SDIO 中断 */ HAL_NVIC_DisableIRQ(SDMMC1_IRQn); /* GPIOB 配置 */ gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9; HAL_GPIO_DeInit(GPIOB, gpio_init_structure.Pin); /* GPIOC 配置 */ gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; HAL_GPIO_DeInit(GPIOC, gpio_init_structure.Pin); /* GPIOC 配置 */ gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7; HAL_GPIO_DeInit(GPIOC, gpio_init_structure.Pin); /* GPIOD 配置 */ gpio_init_structure.Pin = GPIO_PIN_2; HAL_GPIO_DeInit(GPIOD, gpio_init_structure.Pin); /* 禁用 SDMMC1 时钟 */ __HAL_RCC_SDMMC1_CLK_DISABLE(); } } 主程序中 int setup_sdmmc() { // 链接微型 SD 磁盘 I/O 驱动程序 if(FATFS_LinkDriver(&SD_Driver, SDPath) != 0) { printf("Error: setup_sdmmc - link driver failed\n"); return 0; } return 1; } if(!setup_sdmmc()) { printf("ERROR: setting up sdmmc\n"); break; } // TODO 检查卡是否插入闪烁 4LED(如果不是) int ret = f_mount(&fatfs, "sd", 1); if(FR_OK != ret) { printf("ERROR: mounting: /sd: %d\n", ret); break; } std::fstream fs; fs.open("/sd/config.ini", std::fstream::in); if(!fs.is_open()) { printf("ERROR: opening file: /sd/config.ini\n"); break; } ``` 底层接口函数 ``` const char __stdin_name[] =":tt"; const char __stdout_name[] =":tt"; const char __stderr_name[] =":tt"; FILEHANDLE _sys_open(const char *name, int openmode) { #if FATFS_EN BYTE mode; FIL *fp; FRESULT fr; #endif if (name == __stdin_name) return STDIN; else if (name == __stdout_name) { setup_uart(); // 初始化串口 (在main函数执行前执行) return STDOUT; } else if (name == __stderr_name) return STDERR; #if FATFS_EN if (sizeof(FILEHANDLE) < sizeof(void *)) { usart_send_string("sizeof(FILEHANDLE) should be no less than sizeof(void *)!\n", -1); return -1; } fp = malloc(sizeof(FIL)); if (fp == NULL) return -1; if (openmode & OPEN_W) { mode = FA_CREATE_ALWAYS | FA_WRITE; if (openmode & OPEN_PLUS) mode |= FA_READ; } else if (openmode & OPEN_A) { mode = FA_OPEN_APPEND | FA_WRITE; if (openmode & OPEN_PLUS) mode |= FA_READ; } else { mode = FA_READ; if (openmode & OPEN_PLUS) mode |= FA_WRITE; } fr = f_open(fp, name, mode); if (fr == FR_OK) return (uintptr_t)fp; free(fp); #endif return -1; } int _sys_close(FILEHANDLE fh) { #if FATFS_EN FRESULT fr; #endif if (IS_STD(fh)) { if (fh == STDOUT) stop_uart(); return 0; } #if FATFS_EN fr = f_close((FIL *)fh); if (fr == FR_OK) { free((void *)fh); return 0; } #endif return -1; } ``` ###USART ``` void Configure_USART(void) { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; rxrb = CreateRingBuffer(128); /* (1) 启用 GPIO 时钟并配置 USART 引脚 *********************/ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1; PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* 启用 GPIO 端口的外设时钟 */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); /* PB7 ------> USART1_RX PA9 ------> USART1_TX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_7; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* (2) USART 中断的 NVIC 配置 */ /*- 设置 USARTx_IRQn 优先级 */ /*- 启用 USARTx_IRQn */ NVIC_SetPriority(USART1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY+8); NVIC_EnableIRQ(USART1_IRQn); /* (3) 启用 USART 外设时钟和时钟源 ***********************/ /* 设置时钟源 */ LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); /* (4) 配置 USART 功能参数 ********************************/ /* 在修改配置寄存器之前禁用 USART */ /* 注意:注释为与重置值相对应 */ LL_USART_Disable(USART1); /* 设置初始化结构的字段 */ /*- 预标定器 : LL_USART_PRESCALER_DIV1 */ /*- 波特率 : 115200 */ /*- 数据宽度 : LL_USART_DATAWIDTH_8B */ /*- 停止位 : LL_USART_STOPBITS_1 */ /*- 奇偶校验 : LL_USART_PARITY_NONE */ /*- 传输方向 : LL_USART_DIRECTION_TX_RX */ /*- 硬件流控制:LL_USART_HWCONTROL_NONE */ /*- 过采样:LL_USART_OVERSAMPLING_16 */ LL_USART_InitTypeDef usart_initstruct; usart_initstruct.BaudRate = 115200; usart_initstruct.DataWidth = LL_USART_DATAWIDTH_8B; usart_initstruct.StopBits = LL_USART_STOPBITS_1; usart_initstruct.Parity = LL_USART_PARITY_NONE; usart_initstruct.TransferDirection = LL_USART_DIRECTION_TX_RX; usart_initstruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; usart_initstruct.OverSampling = LL_USART_OVERSAMPLING_16; /* 根据初始化结构中定义的参数初始化 USART 实例 */ LL_USART_Init(USART1, &usart_initstruct); LL_USART_ConfigAsyncMode(USART1); /* (5) 启用 USART *********************************************************/ CLEAR_BIT(USART1->CR3, USART_CR3_OVRDIS); LL_USART_Enable(USART1); /* 轮询 USART 初始化 */ // while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))) { // } /* 启用 RXNE 和错误中断 */ LL_USART_EnableIT_RXNE(USART1); //LL_USART_EnableIT_ERROR(USART1); LL_USART_DisableIT_ERROR(USART1); allocate_hal_pin(USARTx_TX_GPIO_PORT, USARTx_TX_PIN); allocate_hal_pin(USARTx_RX_GPIO_PORT, USARTx_RX_PIN); } size_t read_uart(char * buf, size_t length) { size_t cnt = 0; for (int i = 0; i < length; ++i) { if(RingBufferEmpty(rxrb)) break; uint8_t ch; RingBufferGet(rxrb, &ch); buf
= ch; ++cnt; } return cnt; } size_t write_uart(const char *buf, size_t length) { for (int i = 0; i < length; ++i) { LL_USART_TransmitData8(USART1, buf
); while (!LL_USART_IsActiveFlag_TXE(USART1)) { } LL_USART_ClearFlag_TC(USART1); } return length; } ``` ##作品源码 启动器
bootldr.rar
(4.8 MB)
(下载次数: 2, 2022-11-5 20:41 上传)
主程序
Smoothie2.rar
(17.8 MB)
(下载次数: 2, 2022-11-5 20:42 上传)
##作品功能演示视频 ###运行输出结果
###界面运行效果 https://bbs.eeworld.com.cn/forum.php?mod=attachment&aid=NjUwNDQ0fDQ3MjRlMDhifDE2NjczOTgzNTF8NzUwODY4fDEyMjIxMTg%3D ##项目总结 首先感谢电子工程世界组织了这次活动,得捷电子提供此次物料,使我能够初步的实现3D打印机控制器基本功能。在此次开发中,由于踩坑填坑花费太多时间,代码还有很多缺陷,有待完善。但是从开发中也学习了很多原先没有接触过的外设驱动如QSPI,SDRAM,MPU等等知识,对以后的工作肯定大有裨益。 下一步计划是完善代码,把USB,网路,wifi功能实现出来,再在此基础上探索S曲线控制算法。
点赞
回复评论 (2)
沙发
caxfan
3D打印机控制器项目报告.docx
(23.24 MB)
(下载次数: 1, 2022-11-5 20:50 上传)
点赞
2022-11-5 20:53
板凳
lightxixi
界面运行效果演示视频:
VID_20221022_113633
在路上…… EEworld 有你有我
点赞
2022-11-9 11:44
最新活动
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
安世半导体理想二极管与负载开关,保障物联网应用的稳健高效运行
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
PI 电源小课堂|无 DC-DC 变换实现多路高精度输出反激电源
2024 瑞萨电子MCU/MPU工业技术研讨会——深圳、上海站, 火热报名中
随便看看
TI MSP430的脉搏血氧仪设计
AVR开发板
压力传感器的时漂和温漂
为什么我的MOSFET一直是导通的
Protel 2007
请教关于msp430串口波特率计算的问题
【LinkNode开发板测评】第二章 真容 绽放笑靥
CE6 中如何获得其他程序使用的内存空间
STC片子利用PCA模块做16bit timer产生方波输出问题
请问各位
瑞萨R7F0C802 做的充电电流检测
便携式应用中的有源电源管理
实时频谱分析基础知识--泰克
板子启动时提示的错,无法挂载temfs,求助
电动车新国标下的电动自行车与电动摩托车BMS解决方案
基于VB和RS-485总线技术的变频器远程监控系统设计
大家看看我编的程序,这到底是怎么了?
蓝牙欺骗漏洞影响数十亿物联网设备
关于无位置传感器无刷直流电机(BLDCM) 大钮矩/重载启动
如何确定LCD屏的VBPD,VFPD,VSPW,HBPD,HFPD,HSPW的值啊?(内附LCD屏资料)
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复