当前位置: 首页 > news >正文

学网站维护北京网络推广公司wyhseo

学网站维护,北京网络推广公司wyhseo,ppt图标网站链接怎么做,南昌信息推广平台STM32单片机项目实例#xff1a;基于TouchGFX的智能手表设计#xff08;5#xff09;硬件驱动层程序设计 目录 一、 概述 二、 新建工程与外设配置 三、 TouchGFX配置 四、 增加TouchGFX关键驱动 一、 概述 本文内容主要进行工程新建#xff0c;硬件外设的配置以及添加…STM32单片机项目实例基于TouchGFX的智能手表设计5硬件驱动层程序设计 目录 一、 概述 二、 新建工程与外设配置 三、 TouchGFX配置 四、 增加TouchGFX关键驱动 一、 概述 本文内容主要进行工程新建硬件外设的配置以及添加TouchGFX的屏幕、触摸NorFlash驱动主要以流程为主。 二、  新建工程与外设配置 新建工程选择STM32U575RIT6弹出的TrustZone选项选择without TrustZone activated。 Project Manager页面设置工程名0C-1_STM32U575_Hardware_Basic选择工程路径工具链选择MDK-ARM设置堆栈大小0x1200Code Generator页面Copy only the…Generate peripheral initialization as a pair…, Clock Configuration页面系统时钟选择PLLCK输出在HCLK框输入160后回车设置系统时钟频率为160MHz。 Pinout  Configuration 页面System Core栏中的ICACHE进行设置。 Pinout  Configuration 页面System Core栏中的RCC进行设置HSE与LSE设置位晶体谐振器。 返回至Clock Configuration页面HSE的外部输入频率设置为12。 Pinout  Configuration 页面Connectivity栏中设置SPI屏幕接口I2C触摸接口外部存储器的QSPI接口UART调试端口WiFi模组的通信口UART。首先是屏幕的SPI接口设置全双工主机按住ctrl光标移动到PA1端口点击左键拖拽SPI1_SCK至PA5并将PA6/PA7右键Signal Pinning进行端口锁定。 在SPI1的Parameter Settings栏中设置Data Size8Prescalerfor Baud Rate4。 在GPIO Settings中将PA5、PA6、PA7的Maximum outut speed设置为Very Hight。 返回到System Core栏中的GPIO对显示屏的控制引脚以及按键、LED灯与蜂鸣器进行设置。设置PA4为超高速PP输出修改用户标签为LCD_DCX设置PB10为低速PP输出初始电平为高修改用户标签为LCD_BL设置PA8为高速PP输出修改用户标签为LCD_RST设置PA12为下降沿触发修改用户标签为USER_KEY设置PA15为低速PP输出修改用户标签为RUN-BEEP设置PC13为低速PP输出修改用户标签为BLUE_LED。 对Connectivity栏中I2C1接口设置为I2C按住ctrl光标移动到PA3端口点击左键拖拽I2C1_SDA至PB7并将PB6/PB7右键Signal Pinning进行端口锁定。修改I2C Speed Mode为Fast Mode。 返回到System Core栏中的GPIO对触摸屏的控制引脚以进资源扩展板的外设行设置。设置PA0为双边沿触发修改用户标签为EXT-FIVEKEY设置PC6为低速PP输出修改用户标签为EXT-FAN设置PC6为低速PP输出修改用户标签为EXT-MOTOR设置PA11为低速PP输出修改用户标签为TP_RST设置PA12为下降沿触发修改用户标签为USER_KEY设置PB5为双边沿触发修改用户标签为TP_INT。 在NVIC中勾选EXTI Line0/ EXTI Line5全局中断使能。 对Connectivity栏中OCTOSPI1接口设置模式为Quad SPIClock选择Port1 CLKChip Select选择Port1 NCSData[3:0]选择Port1 IO[7:0]设置Fifo Threshold为8Device Size为24Clock Prescaler为2Sample Shiting为Half Cycle。右键将PC0、PC1、PC2、PC3、PA2、PA3固定。 对Connectivity栏中USART1进行设置mode设置Asynchronous并锁定PA9与PA10。 对Connectivity栏中UART5进行设置mode设置Asynchronous并锁定PD2与PC12。 在NVIC Settings中勾选UART5全局中断使能。 对Timers进行设置TIM16/TIM17分别设置5ms与100ms的中断用于任务的触发管理。 在NVIC Settings中勾选TIM16全局中断使能。 对Timers栏中的RTC进行设置 对Analog栏中的ADC1进行设置通道6、通道15、通道16设置为单端转换开启内部的VBAT、VREF以及芯片内部温度测量。 ADC参数设置一栏设置时钟分频÷4采样精度12位Enable Regular Conversions进行使能通道数量6连续扫描模式使能Rank1、Rank2、Rank3、Rank4、Rank5、Rank6分别对应通道6通道15通道16内部温度参考电压以及VBAT电压测量采样时间设置为391.5Cycles。启动DMA循环模式。 在System Core栏中对GPDMA进行设置通道0与通道1设置位标准请求模式通道0用于屏幕数据刷新通道1用于外部存储器的读写。 CH0的请求采用SPI1_TX通道配置的优先级高传输模式正常传输方向内存到外设源端地址自增使能采用半字传输目标地址自增禁止半字传输目标端口设置为1。 CH1采用循环模式端口选则Port1请求采用ADC1通道配置的优先级高传输模式正常传输方向外设到内存源端地址自增禁用采用半字传输源端端口设置Port1目标地址自增使能半字传输目标端口设置为Port1。 在System Core栏中对NVIC的优先级进行设置。  点击右上角的GENERATR CODE等待完成生成工程配置。 三、 TouchGFX配置 对Computing栏中的CRC进行设置。 对Middleware and Software Packs中的X-CUBE-TOUCHGFX进行选择4.21.2版本。 对Middleware and Software Packs中的X-CUBE-TOUCHGFX图形应用进行勾选。采用单缓冲设置宽度320与高度240。 点击右上角的GENERATR CODE等待完成生成工程配置。生成配置后的代码编译会报错需要打开TouchGFX 4.21.2 Designer软件进行一次配置与GUI代码的生成(注意工程路径中不能包含非法字符空格也不可以…)。 打开…\0C-2_STM32U575_Hardware_Basic\TouchGFX下的ApplicationTemplate.touchgfx.part点击右下角的/生成代码。 打开…\0C-2_STM32U575_Hardware_Basic\MDK-ARM下的0C-2_STM32U575_Hardware_Basic.uvprojx点击全编译编译0错误1警告可忽略该警告。 四、 增加TouchGFX关键驱动 将资料光盘中..\FS-STM32U575-WATCH(Release)\Drivers文件夹下的efsm-master、MAX30102_Maxim、Motion_Driver三个文件夹拷贝至新建工程目录..\0C-2_STM32U575_Hardware_Basic\Drivers下。 将资料光盘中.. \FS-STM32U575-WATCH(Release)\Core\Src文件夹下的bsp_ap3216c.c、bsp_esp8266.c、bsp_ft6336.c、bsp_ili9341_4line.c、bsp_ospi_w25q128.c、bsp_sht20.c、user_app.c拷贝至新建工程目录..\0C-2_STM32U575_Hardware_Basic\Core\Src下。 将资料光盘中.. \FS-STM32U575-WATCH(Release)\Core\Irc文件夹下的bsp_ap3216c.h、bsp_esp8266.h、bsp_ft6336.h、bsp_ili9341_4line.h、bsp_ospi_w25q128.h、bsp_sht20.h、user_app.h拷贝至新建工程目录..\0C-2_STM32U575_Hardware_Basic\Core\Irc下。 打开…\0C-2_STM32U575_Hardware_Basic\MDK-ARM下的0C-2_STM32U575_Hardware_Basic.uvprojx点击菜单栏的工程管理快捷图标在Groups中增加motion、efsm-master、MAX30102_Maxim组并在Files族中添加相应的.c文件。 在Application/User/Core中增加bsp_ap3216c.c、bsp_esp8266.c、bsp_ft6336.c、bsp_ili9341_4line.c、bsp_ospi_w25q128.c、bsp_sht20.c、user_app.c文件。 点击菜单栏的魔术棒图标在C/C(AC6)增加motion、efsm-master、MAX30102_Maxim的头文件路径。 打开main.c文件在Private includes的BEGIN与END之间增加以下代码如出现乱码调整编码格式为UTF-8。 /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include user_app.h //用户应用程序/* USER CODE END Includes */ 在Private define的BEGIN与END之间增加以下代码用于ADC的多通达数据采集。 /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define ADC_CONVERTED_DATA_BUFFER_SIZE 6 /* USER CODE END PD */ 在Private variables的BEGIN与END之间增加以下代码用于 任务标志组与ADC多通道采集。 /* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */ uint8_t gChatCount 10; //全局按键按压计数 extern gTask_MarkEN gTaskEnMark; //系统任务使能标识 static uint8_t gTaskIndex 0x00; //系统任务索引变量 extern volatile uint8_t TcpClosedFlag; ADC_ValTypeDef gStruADC{0,0,0,0,0,0}; //A/D通道实时采集的数据 /* USER CODE END PV */ 在Private function的BEGIN与END之间增加以下代码用于touchgfx接口声明与wifi模组数据接收。 /* USER CODE BEGIN PFP */ extern void touchgfx_signalVSynTimer(void); extern gTask_BitDef gTaskStateBit; //任务执行过程中使用到的标志位 volatile uint8_t gRX3_BufF[1]; //串口3-wifi模组接收到的数据 /* USER CODE END PFP */ 在Private user code的BEGIN与END之间增加半主机模式的设置与外部存储器测试。 /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /**************************关闭标准库下的半主机模式****************************/ __ASM (.global __use_no_semihosting); //AC6编译器 //标准库需要的支持函数 struct FILE {int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x x; } void _ttywrch(int ch) {ch ch; } //printf实现重定向 int fputc(int ch, FILE *f) {uint8_t temp[1] {ch};HAL_UART_Transmit(huart1, temp, 1, 2);return ch; } /******************************************************************************//******************************************************************************* * 函 数 名: OSPI_W25Qxx_mmap * 入口参数: 无 * 返 回 值: 无 * 函数功能: 设置为内存映射模式 * 说 明: 无 *******************************************************************************/ void OSPI_W25Qxx_mmap(void) //Flash读写测试 {int32_t OSPI_Status ; //检测标志位//OSPI_Status OSPI_W25Qxx_MemoryMappedMode(); //配置OSPI为内存映射模式if( OSPI_Status OSPI_W25Qxx_OK ){printf (\r\n内存映射模式设置成功\r\n); }else{printf (\r\n内存映射模式设置失败\r\n);Error_Handler();} } /* USER CODE END 0 */ 在main函数中增加相关外设的初始化配置。/* USER CODE BEGIN 2 */ //ESP8266初始化HAL库使用USART3 ESP8266_Init(huart5,(uint8_t *)gRX3_BufF,115200); ap3216c_init(); //环境光传感器初始化ILI9341_Init(); //显示屏初始化FT6336_init(); //触摸屏初始化 mpu_init_dmp(); //mpu6050 dmp初始化 System_Time_init(); //NOR Flash初始化OSPI_W25Qxx_Init(); //初始化W25Q128 OSPI_W25Qxx_mmap(); //设置为内存映射模式 HAL_PWREx_EnableVddA(); HAL_PWREx_EnableVddIO2();//清空任务列表 for(gTaskIndex 0;gTaskIndex OS_TASKLISTCNT;gTaskIndex) g_OSTsakList[gTaskIndex]NULL;//读取ADC值 if (HAL_ADC_Start_DMA(hadc1,(uint32_t *)gStruADC,ADC_CONVERTED_DATA_BUFFER_SIZE) ! HAL_OK) {Error_Handler();}/* USER CODE END 2 */ 在while (1)函数前增加任务调度的定时器使能。 /* Infinite loop *//* USER CODE BEGIN WHILE */HAL_TIM_Base_Start_IT(htim16);//开启定时器16开启,系统任务调度开始HAL_TIM_Base_Start_IT(htim17);//开启定时器17开启,设备控制任务开始 在while (1)函数中增加任务调度管理代码。 while (1){/* USER CODE END WHILE */MX_TouchGFX_Process();/* USER CODE BEGIN 3 *///执行任务列表中的的任务for(gTaskIndex 0;gTaskIndex OS_TASKLISTCNT;gTaskIndex){if((*g_OSTsakList[gTaskIndex]) ! NULL){g_OSTsakList[gTaskIndex]();g_OSTsakList[gTaskIndex] NULL; }}}/* USER CODE END 3 */ 在USER CODE BEGIN 4位置增加中断回调函数用于任务的调度、串口数据的接收处理。 /* USER CODE BEGIN 4 */ //定时器16/17的任务分配 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {static uint8_t p_Time16Cnt 0,p_Time17Cnt 0;/***************************************************************************************///定时器16进行5ms任务中断if (htim-Instance htim16.Instance) {p_Time16Cnt;//if(!(p_Time16Cnt % 4)) //20ms(50Hz)进行触发刷新{touchgfx_signalVSynTimer(); //touchgfx用户接口}//五项按键读取if(!(p_Time16Cnt % 20)) //100ms进行一次窗口更新{if(gTaskStateBit.TouchPress 0) {g_OSTsakList[eUPDATE_FIVEKEY] Update_FiveKey_Value; //更新五向键数据 }}//1000ms运行一次系统运行指示灯if(!(p_Time16Cnt % 200)) {p_Time16Cnt 0; HAL_GPIO_TogglePin(BLUE_LED_GPIO_Port,BLUE_LED_Pin);}}/***************************************************************************************///定时器17进行100ms任务中断if (htim-Instance htim17.Instance) { p_Time17Cnt;//周期为200ms任务if(!(p_Time17Cnt % 2)) //200ms进行一次下列代码{if((gTaskEnMark.UPDATE_DIAL_EN || gTaskEnMark.UPDATE_SIX_AXIS_EN) (gTaskStateBit.TouchPress 0)) {g_OSTsakList[eUPDATE_SIX_AXIS] Update_EulerAngle; //欧拉角更新}}//周期为300ms任务if(!(p_Time17Cnt % 3)) //300ms进行一次下列代码{if(gTaskEnMark.UPDATE_WIFI_RSSI_EN) g_OSTsakList[eUPDATE_WIFI_RSSI] ESP8266_RSSI_Task; //获取wifi连接的RSSI值 } //周期为500ms任务if(!(p_Time17Cnt % 5)) //500ms进行一次下列代码{if(gTaskEnMark.UPDATE_CHIPPAGE) g_OSTsakList[eUPDATE_CHIPINFO] Update_ChipInfo; //系统信息更新}//周期为1000ms任务if(!(p_Time17Cnt % 10)) //1s进行一次下列代码{if(gTaskEnMark.UPDATE_DIAL_EN (gTaskStateBit.TouchPress 0)){g_OSTsakList[eUPDATE_TIME] Update_System_Time; //系统时间更新} }//周期为2000ms任务 if(!(p_Time17Cnt % 20)) //2s进行一次下列代码{if((gTaskEnMark.UPDATE_DIAL_EN || gTaskEnMark.UPDATE_INFOPAGE) (gTaskStateBit.TouchPress 0)){g_OSTsakList[eUPDATE_DIAL_INFO] Update_DialInfo; //更新电压、电流、温湿度、光照度} } //周期为3000ms任务if(!(p_Time17Cnt % 30)) //3s进行一次下列代码{//心率任务会阻塞主程序if(gTaskEnMark.UPDATE_HEALTHPAGE) {g_OSTsakList[eUPDATE_HEART_RATE] Update_HeartRateInfo; //获取健康信息} }//周期为10000ms任务if(!(p_Time17Cnt % 100)) //10s进行一次下列代码{p_Time17Cnt 0; }}/***************************************************************************************//* Prevent unused argument(s) compilation warning */UNUSED(htim); } /*** brief EXTI line rising detection callback.* param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.* retval None*/ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) {/* Prevent unused argument(s) compilation warning */UNUSED(GPIO_Pin);//触摸按下事件if((!HAL_GPIO_ReadPin(TP_INT_GPIO_Port,TP_INT_Pin)) (GPIO_Pin TP_INT_Pin)){gTaskStateBit.TouchPress 1;}if(!HAL_GPIO_ReadPin(USER_KEY_GPIO_Port,USER_KEY_Pin)){gChatCount gChatCount 10;if(gChatCount100) gChatCount10;} } void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin) {/* Prevent unused argument(s) compilation warning */UNUSED(GPIO_Pin);//触摸释放事件if(HAL_GPIO_ReadPin(TP_INT_GPIO_Port,TP_INT_Pin) gTaskStateBit.TouchPress){FT6336_irq_fuc(); //触摸中断产生gTaskStateBit.TouchPress 0; //清除触摸标志 }//五向按键按下if(HAL_GPIO_ReadPin(EXT_FIVEKEY_GPIO_Port,EXT_FIVEKEY_Pin) (GPIO_Pin EXT_FIVEKEY_Pin) (gTaskStateBit.TouchPress 0)){gTaskStateBit.FiveKeyPress 1; } } /*** brief Conversion complete callback in non blocking mode * param hadc: ADC handle* note This example shows a simple way to report end of conversion* and get conversion result. You can add your own implementation.* retval None*/ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {//更新DMA传输状态标志gTaskStateBit.ADCC 1; } /*** brief Rx Transfer completed callback.* param huart UART handle.* retval None*/ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {//USART3接收数据if (huart-Instance UART5) {if(ESP8266_Fram_Record_Struct .InfBit .FramLength ( RX_BUF_MAX_LEN - 1 ) ) //接收到的数据存储至buffer{//留最后一位做结束位ESP8266_Fram_Record_Struct .Data_RX_BUF[ ESP8266_Fram_Record_Struct .InfBit .FramLength ] gRX3_BufF[0]; //UART3开启下一次接收HAL_UART_Receive_IT(huart5,(uint8_t *)gRX3_BufF, 1);//接收一个字节} }} /*** brief UART Abort Receive Complete callback.* param huart UART handle.* retval None*/ void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) {//USART3帧传输完成产生空闲if (huart-Instance UART5){ESP8266_Fram_Record_Struct .InfBit .FramFinishFlag 1; //帧传输完成标志TcpClosedFlag strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, CLOSED\r\n ) ? 1 : 0; //判断连接//UART3开启下一次接收HAL_UART_Receive_IT(huart5,(uint8_t *)gRX3_BufF, 1);//接收一个字节} } /* USER CODE END 4 */ 在stm32u5xx_it.c文件中UART5_IRQHandler中断函数中增加空闲中断判断。 void UART5_IRQHandler(void) {/* USER CODE BEGIN UART5_IRQn 0 *//* USER CODE END UART5_IRQn 0 */HAL_UART_IRQHandler(huart5);/* USER CODE BEGIN UART5_IRQn 1 */if (__HAL_UART_GET_FLAG(huart5, UART_FLAG_IDLE) ! RESET) { __HAL_UART_CLEAR_IDLEFLAG(huart5); HAL_UART_AbortReceive_IT(huart5); }/* USER CODE END UART5_IRQn 1 */ } 在TouchGFXHAL.cpp文件中增加头文件包含。 /* USER CODE BEGIN TouchGFXHAL.cpp */ #include touchgfx/hal/OSWrappers.hpp //用户外设驱动头文件 #include spi.h #include stm32u5xx_hal.h // extern C void ILI9341_SetArea(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); //设置显示区域 extern C void ILI9341_WriteRAM_Prepare(void); // extern SPI_HandleTypeDef hspi1; extern DMA_HandleTypeDef handle_GPDMA1_Channel0; // 增加屏幕的DMA刷新函数 /** * Sets the frame buffer address used by the TFT controller.** param [in] address New frame buffer address.*/ void TouchGFXHAL::setTFTFrameBuffer(uint16_t* address) {// Calling parent implementation of setTFTFrameBuffer(uint16_t* address).//// To overwrite the generated implementation, omit call to parent function// and implemented needed functionality here.TouchGFXGeneratedHAL::setTFTFrameBuffer(address); } static void USER_SPI_Transmit_DMA(const uint16_t *pData, uint16_t pSize) {//Set the transaction informationhspi1.State HAL_SPI_STATE_READY;hspi1.ErrorCode HAL_SPI_ERROR_NONE;//Init field not used in handle to zerohspi1.RxISR NULL;hspi1.TxISR NULL;//Configure communication direction : 1LineSPI_2LINES_TX(hspi1);// Packing mode management is enabled by the DMA settingsIS_SPI_FULL_INSTANCE(hspi1.Instance);//Clear TXDMAEN bitCLEAR_BIT(hspi1.Instance-CFG1, SPI_CFG1_TXDMAEN);//Update the DMA channel statehandle_GPDMA1_Channel0.State HAL_DMA_STATE_BUSY;//Update the DMA channel error codehandle_GPDMA1_Channel0.ErrorCode HAL_DMA_ERROR_NONE;//Configure the source address, destination address, the data size and clear flagsMODIFY_REG(handle_GPDMA1_Channel0.Instance-CBR1, DMA_CBR1_BNDT, ((pSize) DMA_CBR1_BNDT));//Clear all interrupt flags__HAL_DMA_CLEAR_FLAG(handle_GPDMA1_Channel0, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |DMA_FLAG_TO);//Configure DMA channel source addresshandle_GPDMA1_Channel0.Instance-CSAR (uint32_t)pData;//Configure DMA channel destination addresshandle_GPDMA1_Channel0.Instance-CDAR (uint32_t)hspi1.Instance-TXDR;//Enable common interrupts: Transfer Complete and Transfer Errors ITs__HAL_DMA_ENABLE_IT(handle_GPDMA1_Channel0, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO));//If Half Transfer complete callback is set, enable the corresponding IT__HAL_DMA_ENABLE_IT(handle_GPDMA1_Channel0, DMA_IT_HT);//Enable DMA channel__HAL_DMA_ENABLE(handle_GPDMA1_Channel0);//Set the number of data at current transferMODIFY_REG(hspi1.Instance-CR2, SPI_CR2_TSIZE, (pSize));//Enable Tx DMA RequestSET_BIT(hspi1.Instance-CFG1, SPI_CFG1_TXDMAEN);//Enable the SPI Error Interrupt Bit__HAL_SPI_ENABLE_IT(hspi1, (SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));//Enable SPI peripheral__HAL_SPI_ENABLE(hspi1);//if (((hspi1.Instance-AUTOCR SPI_AUTOCR_TRIGEN) 0U) (hspi1.Init.Mode SPI_MODE_MASTER)){/* Master transfer start */SET_BIT(hspi1.Instance-CR1, SPI_CR1_CSTART);} } 在flushFrameBuffer函数中增加屏幕刷新功能。 /*** This function is called whenever the framework has performed a partial draw.** param rect The area of the screen that has been drawn, expressed in absolute coordinates.** see flushFrameBuffer().*/ static uint16_t flushAreaBuf[31745]; //62KB区域性刷新缓冲区 void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect rect) {// Calling parent implementation of flushFrameBuffer(const touchgfx::Rect rect).//// To overwrite the generated implementation, omit call to parent function// and implemented needed functionality here.// Please note, HAL::flushFrameBuffer(const touchgfx::Rect rect) must// be called to notify the touchgfx framework that flush has been performed.// To calculate he start adress of rect,// use advanceFrameBufferToRect(uint8_t* fbPtr, const touchgfx::Rect rect)// defined in TouchGFXGeneratedHAL.cpp/*************************************屏幕刷新开始*************************************/__IO uint16_t *pixels; //帧缓冲地址__IO uint16_t pheight 0,pWidth 0,pBuffCnt 0;//保存长度__IO uint32_t pTotalPixel rect.width * rect.height * 2;__IO uint32_t pFull pTotalPixel / 63488; //62KB取整__IO uint32_t pRemain pTotalPixel % 63488; //62KB取余//设置显示区域ILI9341_SetArea(rect.x, rect.y,rect.xrect.width-1, rect.yrect.height-1);ILI9341_WriteRAM_Prepare(); //开始写入GRAM //设置SPI数据格式为16位缓冲区数据采用小端模式ILI9341数据传输高字节在前hspi1.Instance-CFG1 (~0x1F);hspi1.Instance-CFG1 | SPI_DATASIZE_16BIT; //if((rect.width 320) (rect.height 240)) //采用横屏整个屏幕刷新{//获取像素点地址pixels getClientFrameBuffer() rect.x (rect.y) * HAL::DISPLAY_WIDTH; //传输长度为62KB的像素点for (pBuffCnt 0; pBuffCnt pFull; pBuffCnt){//启动DMA传输USER_SPI_Transmit_DMA((uint16_t *)pixels,63488); //DMA单次传输最长0xFFFF//pixels pixels 31744; //地址偏移//等待DMA传输完成while(HAL_DMA_GetState(handle_GPDMA1_Channel0) ! HAL_DMA_STATE_READY); //适当延时HAL_Delay(0); //阻塞模式下终止正在的传输HAL_SPI_Abort(hspi1);}//启动DMA传输USER_SPI_Transmit_DMA((uint16_t *)pixels,pRemain); //剩余数据传输//等待DMA传输完成while(HAL_DMA_GetState(handle_GPDMA1_Channel0) ! HAL_DMA_STATE_READY); //适当延时HAL_Delay(0);//阻塞模式下终止正在的传输HAL_SPI_Abort(hspi1);}else //屏幕区域刷新{for (pheight 0; pheight rect.height; pheight){//缓冲区数据采用小端模式ILI9341数据传输高字节在前pixels getClientFrameBuffer() rect.x (pheight rect.y) * HAL::DISPLAY_WIDTH;//读取限度点至缓冲区for (pWidth 0; pWidth rect.width; pWidth){flushAreaBuf[pBuffCnt] *pixels; //读取像素点pixels; //调整偏移地址if(pBuffCnt 31744) //缓冲区数据满传输数据至屏幕{//启动DMA传输USER_SPI_Transmit_DMA((uint16_t *)flushAreaBuf,63488);//等待DMA传输完成while(HAL_DMA_GetState(handle_GPDMA1_Channel0) ! HAL_DMA_STATE_READY); //适当延时HAL_Delay(0);//阻塞模式下终止正在的传输HAL_SPI_Abort(hspi1);//复位计数值pBuffCnt 0;}}}//启动DMA传输USER_SPI_Transmit_DMA((uint16_t *)flushAreaBuf,pBuffCnt * 2);//等待DMA传输完成while(HAL_DMA_GetState(handle_GPDMA1_Channel0) ! HAL_DMA_STATE_READY); //适当延时HAL_Delay(0);//阻塞模式下终止正在的传输HAL_SPI_Abort(hspi1);}//设置SPI数据格式为8位hspi1.Instance-CFG1 (~0x1F);hspi1.Instance-CFG1 | SPI_DATASIZE_8BIT; /*************************************屏幕刷新完成*************************************///TouchGFXGeneratedHAL::flushFrameBuffer(rect); } 增加touchGFX的同步刷新函数。 bool TouchGFXHAL::beginFrame() {return TouchGFXGeneratedHAL::beginFrame(); }void TouchGFXHAL::endFrame() {TouchGFXGeneratedHAL::endFrame(); }extern C void touchgfx_signalVSynTimer(void) {/* VSync has occurred, increment TouchGFX engine vsync counter */HAL::getInstance()-vSync();/* VSync has occurred, signal TouchGFX engine */OSWrappers::signalVSync(); } /* USER CODE END TouchGFXHAL.cpp */ 在STM32TouchController.cpp函数中增加触摸屏驱动接口。 void STM32TouchController::init() {/*** Initialize touch controller and driver**/ }extern C {#include bsp_ft6336.h } // extern C FT6336_TouchPointType tp; extern volatile uint32_t ft6336_on_touch_count; // bool STM32TouchController::sampleTouch(int32_t x, int32_t y) {/*** By default sampleTouch returns false,* return true if a touch has been detected, otherwise false.** Coordinates are passed to the caller by reference by x and y.** This function is called by the TouchGFX framework.* By default sampleTouch is called every tick, this can be adjusted by HAL::setTouchSampleRate(int8_t);**/uint16_t xDiff 0,yDiff 0; static uint16_t pI_Touch_X 0, pI_Touch_Y 0;//触摸中断产生if (ft6336_on_touch_count) // irq done{uint8_t id1 FT6336_read_touch1_id(); // id1 0 or 1tp.tp[id1].status (tp.tp[id1].status release) ? touch : stream;tp.tp[id1].x FT6336_read_touch1_x();tp.tp[id1].y FT6336_read_touch1_y();tp.tp[~id1 0x01].status release;//更新数据至TouchGFXif (tp.tp[0].status 1) //最多支持两个触点{ xDiff tp.tp[0].x pI_Touch_X ? (tp.tp[0].x - pI_Touch_X): (pI_Touch_X - tp.tp[0].x);yDiff tp.tp[0].y pI_Touch_Y ? (tp.tp[0].y - pI_Touch_Y): (pI_Touch_Y - tp.tp[0].y);//判断阈值if ((xDiff yDiff) 5){pI_Touch_X tp.tp[0].x;pI_Touch_Y tp.tp[0].y;}//更新触摸,横屏触摸坐标变换x pI_Touch_Y;y 240 - pI_Touch_X;}ft6336_on_touch_count 0;//return true;}//return false; } 点击菜单栏的魔术棒在Linker栏中设置分散加载文件。 在.sct文件中增加外部存储器的加载描述。 ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; *************************************************************LR_IROM1 0x08000000 0x00200000 { ; load region size_regionER_IROM1 0x08000000 0x00200000 { ; load address execution address*.o (RESET, First)*(InRoot$$Sections).ANY (RO).ANY (XO)}RW_IRAM1 0x20000000 0x000C0000 { ; RW data.ANY (RW ZI)} }LR_EROM1 0x90000000 0x1000000 { ; load region size_regionER_EROM1 0x90000000 0x1000000 { ; load address execution address*.o (ExtFlashSection)} } 修改完成后保存文件。重新打开设置栏查看注意是否去掉3中的勾选。。。。 点击菜单栏的魔术棒在Debug栏中设置加载算法文件算法加载文件的方法可以查看《STM32U5核心板NOR-Flash烧写算法的使用v1.0》。 点击全编译工程至此底层驱动文件的添加完成。
http://www.zqtcl.cn/news/526096/

相关文章:

  • 徐州金桥建设监理有限公司网站那个网站做系统好
  • 浙江网站制作做一个自我介绍的网页
  • 郑州做网站公司有多少网站建设需要自备什么
  • 齐齐哈尔网站seo重庆旅游
  • 顺德品牌网站建设信息网络编程课程
  • 广西南宁建设职业学图书馆网站wordpress 黑色主题
  • 网站建设需要准备那些内容阜阳微商城网站建设
  • flash全屏网站模板企业网站示例
  • 制作手机端网站开发厦门网站设计定制
  • 佛山网站开发公司做网站在什么地方发帖子呢
  • 无网站可以做cpc吗wordpress 12张表
  • 有些中小网站cnzz网站排名是怎么做的
  • 深圳做微商网站的公司高端做网站价格
  • 在线原型设计网站wordpress菜单页内跳转
  • 做电影网站要买什么抖音推广怎么收费
  • 专业的公司网站开发网站按钮设计
  • 南宁网站建设是什么深圳公司有哪些
  • 杭州手机申请网站登录怎么做电子商务网站
  • 青岛个人接网站建设wordpress 转载文章
  • 网上做网站任务网络营销传播的核心内容
  • 做黑界头像网站成考过来人的忠告
  • 宁波网站建设是哪家便宜织梦网站数据库备份文件夹
  • 在北京大学生做家教的网站淘宝网页
  • 英铭网站建设网站如何推广引流
  • 关于电子商务网站建设的现状企业公示信息查询系统山西
  • 网站开发 翻译长春建站企业
  • dedecms网站网站解析一般什么时候
  • 制作网站的技术北京律师24小时电话
  • 可拖拽 网站建设如何做自媒体和网站签约赚点击
  • 做网站选哪个语言怎么登录百度app