/********************** * STATIC FUNCTIONS **********************/ static inline void execute_drawing_unit(lv_draw_sw_unit_t * u) { execute_drawing(u); u->task_act->state = LV_DRAW_TASK_STATE_READY; u->task_act = NULL; /*The draw unit is free now. Request a new dispatching as it can get a new task*/ lv_draw_dispatch_request(); }

时间: 2025-04-14 22:53:55 浏览: 35
<think>好的,用户让我介绍一下LVGL中的`execute_drawing_unit`函数,我之前已经帮他分析过`dispatch`函数,现在需要继续这个主题。首先,我需要仔细看看用户提供的代码片段。这个函数是静态内联的,可能和任务执行有关。 首先,函数名是`execute_drawing_unit`,参数是`lv_draw_sw_unit_t *u`。里面调用了`execute_drawing(u)`,然后设置任务状态为就绪,并将任务指针置空,最后调用`lv_draw_dispatch_request`。看起来这个函数负责执行实际的绘制任务,并在完成后触发新的任务调度。 接下来,我需要确认这个函数在之前提到的`dispatch`函数中的位置。之前在`dispatch`函数中,当没有使用OS时,直接调用了`execute_drawing_unit`,而在有OS的情况下是通过线程信号触发的。所以这个函数应该是实际执行绘制操作的地方。 用户可能想了解这个函数的具体作用,以及它和整个渲染流程的关系。需要分步骤解释每个代码行的作用,并说明其在整个系统中的地位。可能还需要对比多线程和单线程环境下的不同处理方式。 另外,用户之前的问题涉及到了任务的状态管理,这里在`execute_drawing_unit`中将任务状态设为`READY`,并清空`task_act`,这可能是为了标记任务完成,释放资源。同时调用`lv_draw_dispatch_request`来请求新的任务分发,这可能是为了保持渲染循环持续进行,避免任务堆积或延迟。 需要确保解释清晰,结构合理,用用户能理解的语言。同时注意代码中的关键点,比如静态内联函数的作用、任务状态的变化、以及调度请求的触发。可能还需要提到性能优化,比如内联函数减少调用开销,或者多线程环境下的协作机制。 最后,总结这个函数的作用,强调它在整个绘制流程中的重要性,比如如何确保任务正确执行并有效管理资源,以及如何与调度器协同工作,保持渲染的高效性。需要确保用户理解每个步骤的意义,以及它们如何共同支持LVGL的渲染机制。</think>在LVGL中,`static inline void execute_drawing_unit(lv_draw_sw_unit_t * u)` 是软件渲染单元的核心执行函数,负责**直接执行绘制操作**并触发任务调度。以下是逐层解析: --- ### **函数逻辑解析** #### 1. **执行实际绘制操作** ```c execute_drawing(u); ``` - **核心绘制调用**:`execute_drawing(u)` 是具体绘制逻辑的入口,可能包含对图形元素(如矩形、文本、图像)的渲染实现。 - **实现细节**:此函数内部会根据任务类型(`u->task_act`)调用不同的绘制函数,例如 `lv_draw_rect` 或 `lv_draw_label`。 #### 2. **更新任务状态** ```c u->task_act->state = LV_DRAW_TASK_STATE_READY; u->task_act = NULL; ``` - **标记任务完成**:将当前任务的 `state` 设为 `READY`,通知系统该任务已处理完毕。 - **释放资源**:清空 `task_act` 指针,表示当前渲染单元空闲,可接收新任务。 #### 3. **触发新一轮任务调度** ```c lv_draw_dispatch_request(); ``` - **动态调度**:主动请求调度器检查是否有待处理任务,确保绘制流水线持续运行。 - **避免阻塞**:防止因任务队列空闲导致界面更新停滞。 --- ### **关键设计特性** #### 1. **静态内联函数优化** - **性能提升**:通过 `static inline` 避免函数调用开销,适合高频调用的核心路径。 - **编译期展开**:代码直接嵌入调用处,减少跳转指令,提升渲染效率。 #### 2. **与调度器的协同** - **状态驱动**:通过修改 `task_act` 和任务状态,实现与 `dispatch()` 函数的松耦合交互。 - **多线程兼容**:若启用 `LV_USE_OS`,此函数可能在独立线程中执行,需保证线程安全。 #### 3. **任务生命周期管理** - **状态流转**:任务从 `IN_PROGRESS` 到 `READY` 的转换,标志其生命周期结束。 - **资源释放**:`task_act = NULL` 隐式释放对任务对象的占用,允许其他单元处理新任务。 --- ### **典型执行流程** 1. **任务就绪**:`dispatch()` 函数将任务绑定到 `draw_sw_unit->task_act`。 2. **执行绘制**:`execute_drawing_unit` 调用具体渲染逻辑。 3. **状态更新**:任务标记为完成,单元置为空闲。 4. **调度循环**:通过 `lv_draw_dispatch_request()` 重新触发调度,形成“渲染-调度-渲染”闭环。 --- ### **应用场景** - **同步渲染**:在单线程环境(如裸机)中,直接调用此函数完成绘制。 - **异步渲染**:在多线程模式下,此函数可能作为线程入口,与主线程并行执行。 - **性能敏感操作**:高频刷新的动画或复杂UI,依赖此函数的轻量级设计保证实时性。 此函数是LVGL软件渲染的“最后一环”,直接决定图形输出的性能和正确性。
阅读全文

相关推荐

/*************************************************************************** * @file power_data.c * @brief * **************************************************************************** * @attention * * Created on: 2025-05-12 * Author: YL Monitor Software group * **************************************************************************** * @description * 功率部件的数据缓存处理模块 * * ****************************************************************************/ /************************ Includes *************************/ /************************ 宏指令 *************************/ #include "power_data.h" /************************ Private types *************************/ /************************ Private constants *************************/ /************************ 功能结构体 *************************/ typedef enum{ CACHE_L1_LOADING = 0xA1,/*正在加载数据*/ CACHE_L1_READY = 0xA2,/*数据就绪*/ CACHE_L1_SENT = 0xA2,/*数据已上传至LEVEL2*/ }ENUM_CACHE_L1_STATUS; typedef enum{ CACHE_L2_SENDING = 0x55,/*数据待上传*/ CACHE_L2_SENT = 0xAA,/*数据已上传*/ }ENUM_CACHE_L2_STATUS; /************************ Private macros *************************/ /************************ Private variables *************************/ /************************ 私有变量 *************************/ #if !SERIAL1_DMARx_ENABLE //禁用DMA1读取 0 /* 一级数据缓存:用于功率部件接收数据的实时缓存 */ uint8_t power1_data_cache_L1[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power1_L1 = NULL; /* 一级缓存当前数据写入位置 */ static uint16_t power1_L1_wPos = 0; /* 一级数据缓存状态 */ static uint16_t power1_L1_status = CACHE_L1_LOADING; #endif #if !SERIAL2_DMARx_ENABLE //禁用DMA2读取 0 /* 一级数据缓存:用于功率部件接收数据的实时缓存 */ uint8_t power2_data_cache_L1[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power2_L1 = NULL; /* 一级缓存当前数据写入位置 */ static uint16_t power2_L1_wPos = 0; /* 一级数据缓存状态 */ static uint16_t power2_L1_status = CACHE_L1_LOADING; #endif /* 二级数据缓存:用于系统状态监控 */ static uint8_t power1_data_cache_L2[POWER_DEVICE_DATA_SIZE] = {0}; static uint8_t power2_data_cache_L2[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power1_L2 = NULL; static SemaphoreHandle_t mutex_RW_Power2_L2 = NULL; /* 二级数据缓存状态 */ static uint8_t power1_L2_status = CACHE_L2_SENDING; static uint8_t power2_L2_status = CACHE_L2_SENDING; /************************ Functions *************************/ /************************ 功能函数 *************************/ /************************************************************ * @funName : MD_SwInitPowerData * @Input : NULL * * @Output : ***************** * @Description : 数据缓存模块软件资源初始化 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void MD_SwInitPowerData(void) { #if !SERIAL1_DMARx_ENABLE if(NULL == mutex_RW_Power1_L1) { mutex_RW_Power1_L1 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power1_L1) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power1_L1); } } #endif #if SERIAL2_DMARx_ENABLE #else if(NULL == mutex_RW_Power2_L1) { mutex_RW_Power2_L1 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power2_L1) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power2_L1); } } #endif if(NULL == mutex_RW_Power1_L2) { mutex_RW_Power1_L2 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power1_L2) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power1_L2); } } if(NULL == mutex_RW_Power2_L2) { mutex_RW_Power2_L2 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power2_L2) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power2_L2); } } } /************************************************************ * @funName : MD_UpdatePowerL2 * @Input : device-功率部件序号 * * @Output : ***************** * @Description : 更新功率部件二级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void MD_UpdatePowerL2(const uint8_t device) { switch(device) { case POWER_DEVICE_1: { #if SERIAL1_DMARx_ENABLE if(BSP_GetRecvSize4Serial1() >= POWER_DEVICE_DATA_SIZE) { uint8_t rbuf[POWER_DEVICE_DATA_SIZE] = {0}; uint16_t rlen = 0; BSP_Recv4Serial1(rbuf, &rlen); if(rlen >= POWER_DEVICE_DATA_SIZE){ portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power1_data_cache_L2, (uint8_t*)rbuf, POWER_DEVICE_DATA_SIZE); power1_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } } #else if(CACHE_L1_READY == power1_L1_status) { portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power1_data_cache_L2, (uint8_t*)power1_data_cache_L1, POWER_DEVICE_DATA_SIZE); power1_L1_status = CACHE_L1_SENT; power1_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } #endif }break; case POWER_DEVICE_2: { #if SERIAL2_DMARx_ENABLE if(BSP_GetRecvSize4Serial2() >= POWER_DEVICE_DATA_SIZE) { uint8_t rbuf[POWER_DEVICE_DATA_SIZE] = {0}; uint16_t rlen = 0; BSP_Recv4Serial2(rbuf, &rlen); if(rlen >= POWER_DEVICE_DATA_SIZE){ portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power2_data_cache_L2, (uint8_t*)rbuf, POWER_DEVICE_DATA_SIZE); power2_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } } #else if(CACHE_L1_READY == power2_L1_status) { portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power2_data_cache_L2, (uint8_t*)power2_data_cache_L1, POWER_DEVICE_DATA_SIZE); power1_L1_status = CACHE_L1_SENT; power2_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } #endif }break; } } /************************************************************ * @funName : MD_UpdatePowerL1 * @Input : device-功率部件序号 * bFirst-是否为第一个数据 * wbuf-数据 * wlen-数据长度 * * @Output : ***************** * @Description : 更新功率部件一级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ //static uint8_t byte = 0; void MD_UpdatePowerL1(const uint8_t device, const bool bFirst, const uint8_t* wbuf, const uint16_t wlen) { uint16_t len = wlen; if(wlen <= 0) { return; } switch(device) { case POWER_DEVICE_1: { #if SERIAL1_DMARx_ENABLE #else if(bFirst) { power1_L1_status = CACHE_L1_LOADING; power1_L1_wPos = 0; memset((uint8_t*)power1_data_cache_L1, 0, POWER_DEVICE_DATA_SIZE); } if(len > POWER_DEVICE_DATA_SIZE - power1_L1_wPos) { len = POWER_DEVICE_DATA_SIZE - power1_L1_wPos; } portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)&power1_data_cache_L1[power1_L1_wPos], wbuf, len); power1_L1_wPos += len; xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); if(POWER_DEVICE_DATA_SIZE <= power1_L1_wPos) { power1_L1_status = CACHE_L1_READY; } #endif }break; case POWER_DEVICE_2: { #if SERIAL2_DMARx_ENABLE #else if(bFirst) { power2_L1_status = CACHE_L1_LOADING; power2_L1_wPos = 0; memset((uint8_t*)power2_data_cache_L1, 0, POWER_DEVICE_DATA_SIZE); } if(len > POWER_DEVICE_DATA_SIZE - power2_L1_wPos) { len = POWER_DEVICE_DATA_SIZE - power2_L1_wPos; } portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)&power2_data_cache_L1[power2_L1_wPos], wbuf, len); power2_L1_wPos += len; xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); if(POWER_DEVICE_DATA_SIZE <= power2_L1_wPos) { power2_L1_status = CACHE_L1_READY; } #endif }break; } } /********************功率部件一级缓存数据********************/ /************************************************************ * @funName : MD_ReadPowerL2 * @Input : device-功率部件序号 * rbuf-数据输出缓存 * pos-数据读取位置 * rlen-数据读取长度 * * @Output : ***************** * @Description : 获取功率部件二级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/13 * *************************************************************/ bool MD_ReadPowerL2(const uint8_t device, uint8_t *rbuf, const uint16_t pos, const uint16_t rlen) { if(rlen > POWER_DEVICE_DATA_SIZE || pos >= POWER_DEVICE_DATA_SIZE || POWER_DEVICE_DATA_SIZE - pos < rlen) { return false; } switch(device) { case POWER_DEVICE_1: { xSemaphoreTake(mutex_RW_Power1_L2, portMAX_DELAY); memcpy(rbuf, (uint8_t*)&power1_data_cache_L2[pos], rlen); xSemaphoreGive(mutex_RW_Power1_L2); }break; case POWER_DEVICE_2: { xSemaphoreTake(mutex_RW_Power2_L2, portMAX_DELAY); memcpy(rbuf, (uint8_t*)&power2_data_cache_L2[pos], rlen); xSemaphoreGive(mutex_RW_Power2_L2); }break; } return true; } /************************************************************ * @funName : MD_GetPowerL2 * @Input : device-功率部件序号 * rbuf-数据缓存地址 * * @Output : ***************** * @Description : 获取功率部件二级缓存地址 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/13 * *************************************************************/ uint8_t* MD_GetPowerL2(const uint8_t device) { uint8_t* addr = NULL; switch(device) { case POWER_DEVICE_1: { xSemaphoreTake(mutex_RW_Power1_L2, portMAX_DELAY); if(CACHE_L2_SENDING != power1_L2_status) { addr = NULL; } else { power1_L2_status = CACHE_L2_SENT; addr = power1_data_cache_L2; } xSemaphoreGive(mutex_RW_Power1_L2); }break; case POWER_DEVICE_2: { xSemaphoreTake(mutex_RW_Power2_L2, portMAX_DELAY); if(CACHE_L2_SENDING != power2_L2_status) { addr = NULL; } else{ power2_L2_status = CACHE_L2_SENT; addr = power2_data_cache_L2; } xSemaphoreGive(mutex_RW_Power1_L2); }break; } return addr; } /************************ End of file *************************/ /*************************************************************************** * @file fw_data.h * @brief This file contains the macros & function about real data for framework & App. * **************************************************************************** * @attention * * Created on: 2025-05-30 * Author: YL Monitor Software group * **************************************************************************** * @description * * * ****************************************************************************/ #ifndef __FW_DATA_H_ #define __FW_DATA_H_ #ifdef __cplusplus extern "C" { #endif /************************ Includes *************************/ #include "main.h" /************************ Exportd types ********************/ typedef struct{ uint8_t byte_H; uint8_t byte_L; }Power_Bits16; typedef struct{ uint8_t byte0; uint8_t byte1; uint8_t byte2; uint8_t byte3; }Power_Bits32; /* 功率部件系统参数 */ typedef struct{ /* word 0 */ Power_Bits16 Reserved0; //0-预留 /* word 1 */ Power_Bits16 SYSCTRL; //1-系统控制 /* word 2 */ Power_Bits16 Flag; //2-系统状态标志 /* word 3 */ Power_Bits16 ProtectHard_PROHARD; //3-硬件保护标志 /* word 4 */ Power_Bits16 ProtectSoft_PROSOFT; //4-软件保护标志 /* word 5 */ Power_Bits16 ProtectDrive_PRODRIVE; //5-驱动保护标志 /* word 6 */ Power_Bits16 ProtectComm_PROCOMM; //6-通信保护标志 /* word 7 */ Power_Bits16 INVCTRL; //7-逆变器控制 /* word 8 */ Power_Bits16 Reserved8; //预留 /* word 9 */ Power_Bits16 Reserved9; //预留 /* word 10 */ Power_Bits16 Reserved10; //预留 /* word 11 */ Power_Bits32 GPADAT_H; //GPIO0~31状态 /* word 12 */ Power_Bits32 GPADAT_L; //GPIO0~31状态 /* word 13*/ Power_Bits32 GPBDAT_H; //GPIO32~63状态 /* word 14 */ Power_Bits32 GPBDAT_L; //GPIO32~63状态 /* word 15 */ Power_Bits32 GPCDAT_H; //GPIO64~87状态 /* word 16 */ Power_Bits32 GPCDAT_L; //GPIO64~87状态 /* word 17 */ Power_Bits16 Reserved17; //预留 /* word 18 */ Power_Bits16 Reserved18; //预留 /* word 19 */ Power_Bits16 Reserved19; //预留 /* word 20 */ Power_Bits16 OSC_CLK_FRQ; //外部晶振频率 /* word 21 */ Power_Bits16 SYS_CLK_FRQ; //系统时钟频率 /* word 22 */ Power_Bits16 SYS_TICK; //定时器时钟基准 /* word 23 */ Power_Bits16 SET_F_PWM; //开关频率 /* word 24 */ Power_Bits16 Reserved24; //预留 /* word 25 */ Power_Bits16 SysMode; //工作模式 /* word 26 */ Power_Bits16 SysState; //工作状态 /* word 27 */ Power_Bits16 SysStartMode; //启动方式 /* word 28*/ Power_Bits16 SysStartStopControl; //启停控制指令来源 /* word 29*/ Power_Bits16 SysCommandSource; //系统频率指令来源 /* word 30*/ Power_Bits16 ModID; //模块编号 /* word 31*/ Power_Bits16 SETUP_UOUT; //电压设定值 /* word 32*/ Power_Bits16 SETUP_IOUT; //电流设定值 /* word 33*/ Power_Bits16 SETUP_FREQ; //频率设定值 /* word 34*/ Power_Bits16 SOFTSTART_TIME; //软件起动时间 /* word 35*/ Power_Bits16 STEP_UOUT; //电压步长 /* word 36*/ Power_Bits16 STEP_IOUT; //电流步长 /* word 37*/ Power_Bits16 STEP_FREQ; //频率步长 /* word 38 */ Power_Bits16 STEP_ANGLE; //相角步长 /* word 39 */ Power_Bits16 POINTCYCLE; //周波点数 /* word 40 */ Power_Bits16 REF_UOUT; //电压给定值 /* word 41 */ Power_Bits16 REF_IOUT; //电流给定值 /* word 42 */ Power_Bits16 REF_FREQ; //频率给定值 /* word 43 */ Power_Bits16 REF_ANGLE; //实时相角 /* word 44 */ Power_Bits16 KPWMA; //A相调制系数 /* word 45 */ Power_Bits16 KPWMB; //B相调制系数 /* word 46 */ Power_Bits16 KPWMC; //C相调制系数 /* word 47 */ Power_Bits16 Effective_Uin; //输入电压有效值 /* word 48 */ Power_Bits16 Effective_Iin; //输入电流有效值 /* word 49 */ Power_Bits16 Effective_Udc; //直流母线电压有效值 /* word 50 */ Power_Bits16 Effective_Uout1; //A相输出电压有效值 /* word 51 */ Power_Bits16 Effective_Uout2; //B相输出电压有效值 /* word 52 */ Power_Bits16 Effective_Uout3; //C相输出电压有效值 /* word 53 */ Power_Bits16 Effective_Iout1; //A相输出电流有效值 /* word 54 */ Power_Bits16 Effective_Iout2; //B相输出电流有效值 /* word 55 */ Power_Bits16 Effective_Iout3; //C相输出电流有效值 /* word 56 */ Power_Bits16 Effective_IL1; //A相电感电流有效值 /* word 57 */ Power_Bits16 Effective_IL2; //B相电感电流有效值 /* word 58 */ Power_Bits16 Effective_IL3; //C相电感电流有效值 /* word 59 */ Power_Bits16 Effective_UinC; //备用电源电压有效值 /* word 60 */ Power_Bits16 Effective_UoutSet; //输出电压设定值(模拟) /* word 61 */ Power_Bits16 Effective_IoutSet; //输出电流设定值(模拟) /* word 62 */ Power_Bits16 Reserved62; //预留 /* word 63 */ Power_Bits16 Effective_FreqSet; //输出电压频率设定值(模拟) /* word 64 */ Power_Bits16 PIDU1_hReference; //PIDU1给定值 /* word 65 */ Power_Bits16 PIDI1_hPresentFeedback; //PIDI1反馈值 /* word 66 */ Power_Bits16 PIDI1_hReference; //PIDI1输出值 /* word 67 */ Power_Bits16 PIDU1_hKp_Gain; //PIDU1参数kp /* word 68*/ Power_Bits16 PIDU1_hKi_Gain; //PIDU1参数ki /* word 69*/ Power_Bits16 PIDU1_hKd_Gain; //PIDU1参数kd /* word 70*/ Power_Bits32 PIDU1_wLower_Limit_Integral; //PIDU1积分下限值 /* word 71*/ Power_Bits32 PIDU1_wUpper_Limit_Integral; //PIDU1积分上限值 /* word 72*/ Power_Bits16 PIDU1_hLower_Limit_Output; //PIDU1输出下限值 /* word 73*/ Power_Bits16 PIDU1_hUpper_Limit_Output; //PIDU1输出上限值 /* word 74*/ Power_Bits16 PIDU2_hReference; //PIDU2给定值 /* word 75*/ Power_Bits16 PIDU2_hPresentFeedback; //PIDU2反馈值 /* word 76*/ Power_Bits16 PIDI2_hReference; //PIDI2输出值 /* word 77*/ Power_Bits16 PIDU2_hKp_Gain; //PIDU2参数kp /* word 78*/ Power_Bits16 PIDU2_hKi_Gain; //PIDU2参数ki /* word 79*/ Power_Bits16 PIDU2_hKd_Gain; //PIDU2参数kd /* word 80*/ Power_Bits32 PIDU2_wLower_Limit_Integral; //PIDU2积分下限值 /* word 81*/ Power_Bits32 PIDU2_wUpper_Limit_Integral; //PIDU2积分上限值 /* word 82*/ Power_Bits16 PIDU2_hLower_Limit_Output; //PIDU2输出下限值 /* word 83*/ Power_Bits16 PIDU2_hUpper_Limit_Output; //PIDU2输出上限值 /* word 84 */ Power_Bits16 PIDI1hReference; //PIDI1给定值 /* word 85 */ Power_Bits16 PIDI1hPresentFeedback; //PIDI1反馈值 /* word 86 */ Power_Bits16 iParkUref_Ds; //PIDI1输出值 /* word 87 */ Power_Bits16 PIDI1_hKp_Gain; //PIDI1参数kp /* word 88*/ Power_Bits16 PIDI1_hKi_Gain; //PIDI1参数ki /* word 89*/ Power_Bits16 PIDI1_hKd_Gain; //PIDI1参数kd /* word 90*/ Power_Bits32 PIDI1_wLower_Limit_Integral; //PIDI1积分下限值 /* word 91*/ Power_Bits32 PIDI1_wUpper_Limit_Integral; //PIDI1积分上限值 /* word 92*/ Power_Bits16 PIDI1_hLower_Limit_Output; //PIDI1输出下限值 /* word 93*/ Power_Bits16 PIDI1_hUpper_Limit_Output; //PIDI1输出上限值 /* word 94 */ Power_Bits16 PIDI2hReference; //PIDI2给定值 /* word 95 */ Power_Bits16 PIDI2_hPresentFeedback; //PIDI2反馈值 /* word 96 */ Power_Bits16 iParkUref_Qs; //输出值 /* word 97 */ Power_Bits16 PIDI2_hKp_Gain; //PIDI2参数kp /* word 98*/ Power_Bits16 PIDI2_hKi_Gain; //PIDI2参数ki /* word 99*/ Power_Bits16 PIDI2_hKd_Gain; //PIDI2参数kd /* word 100*/ Power_Bits32 PIDI2_wLower_Limit_Integral; //PIDI2积分下限值 /* word 101*/ Power_Bits32 PIDI2_wUpper_Limit_Integral; //PIDI2积分上限值 /* word 102*/ Power_Bits16 PIDI2_hLower_Limit_Output; //PIDI2输出下限值 /* word 103*/ Power_Bits16 PIDI2_hUpper_Limit_Output; //PIDI2输出上限值 /* word 104 */ Power_Bits16 PIDPARA_hReference; //PIDPARA给定值 /* word 105 */ Power_Bits16 PIDPARA_hPresentFeedback; //PIDPARA反馈值 /* word 106 */ Power_Bits16 Reserved106; //PIDPARA输出值 /* word 107 */ Power_Bits16 PIDPARA_hKp_Gain; //PIDPARA参数kp /* word 108*/ Power_Bits16 PIDPARA_hKi_Gain; //PIDPARA参数ki /* word 109*/ Power_Bits16 PIDPARA_hKd_Gain; //PIDPARA参数kd /* word 110*/ Power_Bits32 PIDPARA_wLower_Limit_Integral;//PIDPARA积分下限值 /* word 111*/ Power_Bits32 PIDPARA_wUpper_Limit_Integral;//PIDPARA积分上限值 /* word 112*/ Power_Bits16 PIDPARA_hLower_Limit_Output; //PIDPARA输出下限值 /* word 113*/ Power_Bits16 PIDPARA_hUpper_Limit_Output; //PIDPARA输出上限值 /* word 114 */ Power_Bits16 PIDPLL_hReference; //PIDPLL给定值 /* word 115 */ Power_Bits16 PIDPLL_hPresentFeedback; //PIDPLL反馈值 /* word 116 */ Power_Bits16 Reserved116; //PIDPLL输出值 /* word 117 */ Power_Bits16 PIDPLL_hKp_Gain; //PIDPLL参数kp /* word 118*/ Power_Bits16 PIDPLL_hKi_Gain; //PIDPLL参数ki /* word 119*/ Power_Bits16 PIDPLL_hKd_Gain; //PIDPLL参数kd /* word 120*/ Power_Bits32 PIDPLL_wLower_Limit_Integral; //PIDPLL积分下限值 /* word 121*/ Power_Bits32 PIDPLL_wUpper_Limit_Integral; //PIDPLL积分上限值 /* word 122*/ Power_Bits16 PIDPLL_hLower_Limit_Output; //PIDPLL输出下限值 /* word 123*/ Power_Bits16 PIDPLL_hUpper_Limit_Output; //PIDPLL输出上限值 /* word 124 */ Power_Bits16 Reserved124; //输出变压器变比 /* word 125 */ Power_Bits16 Reserved125; //变压器等效电抗 /* word 126 */ Power_Bits16 Reserved126; //变压器等效电阻 /* word 127 */ Power_Bits16 Reserved127; //预留 /* word 128 */ Power_Bits16 FdOverUin_ValLimitHi; //输入过压保护值 /* word 129 */ Power_Bits16 FdUnderUin_ValLimitHi; //输入欠压保护值 /* word 130 */ Power_Bits16 FdOverIin_ValLimitHi; //输入过流保护值 /* word 131 */ Power_Bits16 FdOverUo1_ValLimitHi; //输出过压保护值 /* word 132 */ Power_Bits16 FdOverIo1_ValLimitHi; //输出过流保护值 /* word 133 */ Power_Bits16 FdOverIL1_ValLimitHi; //电感过流保护值 /* word 134 */ Power_Bits16 Reserved134; //短路保护电压动作值 /* word 135 */ Power_Bits16 Reserved135; //短路保护电流动作值 /* word 136 */ Power_Bits16 Reserved136; //短路保护电压返回值 /* word 137 */ Power_Bits16 Reserved137; //短路保护电流返回值 /* word 138 */ Power_Bits16 Reserved138; //短路运行时间 /* word 139 */ Power_Bits16 Reserved139; //110%过载保护限值 /* word 140 */ Power_Bits16 Reserved140; //110%过载保护时间 /* word 141 */ Power_Bits16 Reserved141; //110%过载保护倒计时 /* word 142 */ Power_Bits16 Reserved142; //120%过载保护限值 /* word 143 */ Power_Bits16 Reserved143; //120%过载保护时间 /* word 144 */ Power_Bits16 Reserved144; //120%过载保护倒计时 /* word 145 预留*/ Power_Bits16 Reserved145; /* word 146 AD结果寄存器数据(CH0)*/ Power_Bits16 AdcRegs_ADCRESULT0; /* word 147 */ Power_Bits16 AdcRegs_ADCRESULT1; //AD结果寄存器数据(CH1) /* word 148 */ Power_Bits16 AdcRegs_ADCRESULT2; //AD结果寄存器数据(CH2) /* word 149 */ Power_Bits16 AdcRegs_ADCRESULT3; //AD结果寄存器数据(CH3) /* word 150 */ Power_Bits16 AdcRegs_ADCRESULT4; //AD结果寄存器数据(CH4) /* word 151 */ Power_Bits16 AdcRegs_ADCRESULT5; //AD结果寄存器数据(CH5) /* word 152 */ Power_Bits16 AdcRegs_ADCRESULT6; //AD结果寄存器数据(CH6) /* word 153 */ Power_Bits16 AdcRegs_ADCRESULT7; //AD结果寄存器数据(CH7) /* word 154 */ Power_Bits16 AdcRegs_ADCRESULT8; //AD结果寄存器数据(CH8) /* word 155 */ Power_Bits16 AdcRegs_ADCRESULT9; //AD结果寄存器数据(CH9) /* word 156 */ Power_Bits16 AdcRegs_ADCRESULT10; //AD结果寄存器数据(CH10) /* word 157 */ Power_Bits16 AdcRegs_ADCRESULT11; //AD结果寄存器数据(CH11) /* word 158 */ Power_Bits16 AdcRegs_ADCRESULT12; //AD结果寄存器数据(CH12) /* word 159 */ Power_Bits16 AdcRegs_ADCRESULT13; //AD结果寄存器数据(CH13) /* word 160 */ Power_Bits16 AdcRegs_ADCRESULT14; //AD结果寄存器数据(CH14) /* word 161 */ Power_Bits16 AdcRegs_ADCRESULT15; //AD结果寄存器数据(CH15) /* word 162 预留*/ Power_Bits16 Reserved162; /* word 163 预留*/ Power_Bits16 Reserved163; /* word 164 预留*/ Power_Bits16 Reserved164; /* word 165 预留*/ Power_Bits16 Reserved165; /* word 166 预留*/ Power_Bits16 Reserved166; /* word 167 预留*/ Power_Bits16 Reserved167; /* word 168 预留*/ Power_Bits16 Reserved168; /* word 169预留 */ Power_Bits16 Reserved169; /* word 170 预留*/ Power_Bits16 Reserved170; /* word 171 预留*/ Power_Bits16 Reserved171; /* word 172 预留*/ Power_Bits16 Reserved172; /* word 173 预留*/ Power_Bits16 Reserved173; /* word 174 预留*/ Power_Bits16 Reserved174; /* word 175 预留*/ Power_Bits16 Reserved175; /* word 176 预留*/ Power_Bits16 Reserved176; /* word 177 预留*/ Power_Bits16 Reserved177; /* word 178 预留*/ Power_Bits16 Reserved178; /* word 179 预留*/ Power_Bits16 Reserved179; /* word 180 输入电压传感器采样范围*/ Power_Bits16 PEAK_UIN_SENSOR; /* word 181 输入电流传感器采样范围*/ Power_Bits16 PEAK_IIN_SENSOR; /* word 182 输出电压传感器采样范围*/ Power_Bits16 PEAK_UO_SENSOR; /* word 183 输出电流传感器采样范围*/ Power_Bits16 PEAK_IO_SENSOR; /* word 184 电感电流传感器采样范围*/ Power_Bits16 PEAK_IL_SENSOR; /* word 185 预留*/ Power_Bits16 Reserved185; /* word 186 预留*/ Power_Bits16 Reserved186; /* word 187 预留*/ Power_Bits16 Reserved187; /* word 188 预留*/ Power_Bits16 Reserved188; /* word 189 预留*/ Power_Bits16 Reserved189; /* word 190 通道选择*/ Power_Bits16 ChannelSelect; /* word 191 预留*/ Power_Bits16 Reserved191; /* word 192 预留*/ Power_Bits16 Reserved192; /* word 193 地址偏移量*/ Power_Bits16 AddressOffset; /* word 194 预留*/ Power_Bits16 Reserved194; /* word 195 预留*/ Power_Bits16 Reserved195; /* word 196 预留*/ Power_Bits16 Reserved196; /* word 197 预留*/ Power_Bits16 Reserved197; /* word 198 预留*/ Power_Bits16 Reserved198; /* word 199 网络通讯协议控制*/ Power_Bits16 Modbus_Control_ModbusCtrl; }Power_System_Type; STM32F105 power_data.c程序的二级缓存的400字节的数据准确的映射给fw_data.h程序中的Power_System_Type结构体中,然后去调用结构体的某一个数据,需要频繁访问结构体中的某个字段,可以将其缓存到局部变量中,减少多次访问互斥锁的开销,用标准库写出详细代码和注释,优化的建议也写入代码中,别单独提出来

这是我的main.c文件/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ volatile uint8_t btn0_pressed = 0; volatile uint8_t btn1_pressed = 0; typedef enum { IDLE, PROCESSING_BTN0, PROCESSING_BTN1 } SystemState; volatile SystemState state = IDLE; uint8_t blink_step = 0; uint32_t next_step_time = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE BEGIN 0 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static uint32_t last_btn0_time = 0; static uint32_t last_btn1_time = 0; uint32_t current_time = HAL_GetTick(); if (GPIO_Pin == GPIO_PIN_0) { // BTN0 if (current_time - last_btn0_time > 200) { // 消抖 btn0_pressed = 1; last_btn0_time = current_time; } } else if (GPIO_Pin == GPIO_PIN_1) { // BTN1 if (current_time - last_btn1_time > 200) { btn1_pressed = 1; last_btn1_time = current_time; } } } /* USER CODE END 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /*Configure GPIO pins : PB0 PB1 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 改为上升沿触发 GPIO_InitStruct.Pull = GPIO_PULLDOWN; // 如果硬件使用外部下拉电阻,则保持PULLUP HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ // 优先处理BTN1 if (btn1_pressed) { state = PROCESSING_BTN1; btn1_pressed = 0; btn0_pressed = 0; // 取消BTN0的请求 blink_step = 0; next_step_time = HAL_GetTick(); } else if (btn0_pressed && state == IDLE) { state = PROCESSING_BTN0; btn0_pressed = 0; blink_step = 0; next_step_time = HAL_GetTick(); } switch (state) { case PROCESSING_BTN1: if (HAL_GetTick() >= next_step_time) { if (blink_step % 2 == 0) { // 奇數位亮,偶數位滅 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_6, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_RESET); } else { // 偶數位亮,奇數位滅 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_6, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_SET); } blink_step++; next_step_time += 500; // 500ms切換一次 if (blink_step >= 6) { // 3次交替(6步) HAL_GPIO_WritePin(GPIOC, 0xFF, GPIO_PIN_SET); // 恢復全滅 state = IDLE; } } break; case PROCESSING_BTN0: if (HAL_GetTick() >= next_step_time) { if (blink_step % 2 == 0) { HAL_GPIO_WritePin(GPIOC, 0xFF, GPIO_PIN_RESET); // 全亮 } else { HAL_GPIO_WritePin(GPIOC, 0xFF, GPIO_PIN_SET); // 全滅 } blink_step++; next_step_time += 500; // 500ms切換 if (blink_step >= 6) { // 3次全亮全滅(6步) HAL_GPIO_WritePin(GPIOC, 0xFF, GPIO_PIN_SET); state = IDLE; } } break; default: break; } /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != 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_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, 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_SET); /*Configure GPIO pins : PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 */ GPIO_InitStruct.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_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pins : PB0 PB1 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); // BTN0优先级较低 HAL_NVIC_EnableIRQ(EXTI0_IRQn); HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0); // BTN1优先级较高 HAL_NVIC_EnableIRQ(EXTI1_IRQn); /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ 这是我的main.h文件/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.h * @brief : Header for main.c file. * This file contains the common defines of the application. ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __MAIN_H #define __MAIN_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx_hal.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ /* USER CODE END EM */ /* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ #ifdef __cplusplus } #endif #endif /* __MAIN_H */ 这是我的stm32f1xx_it.c文件/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32f1xx_it.c * @brief Interrupt Service Routines. ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f1xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /******************************************************************************/ /* Cortex-M3 Processor Interruption and Exception Handlers */ /******************************************************************************/ /** * @brief This function handles Non maskable interrupt. */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ while (1) { } /* USER CODE END NonMaskableInt_IRQn 1 */ } /** * @brief This function handles Hard fault interrupt. */ void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_HardFault_IRQn 0 */ /* USER CODE END W1_HardFault_IRQn 0 */ } } /** * @brief This function handles Memory management fault. */ void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ /* USER CODE END MemoryManagement_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ /* USER CODE END W1_MemoryManagement_IRQn 0 */ } } /** * @brief This function handles Prefetch fault, memory access fault. */ void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ /* USER CODE END BusFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_BusFault_IRQn 0 */ /* USER CODE END W1_BusFault_IRQn 0 */ } } /** * @brief This function handles Undefined instruction or illegal state. */ void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ /* USER CODE END UsageFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ /* USER CODE END W1_UsageFault_IRQn 0 */ } } /** * @brief This function handles System service call via SWI instruction. */ void SVC_Handler(void) { /* USER CODE BEGIN SVCall_IRQn 0 */ /* USER CODE END SVCall_IRQn 0 */ /* USER CODE BEGIN SVCall_IRQn 1 */ /* USER CODE END SVCall_IRQn 1 */ } /** * @brief This function handles Debug monitor. */ void DebugMon_Handler(void) { /* USER CODE BEGIN DebugMonitor_IRQn 0 */ /* USER CODE END DebugMonitor_IRQn 0 */ /* USER CODE BEGIN DebugMonitor_IRQn 1 */ /* USER CODE END DebugMonitor_IRQn 1 */ } /** * @brief This function handles Pendable request for system service. */ void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ /* USER CODE BEGIN PendSV_IRQn 1 */ /* USER CODE END PendSV_IRQn 1 */ } /** * @brief This function handles System tick timer. */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } /******************************************************************************/ /* STM32F1xx Peripheral Interrupt Handlers */ /* Add here the Interrupt Handlers for the used peripherals. */ /* For the available peripheral interrupt handler names, */ /* please refer to the startup file (startup_stm32f1xx.s). */ /******************************************************************************/ /* USER CODE BEGIN 1 */ // 添加EXTI0和EXTI1的中断服务函数 void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // 处理PB0的中断 } void EXTI1_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); // 处理PB1的中断 } /* USER CODE END 1 */ 这是我的stm32f1xx_it.h文件/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file stm32f1xx_it.h * @brief This file contains the headers of the interrupt handlers. ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_IT_H #define __STM32F1xx_IT_H #ifdef __cplusplus extern "C" { #endif /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ /* USER CODE END EM */ /* Exported functions prototypes ---------------------------------------------*/ void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void EXTIO_IRQHandler(void); void EXTI1_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ #ifdef __cplusplus } #endif #endif /* __STM32F1xx_IT_H */ 这是我的报错/Core/Src/main.c:119:3: error: 'GPIO_InitStruct' undeclared (first use in this function) make: *** [Core/Src/subdir.mk:34: Core/Src/main.o] Error 1帮我检查并修改,给我修改后的详细步骤和代码

/****************************************************************************** * * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of the Xilinx shall not be used * in advertising or otherwise to promote the sale, use or other dealings in * this Software without prior written authorization from Xilinx. * ******************************************************************************/ /*****************************************************************************/ /** * @file xttcps_rtc_example.c * * This example uses one timer/counter to make a real time clock. The number of * minutes and seconds is displayed on the console. * * * @note * * * MODIFICATION HISTORY: * * Ver Who Date Changes * ---- ------ -------- --------------------------------------------- * 1.00 drg/jz 01/23/10 First release * 3.01 pkp 01/30/16 Modified SetupTimer to remove XTtcps_Stop before TTC * configuration as it is added in xttcps.c in * XTtcPs_CfgInitialize * 3.2 mus 10/28/16 Updated TmrCntrSetup as per prototype of * XTtcPs_CalcIntervalFromFreq * ms 01/23/17 Modified xil_printf statement in main function to * ensure that "Successfully ran" and "Failed" strings * are available in all examples. This is a fix for * CR-965028. * ******************************************************************************/ /***************************** Include Files *********************************/ #include <stdio.h> #include <stdlib.h> #include "xparameters.h" #include "xstatus.h" #include "xil_io.h" #include "xil_exception.h" #include "xttcps.h" #include "xscugic.h" #include "xil_printf.h" /************************** Constant Definitions *****************************/ /* * The following constants map to the XPAR parameters created in the * xparameters.h file. They are only defined here such that a user can easily * change all the needed parameters in one place. */ #define TTC_TICK_DEVICE_ID XPAR_XTTCPS_0_DEVICE_ID #define TTC_TICK_INTR_ID XPAR_XTTCPS_0_INTR #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID /* * Constants to set the basic operating parameters. * PWM_DELTA_DUTY is critical to the running time of the test. Smaller values * make the test run longer. */ #define TICK_TIMER_FREQ_HZ 100 /* Tick timer counter's output frequency */ #define TICKS_PER_CHANGE_PERIOD TICK_TIMER_FREQ_HZ /* Tick signals per update */ /**************************** Type Definitions *******************************/ typedef struct { u32 OutputHz; /* Output frequency */ XInterval Interval; /* Interval value */ u8 Prescaler; /* NO USED */ u16 Options; /* Option settings */ } TmrCntrSetup; /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ static int TmrRtcInterruptExample(void); /* Main test */ /* Set up routines for timer counters */ static int SetupTicker(void); static int SetupTimer(int DeviceID); /* Interleaved interrupt test for both timer counters */ static int WaitForDutyCycleFull(void); static int SetupInterruptSystem(u16 IntcDeviceID, XScuGic *IntcInstancePtr); static void TickHandler(void *CallBackRef); /************************** Variable Definitions *****************************/ static XTtcPs TtcPsInst; /* Timer counter instance */ static TmrCntrSetup SettingsTable= {TICK_TIMER_FREQ_HZ, 0, 0, 0}; /* Ticker timer counter initial setup, only output freq */ XScuGic InterruptController; /* Interrupt controller instance */ static u8 ErrorCount; /* Errors seen at interrupt time */ static volatile u8 UpdateFlag; /* Flag to update the seconds counter */ static u32 TickCount; /* Ticker interrupts between seconds change */ /*****************************************************************************/ /** * * This is the main function that calls the TTC RTC interrupt example. * * @param None * * @return * - XST_SUCCESS to indicate Success * - XST_FAILURE to indicate a Failure. * * @note None. * *****************************************************************************/ int main(void) { int Status; xil_printf("Starting Timer RTC Example"); Status = TmrRtcInterruptExample(); if (Status != XST_SUCCESS) { xil_printf("ttcps rtc Example Failed\r\n"); return XST_FAILURE; } xil_printf("Successfully ran ttcps rtc Example\r\n"); return XST_SUCCESS; } /*****************************************************************************/ /** * * This is the main function of the interrupt example. * * * @param None. * * @return XST_SUCCESS to indicate success, else XST_FAILURE to indicate * a Failure. * ****************************************************************************/ static int TmrRtcInterruptExample(void) { int Status; /* * Make sure the interrupts are disabled, in case this is being run * again after a failure. */ /* * Connect the Intc to the interrupt subsystem such that interrupts can * occur. This function is application specific. */ Status = SetupInterruptSystem(INTC_DEVICE_ID, &InterruptController); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set up the Ticker timer */ Status = SetupTicker(); if (Status != XST_SUCCESS) { return Status; } Status = WaitForDutyCycleFull(); if (Status != XST_SUCCESS) { return Status; } /* * Stop the counters */ XTtcPs_Stop(&TtcPsInst); return XST_SUCCESS; } /****************************************************************************/ /** * * This function sets up the Ticker timer. * * @param None * * @return XST_SUCCESS if everything sets up well, XST_FAILURE otherwise. * *****************************************************************************/ int SetupTicker(void) { int Status; TmrCntrSetup *TimerSetup; XTtcPs *TtcPsTick; TimerSetup = &SettingsTable; /* * Set up appropriate options for Ticker: interval mode without * waveform output. */ TimerSetup->Options |= (XTTCPS_OPTION_INTERVAL_MODE); /* * Calling the timer setup routine * . initialize device * . set options */ Status = SetupTimer(TTC_TICK_DEVICE_ID); if(Status != XST_SUCCESS) { return Status; } TtcPsTick = &TtcPsInst; /* * Connect to the interrupt controller */ Status = XScuGic_Connect(&InterruptController, TTC_TICK_INTR_ID, (Xil_InterruptHandler)TickHandler, (void *)TtcPsTick); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the Timer counter */ XScuGic_Enable(&InterruptController, TTC_TICK_INTR_ID); /* * Enable the interrupts for the tick timer/counter * We only care about the interval timeout. */ XTtcPs_EnableInterrupts(TtcPsTick, XTTCPS_IXR_INT_ENABLE); /* * Start the tick timer/counter */ XTtcPs_Start(TtcPsTick); return Status; } /****************************************************************************/ /** * * This function uses the interrupt inter-locking between the ticker timer * counter and the waveform output timer counter. When certain amount of * interrupts have happened to the ticker timer counter, a flag, UpdateFlag, * is set to true. * * * @param None * * @return XST_SUCCESS if duty cycle successfully reaches beyond 100, * otherwise XST_FAILURE. * *****************************************************************************/ int WaitForDutyCycleFull(void) { u32 seconds; /* * Initialize some variables used by the interrupts and in loops. */ ErrorCount = 0; seconds = 0; /* * Loop until two minutes passes. */ while (seconds <= 121) { /* * If error occurs, disable interrupts, and exit. */ if (0 != ErrorCount) { return XST_FAILURE; } /* * The Ticker interrupt sets a flag for update. */ if (UpdateFlag) { /* * Calculate the time setting here, not at the time * critical interrupt level. */ seconds++; UpdateFlag = FALSE; xil_printf("Time: %d\n\r", seconds); } } return XST_SUCCESS; } /****************************************************************************/ /** * * This function sets up a timer counter device, using the information in its * setup structure. * . initialize device * . set options * . set interval and prescaler value for given output frequency. * * @param DeviceID is the unique ID for the device. * * @return XST_SUCCESS if successful, otherwise XST_FAILURE. * *****************************************************************************/ int SetupTimer(int DeviceID) { int Status; XTtcPs_Config *Config; XTtcPs *Timer; TmrCntrSetup *TimerSetup; TimerSetup = &SettingsTable; Timer = &TtcPsInst; /* * Look up the configuration based on the device identifier */ Config = XTtcPs_LookupConfig(DeviceID); if (NULL == Config) { return XST_FAILURE; } /* * Initialize the device */ Status = XTtcPs_CfgInitialize(Timer, Config, Config->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the options */ XTtcPs_SetOptions(Timer, TimerSetup->Options); /* * Timer frequency is preset in the TimerSetup structure, * however, the value is not reflected in its other fields, such as * IntervalValue and PrescalerValue. The following call will map the * frequency to the interval and prescaler values. */ XTtcPs_CalcIntervalFromFreq(Timer, TimerSetup->OutputHz, &(TimerSetup->Interval), &(TimerSetup->Prescaler)); /* * Set the interval and prescale */ XTtcPs_SetInterval(Timer, TimerSetup->Interval); return XST_SUCCESS; } /****************************************************************************/ /** * * This function setups the interrupt system such that interrupts can occur. * This function is application specific since the actual system may or may not * have an interrupt controller. The TTC could be directly connected to a * processor without an interrupt controller. The user should modify this * function to fit the application. * * @param IntcDeviceID is the unique ID of the interrupt controller * @param IntcInstacePtr is a pointer to the interrupt controller * instance. * * @return XST_SUCCESS if successful, otherwise XST_FAILURE. * *****************************************************************************/ static int SetupInterruptSystem(u16 IntcDeviceID, XScuGic *IntcInstancePtr) { int Status; XScuGic_Config *IntcConfig; /* The configuration parameters of the interrupt controller */ /* * Initialize the interrupt controller driver */ IntcConfig = XScuGic_LookupConfig(IntcDeviceID); if (NULL == IntcConfig) { return XST_FAILURE; } Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the interrupt controller interrupt handler to the hardware * interrupt handling logic in the ARM processor. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, IntcInstancePtr); /* * Enable interrupts in the ARM */ Xil_ExceptionEnable(); return XST_SUCCESS; } /***************************************************************************/ /** * * This function is the handler which handles the periodic tick interrupt. * It updates its count, and set a flag to signal PWM timer counter to * update its duty cycle. * * This handler provides an example of how to handle data for the TTC and * is application specific. * * @param CallBackRef contains a callback reference from the driver, in * this case it is the instance pointer for the TTC driver. * * @return None. * *****************************************************************************/ static void TickHandler(void *CallBackRef) { u32 StatusEvent; /* * Read the interrupt status, then write it back to clear the interrupt. */ StatusEvent = XTtcPs_GetInterruptStatus((XTtcPs *)CallBackRef); XTtcPs_ClearInterruptStatus((XTtcPs *)CallBackRef, StatusEvent); if (0 != (XTTCPS_IXR_INT_ENABLE & StatusEvent)) { TickCount++; if (TICKS_PER_CHANGE_PERIOD == TickCount) { TickCount = 0; UpdateFlag = TRUE; } } else { /* * The Interval event should be the only one enabled. If it is * not it is an error */ ErrorCount++; } } 请详细分析一下以上的代码,并给出详细的解释

逐句分析以下这段代码/** ****************************************************************************** * @file stm32f10x_tim.c * @author MCD Application Team * @version V3.5.0 * @date 11-March-2011 * @brief This file provides all the TIM firmware functions. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *
© COPYRIGHT 2011 STMicroelectronics
****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_tim.h" #include "stm32f10x_rcc.h" /** @addtogroup STM32F10x_StdPeriph_Driver * @{ */ /** @defgroup TIM * @brief TIM driver modules * @{ */ /** @defgroup TIM_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup TIM_Private_Defines * @{ */ /* ---------------------- TIM registers bit mask ------------------------ */ #define SMCR_ETR_Mask ((uint16_t)0x00FF) #define CCMR_Offset ((uint16_t)0x0018) #define CCER_CCE_Set ((uint16_t)0x0001) #define CCER_CCNE_Set ((uint16_t)0x0004) /** * @} */ /** @defgroup TIM_Private_Macros * @{ */ /** * @} */ /** @defgroup TIM_Private_Variables * @{ */ /** * @} */ /** @defgroup TIM_Private_FunctionPrototypes * @{ */ static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, uint1

main.c:“/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != 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_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */” gpio.c:“/* Includes ------------------------------------------------------------------*/ #include "gpio.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /*----------------------------------------------------------------------------*/ /* Configure GPIO */ /*----------------------------------------------------------------------------*/ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET); /*Configure GPIO pins : PC0 PC1 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ ” tim.c:“/* Includes ------------------------------------------------------------------*/ #include "tim.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ TIM_HandleTypeDef htim2; /* TIM2 init function */ void MX_TIM2_Init(void) { /* USER CODE BEGIN TIM2_Init 0 */ /* USER CODE END TIM2_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; /* USER CODE BEGIN TIM2_Init 1 */ /* USER CODE END TIM2_Init 1 */ htim2.Instance = TIM2; htim2.Init.Prescaler = 71; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 1000; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM2_Init 2 */ /* USER CODE END TIM2_Init 2 */ HAL_TIM_MspPostInit(&htim2); } void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) { if(tim_pwmHandle->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspInit 0 */ /* USER CODE END TIM2_MspInit 0 */ /* TIM2 clock enable */ __HAL_RCC_TIM2_CLK_ENABLE(); /* TIM2 interrupt Init */ HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM2_IRQn); /* USER CODE BEGIN TIM2_MspInit 1 */ /* USER CODE END TIM2_MspInit 1 */ } } void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(timHandle->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspPostInit 0 */ /* USER CODE END TIM2_MspPostInit 0 */ __HAL_RCC_GPIOA_CLK_ENABLE(); /**TIM2 GPIO Configuration PA0-WKUP ------> TIM2_CH1 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN TIM2_MspPostInit 1 */ /* USER CODE END TIM2_MspPostInit 1 */ } } void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle) { if(tim_pwmHandle->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspDeInit 0 */ /* USER CODE END TIM2_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_TIM2_CLK_DISABLE(); /* TIM2 interrupt Deinit */ HAL_NVIC_DisableIRQ(TIM2_IRQn); /* USER CODE BEGIN TIM2_MspDeInit 1 */ /* USER CODE END TIM2_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ ” usart.c:“/* Includes ------------------------------------------------------------------*/ #include "usart.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ UART_HandleTypeDef huart1; /* USART1 init function */ void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**USART1 GPIO Configuration PB6 ------> USART1_TX PB7 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); __HAL_AFIO_REMAP_USART1_ENABLE(); /* USART1 interrupt Init */ HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PB6 ------> USART1_TX PB7 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7); /* USART1 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ ” stm32f1xx_it.c:“/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f1xx_it.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ /* USER CODE END TD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ extern TIM_HandleTypeDef htim2; extern UART_HandleTypeDef huart1; /* USER CODE BEGIN EV */ /* USER CODE END EV */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ while (1) { } /* USER CODE END NonMaskableInt_IRQn 1 */ } void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_HardFault_IRQn 0 */ /* USER CODE END W1_HardFault_IRQn 0 */ } } void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ /* USER CODE END MemoryManagement_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ /* USER CODE END W1_MemoryManagement_IRQn 0 */ } } void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ /* USER CODE END BusFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_BusFault_IRQn 0 */ /* USER CODE END W1_BusFault_IRQn 0 */ } } void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ /* USER CODE END UsageFault_IRQn 0 */ while (1) { /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ /* USER CODE END W1_UsageFault_IRQn 0 */ } } void SVC_Handler(void) { /* USER CODE BEGIN SVCall_IRQn 0 */ /* USER CODE END SVCall_IRQn 0 */ /* USER CODE BEGIN SVCall_IRQn 1 */ /* USER CODE END SVCall_IRQn 1 */ } void DebugMon_Handler(void) { /* USER CODE BEGIN DebugMonitor_IRQn 0 */ /* USER CODE END DebugMonitor_IRQn 0 */ /* USER CODE BEGIN DebugMonitor_IRQn 1 */ /* USER CODE END DebugMonitor_IRQn 1 */ } void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ /* USER CODE BEGIN PendSV_IRQn 1 */ /* USER CODE END PendSV_IRQn 1 */ } void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } void RCC_IRQHandler(void) { /* USER CODE BEGIN RCC_IRQn 0 */ /* USER CODE END RCC_IRQn 0 */ /* USER CODE BEGIN RCC_IRQn 1 */ /* USER CODE END RCC_IRQn 1 */ } void TIM2_IRQHandler(void) { /* USER CODE BEGIN TIM2_IRQn 0 */ /* USER CODE END TIM2_IRQn 0 */ HAL_TIM_IRQHandler(&htim2); /* USER CODE BEGIN TIM2_IRQn 1 */ /* USER CODE END TIM2_IRQn 1 */ } void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */ } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */” main.h:“/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __MAIN_H #define __MAIN_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "stm32f1xx_hal.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ /* USER CODE END EM */ /* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ #define DIR_Pin GPIO_PIN_0 #define DIR_GPIO_Port GPIOC #define EN_Pin GPIO_PIN_1 #define EN_GPIO_Port GPIOC /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ #ifdef __cplusplus } #endif #endif /* __MAIN_H */ ” gpio.h:“/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __GPIO_H__ #define __GPIO_H__ #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "main.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ void MX_GPIO_Init(void); /* USER CODE BEGIN Prototypes */ /* USER CODE END Prototypes */ #ifdef __cplusplus } #endif #endif /*__ GPIO_H__ */” tim.h:“/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __TIM_H__ #define __TIM_H__ #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "main.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ extern TIM_HandleTypeDef htim2; /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ void MX_TIM2_Init(void); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); /* USER CODE BEGIN Prototypes */ /* USER CODE END Prototypes */ #ifdef __cplusplus } #endif #endif /* __TIM_H__ */ ” usart.h:“/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USART_H__ #define __USART_H__ #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "main.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ extern UART_HandleTypeDef huart1; /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ void MX_USART1_UART_Init(void); /* USER CODE BEGIN Prototypes */ /* USER CODE END Prototypes */ #ifdef __cplusplus } #endif #endif /* __USART_H__ */” stm32f1xx_it.h:“/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F1xx_IT_H #define __STM32F1xx_IT_H #ifdef __cplusplus extern "C" { #endif /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ /* USER CODE BEGIN EC */ /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ /* USER CODE END EM */ /* Exported functions prototypes ---------------------------------------------*/ void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void RCC_IRQHandler(void); void TIM2_IRQHandler(void); void USART1_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ #ifdef __cplusplus } #endif #endif /* __STM32F1xx_IT_H */ ”目前我已经有以上代码,那么完成一个42步进电机的控制,采用TB6600驱动器,串口发送一个多位数据,比如第一部分控制正转反转与停止,第二位部分控制圈数,第三部分控制速度,如果要实现该功能在以上代码的基础上那么还需要完成哪些部分,请帮我完成,详细一些,还要确保所有量或函数都要声明,一定确保正确性,记得反复检查下

找不到错在哪,但是温度就是不变 /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "LCD.h" #include "DS18B20.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ float T; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ lcd9648_init(); DS18B20_ConvertT(); lcd9648_clear(); lcd_show_string(0,0,96,48,16,"Temperature:"); lcd_reflash_gram(); // lcd9648_init(); // lcd9648_clear(); // lcd_show_string(0,0,96,48,12,"Hello World!"); // lcd_show_string(0,14,96,48,16,"Temperature:"); // //lcd_show_fontHZ(0, 30,"���пƼ�"); // lcd_reflash_gram(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { DS18B20_ConvertT(); T=DS18B20_ReadT(); if(T<0){ lcd_show_char(0,1*16,'-',16,0); lcd_reflash_gram(); T=-T; } else{ lcd_show_char(0,1*16,'+',16,0); lcd_reflash_gram(); } lcd_show_num(1*8,1*16,(int)T,3,16,0); lcd_show_char(4*8,1*16,'.',16,0); lcd_show_num(5*8,1*16,(unsigned long)(T*10000)%10000,4,16,0); lcd_reflash_gram(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(500); } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != 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_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, SCL_Pin|SDA_Pin|RS_Pin|CS_Pin |RST_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(DQ_GPIO_Port, DQ_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : SCL_Pin SDA_Pin RS_Pin CS_Pin RST_Pin */ GPIO_InitStruct.Pin = SCL_Pin|SDA_Pin|RS_Pin|CS_Pin |RST_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pin : DQ_Pin */ GPIO_InitStruct.Pin = DQ_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(DQ_GPIO_Port, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ HAL_GPIO_WritePin(DQ_GPIO_Port,DQ_Pin,GPIO_PIN_SET); /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */

/*---------------------------------------------------------------------------/ / FatFs - FAT file system module include file R0.09 (C)ChaN, 2011 /----------------------------------------------------------------------------/ / FatFs module is a generic FAT file system module for small embedded systems. / This is a free software that opened for education, research and commercial / developments under license policy of following trems. / / Copyright (C) 2011, ChaN, all right reserved. / / * The FatFs module is a free software and there is NO WARRANTY. / * No restriction on use. You can use, modify and redistribute it for / personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. / * Redistributions of source code must retain the above copyright notice. / /----------------------------------------------------------------------------*/ #ifndef _FATFS #define _FATFS 6502 /* Revision ID */ #ifdef __cplusplus extern "C" { #endif #include "integer.h" /* Basic integer types */ #include "ffconf.h" /* FatFs configuration options */ #include "HeaderFiles.h" #if _FATFS != _FFCONF #error Wrong configuration file (ffconf.h). #endif /* Definitions of volume management */ #if _MULTI_PARTITION /* Multiple partition configuration */ typedef struct { BYTE pd; /* Physical drive number */ BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ } PARTITION; extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ #define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ #define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ #else /* Single partition configuration */ #define LD2PD(vol) (vol) /* Each logical drive is bound to the same physical drive number */ #define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */ #endif /* Type of path name strings on FatFs API */ #if _LFN_UNICODE /* Unicode string */ #if !_USE_LFN #error _LFN_UNICODE must be 0 in non-LFN cfg. #endif #ifndef _INC_TCHAR typedef WCHAR TCHAR; #define _T(x) L ## x #define _TEXT(x) L ## x #endif #else /* ANSI/OEM string */ #ifndef _INC_TCHAR typedef char TCHAR; #define _T(x) x #define _TEXT(x) x #endif #endif /* File system object structure (FATFS) */ typedef struct { BYTE fs_type; /* FAT sub-type (0:Not mounted) */ BYTE drv; /* Physical drive number */ BYTE csize; /* Sectors per cluster (1,2,4...128) */ BYTE n_fats; /* Number of FAT copies (1,2) */ BYTE wflag; /* win[] dirty flag (1:must be written back) */ BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */ WORD id; /* File system mount ID */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ #if _MAX_SS != 512 WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */ #endif #if _FS_REENTRANT _SYNC_t sobj; /* Identifier of sync object */ #endif #if !_FS_READONLY DWORD last_clust; /* Last allocated cluster */ DWORD free_clust; /* Number of free clusters */ DWORD fsi_sector; /* fsinfo sector (FAT32) */ #endif #if _FS_RPATH DWORD cdir; /* Current directory start cluster (0:root) */ #endif DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ DWORD fsize; /* Sectors per FAT */ DWORD fatbase; /* FAT start sector */ DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ DWORD database; /* Data start sector */ DWORD winsect; /* Current sector appearing in the win[] */ BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */ } FATFS; /* File object structure (FIL) */ typedef struct { FATFS* fs; /* Pointer to the owner file system object */ WORD id; /* Owner file system mount ID */ BYTE flag; /* File status flags */ BYTE pad1; DWORD fptr; /* File read/write pointer (0 on file open) */ DWORD fsize; /* File size */ DWORD sclust; /* File start cluster (0 when fsize==0) */ DWORD clust; /* Current cluster */ DWORD dsect; /* Current data sector */ #if !_FS_READONLY DWORD dir_sect; /* Sector containing the directory entry */ BYTE* dir_ptr; /* Ponter to the directory entry in the window */ #endif #if _USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */ #endif #if _FS_SHARE UINT lockid; /* File lock ID (index of file semaphore table) */ #endif #if !_FS_TINY BYTE buf[_MAX_SS]; /* File data read/write buffer */ #endif } FIL; /* Directory object structure (DIR) */ typedef struct { FATFS* fs; /* Pointer to the owner file system object */ WORD id; /* Owner file system mount ID */ WORD index; /* Current read/write index number */ DWORD sclust; /* Table start cluster (0:Root dir) */ DWORD clust; /* Current cluster */ DWORD sect; /* Current sector */ BYTE* dir; /* Pointer to the current SFN entry in the win[] */ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ #if _USE_LFN WCHAR* lfn; /* Pointer to the LFN working buffer */ WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ #endif } DIR; /* File status structure (FILINFO) */ typedef struct { DWORD fsize; /* File size */ WORD fdate; /* Last modified date */ WORD ftime; /* Last modified time */ BYTE fattrib; /* Attribute */ TCHAR fname[13]; /* Short file name (8.3 format) */ #if _USE_LFN TCHAR* lfname; /* Pointer to the LFN buffer */ UINT lfsize; /* Size of LFN buffer in TCHAR */ #endif } FILINFO; /* File function return code (FRESULT) */ typedef enum { FR_OK = 0, /* (0) Succeeded */ FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ FR_INT_ERR, /* (2) Assertion failed */ FR_NOT_READY, /* (3) The physical drive cannot work */ FR_NO_FILE, /* (4) Could not find the file */ FR_NO_PATH, /* (5) Could not find the path */ FR_INVALID_NAME, /* (6) The path name format is invalid */ FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */ FR_EXIST, /* (8) Acces denied due to prohibited access */ FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ FR_NOT_ENABLED, /* (12) The volume has no work area */ FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ } FRESULT; /*--------------------------------------------------------------*/ /* FatFs module application interface */ FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */ FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ FRESULT f_close (FIL*); /* Close an open file object */ FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */ FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */ FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */ FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */ FRESULT f_truncate (FIL*); /* Truncate file */ FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */ FRESULT f_mkdir (const TCHAR*); /* Create a new directory */ FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */ FRESULT f_chdrive (BYTE); /* Change current drive */ FRESULT f_chdir (const TCHAR*); /* Change current directory */ FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */ FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */ FRESULT f_fdisk (BYTE, const DWORD[], void*); /* Divide a physical drive into some partitions */ int f_putc (TCHAR, FIL*); /* Put a character to the file */ int f_puts (const TCHAR*, FIL*); /* Put a string to the file */ int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */ TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */ #define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) #define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0) #define f_tell(fp) ((fp)->fptr) #define f_size(fp) ((fp)->fsize) #ifndef EOF #define EOF (-1) #endif /*--------------------------------------------------------------*/ /* Additional user defined functions */ /* RTC function */ #if !_FS_READONLY DWORD get_fattime (void); #endif /* Unicode support functions */ #if _USE_LFN /* Unicode - OEM code conversion */ WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */ WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */ #if _USE_LFN == 3 /* Memory functions */ void* ff_memalloc (UINT); /* Allocate memory block */ void ff_memfree (void*); /* Free memory block */ #endif #endif /* Sync functions */ #if _FS_REENTRANT int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */ int ff_req_grant (_SYNC_t); /* Lock sync object */ void ff_rel_grant (_SYNC_t); /* Unlock sync object */ int ff_del_syncobj (_SYNC_t); /* Delete a sync object */ #endif /*--------------------------------------------------------------*/ /* Flags and offset address */ /* File access control and file status flags (FIL.flag) */ #define FA_READ 0x01 #define FA_OPEN_EXISTING 0x00 #define FA__ERROR 0x80 #if !_FS_READONLY #define FA_WRITE 0x02 #define FA_CREATE_NEW 0x04 #define FA_CREATE_ALWAYS 0x08 #define FA_OPEN_ALWAYS 0x10 #define FA__WRITTEN 0x20 #define FA__DIRTY 0x40 #endif /* FAT sub type (FATFS.fs_type) */ #define FS_FAT12 1 #define FS_FAT16 2 #define FS_FAT32 3 /* File attribute bits for directory entry */ #define AM_RDO 0x01 /* Read only */ #define AM_HID 0x02 /* Hidden */ #define AM_SYS 0x04 /* System */ #define AM_VOL 0x08 /* Volume label */ #define AM_LFN 0x0F /* LFN entry */ #define AM_DIR 0x10 /* Directory */ #define AM_ARC 0x20 /* Archive */ #define AM_MASK 0x3F /* Mask of defined bits */ /* Fast seek feature */ #define CREATE_LINKMAP 0xFFFFFFFF /*--------------------------------*/ /* Multi-byte word access macros */ #if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ #define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) #define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) #define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) #define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) #else /* Use byte-by-byte access to the FAT structure */ #define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) #define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr)) #define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8) #define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24) #endif #ifdef __cplusplus } #endif #endif /* _FATFS */ 根据头文件修改一下

/********************** * MACROS **********************/ lv_disp_drv_t *lv_port_disp_init() { static lv_disp_draw_buf_t draw_buf_dsc_3; static lv_color_t buf_3_1[LVGL_HOR_RES * LVGL_VER_RES]; /*A screen sized buffer*/ static lv_color_t buf_3_2[LVGL_HOR_RES * LVGL_VER_RES]; /*Another screen sized buffer*/ lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2, LVGL_VER_RES * LVGL_HOR_RES); /*Initialize the display buffer*/ /*----------------------------------- * Register the display in LVGL *----------------------------------*/ static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ 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 = LVGL_HOR_RES; disp_drv.ver_res = LVGL_VER_RES; disp_drv.physical_hor_res = LVGL_HOR_RES; disp_drv.physical_ver_res = LVGL_VER_RES; disp_drv.screen_transp = LV_COLOR_SCREEN_TRANSP; disp_drv.dpi = LV_DPI_DEF; disp_drv.color_chroma_key = LV_COLOR_CHROMA_KEY; /*Used to copy the buffer's content to the display*/ disp_drv.flush_cb = disp_flush; /*Set a display buffer*/ disp_drv.draw_buf = &draw_buf_dsc_3; #if ROTATE_SCREEN disp_drv.rotated = 1; disp_drv.sw_rotate = 1; #endif /*Required for Example 3)*/ disp_drv.full_refresh = 0; /* Fill a memory array with a color if you have GPU. * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL. * But if you have a different GPU you can use with this callback.*/ //disp_drv.gpu_fill_cb = gpu_fill; /*Finally register the driver*/ lv_disp_drv_register(&disp_drv); return &disp_drv; } 把他转成lv_display_create的函数。

/** ****************************************************************************** * @file usbd_customhid.c * @author MCD Application Team * @brief This file provides the CUSTOM_HID core functions. * * @verbatim * * =================================================================== * CUSTOM_HID Class Description * =================================================================== * This module manages the CUSTOM_HID class V1.11 following the "Device Class Definition * for Human Interface Devices (CUSTOM_HID) Version 1.11 Jun 27, 2001". * This driver implements the following aspects of the specification: * - The Boot Interface Subclass * - Usage Page : Generic Desktop * - Usage : Vendor * - Collection : Application * * @note In HS mode and when the DMA is used, all variables and data structures * dealing with the DMA during the transaction process should be 32-bit aligned. * * * @endverbatim * ****************************************************************************** * @attention * *
© Copyright (c) 2015 STMicroelectronics. * All rights reserved.
* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* BSPDependencies - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" - "stm32xxxxx_{eval}{discovery}_io.c" EndBSPDependencies */ /* Includes ------------------------------------------------------------------*/ #include "usbd_customhid.h" #include "usbd_ctlreq.h" /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ */ /** @defgroup USBD_CUSTOM_HID * @brief usbd core module * @{ */ /** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup USBD_CUSTOM_HID_Private_Defines * @{ */ /** * @} */ /** @defgroup USBD_CUSTOM_HID_Private_Macros * @{ */ /** * @} */ /** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes * @{ */基于STM32F103VeT6利用CubeMX生成的USB的HID的代码要怎么理解

/*************************************************************************** * @file bsp_serial1.c * Created on: 2025-03-18 * Author: YL Monitor Software group ****************************************************************************/ #include "main.h" #include "power_data.h" /************************ Private macros *************************/ #if SERIAL1_DMATx_ENABLE //开启串行通信1 DMA 发送中断 -- 1 /* 串行通信 DMA发送缓冲区大小 */ #define SERIAL_TX_BUFF_SIZE 400 #endif #if SERIAL1_DMARx_ENABLE //开启串行通信1 DMA 接收中断 /* 串行通信 DMA接收缓冲区大小 */ #define SERIAL_RX_BUFF_SIZE 400 #endif /************************ Private variables *************************/ #if SERIAL1_DMATx_ENABLE //开启串行通信1 DMA 发送中断 -- 1 /* 串行通信 DMA发送缓存 */ static uint8_t DMA_TxBuff[SERIAL_TX_BUFF_SIZE]; #endif #if SERIAL1_DMARx_ENABLE //开启串行通信1 DMA 接收中断 /* 串行通信 DMA接收缓存 */ static uint8_t DMA_RxBuff[SERIAL_RX_BUFF_SIZE]={0XFF}; //接收缓冲区初始化为非0值(可选,仅在首次接收前需要) //注意:DMA会覆盖有效数据部分,剩余未覆盖部分无需初始化,但处理时仅取rlen长度 //static uint8_t DMA_RxBuff[SERIAL_RX_BUFF_SIZE] = {0xFF}; // 初始化为非0值 #endif /* 串行通信 接收数据队列 */ //static QueueHandle_t queueRecvData = NULL; static SemaphoreHandle_t mutexSerialSend = NULL; /* 串行通信2 数据接收离线状态时间计数器 * 在硬件定时器中进行累加 * DMA接收中断中清零 * 当离线超过5ms,接收结束,或者设备离线,可以进行数据转发至上位机*/ static uint16_t recv_offline_timer_count = 0; /**************************************** * @funName : BSP_HwInitSerial1 * @Description : 串行通信口1 硬件资源初始化 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 ********************************************/ void BSP_HwInitSerial1(void) { GPIO_InitTypeDef GPIO_InitStructure ={0}; USART_InitTypeDef USART_InitStructure ={0}; NVIC_InitTypeDef NVIC_InitStructure ={0}; DMA_InitTypeDef DMA_InitStructure ={0}; /****************Tx****************/ GPIO_InitStructure.GPIO_Pin = SERIAL1_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SERIAL1_TX_PORT, &GPIO_InitStructure); /****************Rx****************/ GPIO_InitStructure.GPIO_Pin = SERIAL1_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(SERIAL1_RX_PORT, &GPIO_InitStructure); /* 串行通信初始化 */ USART_DeInit(SERIAL1); USART_InitStructure.USART_BaudRate = SERIAL1_BAUD_RATE; //波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(SERIAL1, &USART_InitStructure); #if SERIAL1_IT_ENABLE //开启串行通信1中断 NVIC_InitStructure.NVIC_IRQChannel = SERIAL1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SERIAL1_PreemptionPriority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif #if SERIAL1_DMATx_ENABLE //开启串行通信1 DMA 发送中断 /* DMA发送初始化 */ DMA_DeInit(SERIAL1_DMATx_Channel); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&SERIAL1->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_TxBuff; //(uint32_t)(USART3.pbRx) 目标BUF 既是要写在哪个数组中 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SERIAL_TX_BUFF_SIZE; //DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //内存字节为单位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存字节为单位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA_Mode_Circular DMA_Mode_Normal-工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //4优先级之一的(高优先级) DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存 DMA_Init(SERIAL1_DMATx_Channel, &DMA_InitStructure); /* DMA发送中断优先级设置 */ NVIC_InitStructure.NVIC_IRQChannel = SERIAL1_DMATx_IRQn ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SERIAL1_DMATx_PreemptionPriority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(SERIAL1_DMATx_Channel, DMA_IT_TC, ENABLE); //使能DMA1传输完成中 DMA_Cmd(SERIAL1_DMATx_Channel, ENABLE); //启用DMA1通道 #endif #if SERIAL1_DMARx_ENABLE //开启串行通信1 DMA 接收中断 /* DMA接收初始化 */ DMA_DeInit(SERIAL1_DMARx_Channel); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&SERIAL1->DR); //源头是BUF既是(&(SERIAL1->DR)) DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_RxBuff; //(uint32_t)(USART3.pbRx) 目标BUF 既是要写在哪个数组中 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设做源头-外设是作为数据传输的目的地还是来源 DMA_InitStructure.DMA_BufferSize = SERIAL_RX_BUFF_SIZE; //DMA缓存的大小! 单位在下边设定 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设字节为单位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存字节为单位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //循环模式DMA_Mode_Circular DMA_Mode_Normal-工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA_Priority_VeryHigh,DMA_Priority_High,DMA_Priority_Medium(初始使用); ---------------- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存 DMA_Init(SERIAL1_DMARx_Channel, &DMA_InitStructure); /* DMA接收中断优先级设置 */ NVIC_InitStructure.NVIC_IRQChannel = SERIAL1_DMARx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SERIAL1_DMARx_PreemptionPriority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(SERIAL1_DMATx_Channel, DMA_IT_TC, ENABLE); //使能DMA1传输完成中 //DMA_ITConfig(SERIAL1_DMARx_Channel, DMA_IT_TC, DISABLE); //禁用DMA1传输完成中 DMA_Cmd(SERIAL1_DMARx_Channel, ENABLE); #endif USART_DMACmd(SERIAL1, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE); //使能USART3的DMA发送,接收请求 //USART_ITConfig(SERIAL1, USART_IT_RXNE, ENABLE); USART_ITConfig(SERIAL1, USART_IT_IDLE, ENABLE); //启用的USART3中断 USART_Cmd(SERIAL1, ENABLE); } /********************************************* * @funName : BSP_SwInitSerial1 * @Description : 串行通信口1 软件资源初始化 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 ************************************************/ void BSP_SwInitSerial1(void) { // if(NULL == queueRecvData) // { // queueRecvData = xQueueCreate(SERIAL_DATA_QUEUE_SIZE, sizeof(uint8_t)); // // /* 数据接收队列创建失败 */ // if(NULL == queueRecvData) // { // } // } if(NULL == mutexSerialSend) { mutexSerialSend = xSemaphoreCreateBinary(); /* 数据发送互斥量创建失败 */ if(NULL == mutexSerialSend) { } else { /* 释放数据发送互斥量 */ xSemaphoreGive(mutexSerialSend); } } } /****************************************** * @funName : SERIAL1_IRQHandler * @Description : 串行通信口1 中断,用于处理空闲接收中断, * 获取DMA接收的数据,并缓存至数据队列 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 **************************************************/ void SERIAL1_IRQHandler(void) { //uint8_t byte = 0; uint16_t i = 0, rlen = 0; //if(USART_GetITStatus(SERIAL1, USART_IT_RXNE) != RESET)//接收数据寄存器不空中断 if(USART_GetITStatus(SERIAL1, USART_IT_IDLE) != RESET)//检查UART4中断是否发生 空闲线路检测中断 { // portBASE_TYPE xRecvWoken = pdFALSE; USART_ReceiveData(SERIAL1);//返回USART3外设最近接收到的数据 // if(recv_offline_timer_count > 45) // { // xQueueReset(queueRecvData); // } // recv_offline_timer_count = 0; #if SERIAL1_DMARx_ENABLE//接收中断 rlen = SERIAL_RX_BUFF_SIZE - DMA_GetCurrDataCounter(SERIAL1_DMARx_Channel); DMA_Cmd(SERIAL1_DMARx_Channel, DISABLE);//禁止DMA1接收 //DMA_ClearFlag(SERIAL1_DMARx_FLAG);//清除DMA2通道的挂起标志 if(recv_offline_timer_count > 45) { MD_PowerDataPush(POWER_DEVICE_1, true, DMA_RxBuff, rlen); } else { MD_PowerDataPush(POWER_DEVICE_1, false, DMA_RxBuff, rlen); } recv_offline_timer_count = 0; // if(recv_offline_timer_count > 45) // { // xQueueReset(queueRecvData); // } // recv_offline_timer_count = 0; // if(rlen > 0 && NULL != queueRecvData) // { // /* DMA接收数据存入数据队列 */ // for(i = 0; i < rlen;i ++)//i++不能写错 // { // //recv_offline_timer_count = 0; // if(errQUEUE_FULL == xQueueSendFromISR(queueRecvData, &DMA_RxBuff[i], &xRecvWoken))//队列从ISR发送 // { // break; // } // } // } DMA_SetCurrDataCounter(SERIAL1_DMARx_Channel, SERIAL_RX_BUFF_SIZE);//设置当前DMA2通道3传输中的数据单元数 DMA_Cmd(SERIAL1_DMARx_Channel, ENABLE); recv_offline_timer_count=0; //清零离线计数器 #else USART_ClearITPendingBit(SERIAL1, USART_IT_RXNE);//清除USART3的中断挂起位 xQueueSendFromISR(queueRecvData, &byte, &xRecvWoken);//调用xQueueGenericSendFromISR()的宏 #endif USART_ClearITPendingBit(SERIAL1, USART_IT_IDLE); } /* 全部数据发送完成,产生该标记 */ // if (USART_GetITStatus(SERIAL1, USART_IT_TC) != RESET)//检查USART3中断是否发生 // { // USART_ClearITPendingBit(SERIAL1, USART_IT_TC); //清除USART3的中断挂起位-传输完全中断 // } } #if SERIAL1_DMATx_ENABLE /***************************************** * @funName : SERIAL1_DMATx_IRQHandler * @Description : 串行通信口1 DMA 发送中断 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/24 *******************************************/ void SERIAL1_DMATx_IRQHandler(void) { portBASE_TYPE xSendWoken = pdFALSE; if(RESET != DMA_GetITStatus(SERIAL1_DMATx_IT_TC)) { /* 关闭 DMA */ DMA_Cmd(SERIAL1_DMATx_Channel, DISABLE); /* 清除标记 */ DMA_ClearITPendingBit(SERIAL1_DMATx_IT_TC); /* 清除数据长度 */ DMA_SetCurrDataCounter(SERIAL1_DMATx_Channel, 0); USART_ITConfig(SERIAL1, USART_IT_TC, DISABLE); if(NULL != mutexSerialSend) { /* 释放 OS 数据发送权限 */ xSemaphoreGiveFromISR(mutexSerialSend, &xSendWoken); portYIELD_FROM_ISR(xSendWoken); } } } #endif /********************************************** * @funName : BSP_Send2Serial1 * @Description : 串行通信口1 DMA发送启动 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 **********************************************/ void BSP_Send2Serial1(uint8_t* sbuf, const uint16_t slen) { uint16_t len = slen; if(slen == 0||NULL == sbuf) { return; } if(len > SERIAL_TX_BUFF_SIZE) { len = SERIAL_TX_BUFF_SIZE; } /******************************************** *获取OS 数据发送权限 * <DMA发送完成后,在串行通信中断服务中释放> *********************************************/ if(NULL != mutexSerialSend) { xSemaphoreTake(mutexSerialSend, portMAX_DELAY); } #if SERIAL1_DMATx_ENABLE // else // { // while(!DMA_GetFlagStatus(SERIAL1_DMATx_IT_TC)); // } #endif #if SERIAL1_DMATx_ENABLE DMA_SetCurrDataCounter(SERIAL1_DMATx_Channel, len); /*发送DMA流的地址不自增*/ //SERIAL1_DMATx_Channel->CCR |= (1 << 10);//----------- /*设置接收和发送的内存地址*/ SERIAL1_DMATx_Channel->CMAR = (uint32_t)sbuf; DMA_Cmd(SERIAL1_DMATx_Channel, ENABLE); USART_DMACmd(SERIAL1, USART_DMAReq_Tx, ENABLE); #else { uint16_t i = 0; while(i < len) { USART_SendData(SERIAL1, sbuf[i]); } if(NULL != mutexSerialSend) { xSemaphoreGive(mutexSerialSend); } } #endif } #if 0 /******************************************** * @funName : BSP_Recv4Serial1 * @Description : 从串口1接收数据队列获取数据 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 **********************************************/ void BSP_Recv4Serial1(uint8_t * rbuf, uint16_t* rlen) { int iCnt = 0, len; *rlen = 0; if(NULL == queueRecvData || NULL == rbuf) { return; } len = uxQueueMessagesWaiting(queueRecvData);//排队等待消息 for(iCnt = 0; iCnt < len; ++iCnt) { if(pdFALSE == xQueueReceive(queueRecvData, &rbuf[iCnt], 0)) { break; } } *rlen = iCnt; } /********************************************* * @funName : BSP_GetCurRecv4Serial1 * @Description : 获取串口1接收数据队列当前数据长度 * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/4/03 *************************************************/ uint16_t BSP_GetCurRecv4Serial1(void) { //等待中的消息队列(通信 接收数据队列) return uxQueueMessagesWaiting(queueRecvData); } #endif /**************************************** * @funName : BSP_SetRecvOffline4Serial1 * @Description : 对数据监听离线状态时间计数进行更新(硬件定时器中执行) * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/4/02 ********************************************/ void BSP_SetRecvOffline4Serial1(void) { ++recv_offline_timer_count; } /********************************************** * @funName : BSP_GetRecvOffline4Serial1 * @Output : 离线状态时间计数 * @Description : 读取数据监听离线状态时间计数(硬件定时器中执行) * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/4/02 *********************************************/ uint16_t BSP_GetRecvOffline4Serial1(void) { return recv_offline_timer_count; } /************************ End of file *************************/ //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART3->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } /*************************************************************************** * @file power_data.c * @brief * **************************************************************************** * @attention * * Created on: 2025-05-12 * Author: YL Monitor Software group * **************************************************************************** * @description * 功率部件的数据信息处理模块 * * ****************************************************************************/ /************************ Includes *************************/ #include "power_data.h" #include "main.h" /************************ Private types *************************/ /************************ Private constants *************************/ /************************ Private macros *************************/ /************************ Private variables *************************/ /* 一级数据缓存:用于功率部件接收数据的实时缓存 */ uint8_t power1_data_cache_L1[POWER_DEVICE_DATA_SIZE] = {0}; uint8_t power2_data_cache_L1[POWER_DEVICE_DATA_SIZE] = {0}; /* 二级数据缓存:用于系统状态监控 */ uint8_t power1_data_cache_L2[POWER_DEVICE_DATA_SIZE] = {0}; uint8_t power2_data_cache_L2[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power1_L1 = NULL; static SemaphoreHandle_t mutex_RW_Power1_L2 = NULL; static SemaphoreHandle_t mutex_RW_Power2_L1 = NULL; static SemaphoreHandle_t mutex_RW_Power2_L2 = NULL; /* 一级缓存当前数据写入位置 */ uint16_t power1_L1_wPos = 0; uint16_t power2_L1_wPos = 0; /* 二级缓存状态:0xAA已上传,0x55未上传 */ uint8_t power1_L2_status = 0x55; uint8_t power2_L2_status = 0x55; /************************ Functions *************************/ /************************************************************ * @funName : MD_SwInitPowerData * @Input : NULL * * @Output : ***************** * @Description : 数据缓存模块软件资源初始化 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void MD_SwInitPowerData(void) { if(NULL == mutex_RW_Power1_L1) { mutex_RW_Power1_L1 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power1_L1) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power1_L1); } } if(NULL == mutex_RW_Power1_L2) { mutex_RW_Power1_L2 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power1_L2) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power1_L2); } } if(NULL == mutex_RW_Power2_L1) { mutex_RW_Power2_L1 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power2_L1) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power2_L1); } } if(NULL == mutex_RW_Power2_L2) { mutex_RW_Power2_L2 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power2_L2) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power2_L2); } } } /************************************************************ * @funName : prvUpdatePowerL2 * @Input : device-功率部件序号 * * @Output : ***************** * @Description : 更新功率部件二级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void prvUpdatePowerL2(const uint8_t device) { switch(device) { case POWER_DEVICE_1: { portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy(power1_data_cache_L2, power1_data_cache_L1, POWER_DEVICE_DATA_SIZE); power1_L2_status = 0x55;/* 未发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); }break; case POWER_DEVICE_2: { portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy(power2_data_cache_L2, power2_data_cache_L1, POWER_DEVICE_DATA_SIZE); power2_L2_status = 0x55;/* 未发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); }break; } } /************************************************************ * @funName : MD_PowerDataPush * @Input : device-功率部件序号 * bFirst-是否为第一个数据 * wbuf-数据 * wlen-数据长度 * * @Output : ***************** * @Description : 更新功率部件一级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void MD_PowerDataPush(const uint8_t device, const bool bFirst, const uint8_t* wbuf, const uint16_t wlen) { uint16_t len = wlen; if(wlen <= 0) { return; } switch(device) { case POWER_DEVICE_1: { if(bFirst) { power1_L1_wPos = 0; } if(len > POWER_DEVICE_DATA_SIZE - power1_L1_wPos) { len = POWER_DEVICE_DATA_SIZE - power1_L1_wPos; } portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)&power1_data_cache_L1[power1_L1_wPos], wbuf, len); power1_L1_wPos += len; xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); if(POWER_DEVICE_DATA_SIZE <= power1_L1_wPos){ prvUpdatePowerL2(device); } }break; case POWER_DEVICE_2: { if(bFirst) { power2_L1_wPos = 0; } if(len > POWER_DEVICE_DATA_SIZE - power2_L1_wPos) { len = POWER_DEVICE_DATA_SIZE - power2_L1_wPos; } portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)&power2_data_cache_L1[power2_L1_wPos], wbuf, len); power2_L1_wPos += len; xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); if(POWER_DEVICE_DATA_SIZE <= power2_L1_wPos) { prvUpdatePowerL2(device); } }break; } } /********************功率部件一级缓存数据********************/ /************************************************************ * @funName : MD_ReadPowerL2 * @Input : device-功率部件序号 * rbuf-数据输出缓存 * pos-数据读取位置 * rlen-数据读取长度 * * @Output : ***************** * @Description : 获取功率部件二级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/13 * *************************************************************/ bool MD_ReadPowerL2(const uint8_t device, uint8_t *rbuf, const uint16_t pos, const uint16_t rlen) { if(rlen > POWER_DEVICE_DATA_SIZE || pos >= POWER_DEVICE_DATA_SIZE || POWER_DEVICE_DATA_SIZE - pos < rlen) { return false; } switch(device) { case POWER_DEVICE_1: { xSemaphoreTake(mutex_RW_Power1_L2, portMAX_DELAY); memcpy(rbuf, (uint8_t*)&power1_data_cache_L2[pos], rlen); xSemaphoreGive(mutex_RW_Power1_L2); }break; case POWER_DEVICE_2: { xSemaphoreTake(mutex_RW_Power2_L2, portMAX_DELAY); memcpy(rbuf, (uint8_t*)&power2_data_cache_L2[pos], rlen); xSemaphoreGive(mutex_RW_Power2_L2); }break; } return true; } /************************************************************ * @funName : MD_GetPowerL2 * @Input : device-功率部件序号 * rbuf-数据缓存地址 * * @Output : ***************** * @Description : 获取功率部件二级缓存地址 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/13 * *************************************************************/ bool MD_GetPowerL2(const uint8_t device, uint8_t *rbuf) { bool ret = false; switch(device) { case POWER_DEVICE_1: { xSemaphoreTake(mutex_RW_Power1_L2, portMAX_DELAY); if(0x55 != power1_L2_status) { ret = false; } else { rbuf = (uint8_t*)power1_data_cache_L2; power1_L2_status = 0xFF; //power1_L2_status = 0x55; ret = true; } xSemaphoreGive(mutex_RW_Power1_L2); }break; case POWER_DEVICE_2: { xSemaphoreTake(mutex_RW_Power2_L2, portMAX_DELAY); if(0x55 != power2_L2_status) { ret = false; } else { rbuf = (uint8_t*)power2_data_cache_L2; power2_L2_status = 0xAA; ret = true; } xSemaphoreGive(mutex_RW_Power1_L2); }break; } return ret; } /************************ End of file *************************/ /*************************************************************************** * @file bsp_hmi_eth.c * @brief **************************************************************************** * @attention * Created on: 2025-03-18 * Author: YL Monitor Software group **************************************************************************** * @description ****************************************************************************/ #include "main.h" /************************ Private macros *************************/ /* 人机交互网络通信 DMA 发送中断缓存大小 */ #if HMI_ETH_DMATx_ENABLE #define HMI_ETH_TX_BUFF_SIZE 64 #endif /* 人机交互网络通信 DMA 接收中断缓存大小 */ #if HMI_ETH_DMARx_ENABLE #define HMI_ETH_RX_BUFF_SIZE 400//64 #endif /************************ Private variables *************************/ #if HMI_ETH_DMATx_ENABLE /* 通信 DMA发送缓存 */ static uint8_t DMA_TxBuff[HMI_ETH_TX_BUFF_SIZE] = {0}; #endif #if HMI_ETH_DMARx_ENABLE /* 通信 DMA接收缓存 */ static uint8_t DMA_RxBuff[HMI_ETH_RX_BUFF_SIZE] = {0}; #endif /* 通信 接收数据队列 */ static QueueHandle_t queueRecvData = NULL; static SemaphoreHandle_t mutexHmiEthSend = NULL; /************************ Functions *************************/ /************************************************************ * @funName : BSP_HwInitHmiEth * @Input : NULL * * @Output : ***************** * @Description : 人机交互网络通信 硬件资源初始化 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 * *************************************************************/ void BSP_HwInitHmiEth(void) { GPIO_InitTypeDef GPIO_InitStructure ={0}; USART_InitTypeDef USART_InitStructure ={0}; NVIC_InitTypeDef NVIC_InitStructure ={0}; DMA_InitTypeDef DMA_InitStructure ={0}; /****************Tx****************/ GPIO_InitStructure.GPIO_Pin = HMI_ETH_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(HMI_ETH_TX_PORT, &GPIO_InitStructure); /****************Rx****************/ GPIO_InitStructure.GPIO_Pin = HMI_ETH_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 GPIO_Mode_IN_FLOATING; GPIO_Init(HMI_ETH_RX_PORT, &GPIO_InitStructure); /* 串行通信初始化 */ USART_DeInit(HMI_ETH); USART_InitStructure.USART_BaudRate = HMI_ETH_BAUD_RATE; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(HMI_ETH, &USART_InitStructure); #if HMI_ETH_IT_ENABLE NVIC_InitStructure.NVIC_IRQChannel = HMI_ETH_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = HMI_ETH_PreemptionPriority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //USART_ITConfig(HMI_ETH, USART_IT_IDLE, ENABLE); USART_ITConfig(HMI_ETH, USART_IT_RXNE, ENABLE); #endif #if HMI_ETH_DMATx_ENABLE /* DMA发送初始化 */ DMA_DeInit(HMI_ETH_DMATx_Channel); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&HMI_ETH->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_TxBuff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = HMI_ETH_TX_BUFF_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular DMA_Mode_Normal DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(HMI_ETH_DMATx_Channel, &DMA_InitStructure); /* DMA发送中断优先级设置 */ NVIC_InitStructure.NVIC_IRQChannel = HMI_ETH_DMATx_IRQn ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = HMI_ETH_DMATx_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(HMI_ETH_DMATx_Channel, DMA_IT_TC, ENABLE); USART_DMACmd(HMI_ETH, USART_DMAReq_Tx, ENABLE); DMA_Cmd(HMI_ETH_DMATx_Channel, DISABLE); #endif #if HMI_ETH_DMARx_ENABLE /* DMA接收初始化 */ DMA_DeInit(HMI_ETH_DMARx_Channel); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&HMI_ETH->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_RxBuff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = HMI_ETH_RX_BUFF_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA_Mode_Circular DMA_Mode_Normal DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(HMI_ETH_DMARx_Channel, &DMA_InitStructure); /* DMA接收中断优先级设置 */ NVIC_InitStructure.NVIC_IRQChannel = HMI_ETH_DMARx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = HMI_ETH_DMARx_PreemptionPriority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(HMI_ETH_DMARx_Channel, DMA_IT_TC, ENABLE); DMA_Cmd(HMI_ETH_DMARx_Channel, ENABLE); USART_DMACmd(HMI_ETH, USART_DMAReq_Rx, ENABLE); #endif USART_Cmd(HMI_ETH, ENABLE); } /************************************************************ * @funName : BSP_SwInitHmiEth * @Input : NULL * * @Output : ***************** * @Description : 人机交互网络通信 软件资源初始化 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 * *************************************************************/ void BSP_SwInitHmiEth(void) { if(NULL == queueRecvData) { queueRecvData = xQueueCreate(HMI_ETH_RX_QUEUE_SIZE, sizeof(uint8_t)); /* 数据接收队列创建失败 */ if(NULL == queueRecvData) { } } if(NULL == mutexHmiEthSend) { mutexHmiEthSend = xSemaphoreCreateBinary(); /* 数据发送互斥量创建失败 */ if(NULL == mutexHmiEthSend) { } else { /* 释放数据发送互斥量 */ xSemaphoreGive(mutexHmiEthSend); } } } /************************************************************ * @funName : HMI_ETH_IRQHandler * @Input : NULL * @Output : ***************** * @Description : 人机交互网络通信 中断,用于处理空闲接收中断, * 获取DMA接收的数据,并缓存至数据队列 ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 *************************************************************/ void HMI_ETH_IRQHandler(void) { if(USART_GetITStatus(HMI_ETH, USART_IT_RXNE) != RESET) { uint8_t byte = 0; uint16_t i = 0, rlen = 0; portBASE_TYPE xRecvWoken = pdFALSE; byte = USART_ReceiveData(HMI_ETH); #if HMI_ETH_DMARx_ENABLE rlen = HMI_ETH_RX_BUFF_SIZE - DMA_GetCurrDataCounter(HMI_ETH_DMARx_Channel); DMA_Cmd(HMI_ETH_DMARx_Channel, DISABLE); DMA_ClearFlag(HMI_ETH_DMARx_FLAG); if(rlen > 0 && NULL != queueRecvData) { /* DMA接收数据存入数据队列 */ for(i = 0; i < rlen; ++i){ //recv_offline_timer_count = 0; if(errQUEUE_FULL == xQueueSendFromISR(queueRecvData, &DMA_RxBuff[i], &xRecvWoken)) { break; } } } USART_ClearITPendingBit(HMI_ETH, USART_IT_IDLE); DMA_SetCurrDataCounter(HMI_ETH_DMARx_Channel, HMI_ETH_RX_BUFF_SIZE); DMA_Cmd(HMI_ETH_DMARx_Channel, ENABLE); #else USART_ClearITPendingBit(HMI_ETH, USART_IT_RXNE); xQueueSendFromISR(queueRecvData, &byte, &xRecvWoken); #endif } /* 全部数据发送完成,产生该标记 */ if (USART_GetITStatus(HMI_ETH, USART_IT_TC) != RESET) { USART_ClearITPendingBit(HMI_ETH, USART_IT_TC); } } #if HMI_ETH_DMATx_ENABLE /************************************************************ * @funName : HMI_ETH_DMATx_IRQHandler * @Input : NULL * @Output : ***************** * @Description : 人机交互网络通信 DMA 发送中断 ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/24 *************************************************************/ void HMI_ETH_DMATx_IRQHandler(void) { portBASE_TYPE xSendWoken = pdFALSE; if(RESET != DMA_GetITStatus(HMI_ETH_DMATx_IT_TC)) { /* 关闭 DMA */ DMA_Cmd(HMI_ETH_DMATx_Channel, DISABLE); /* 清除完成标记 */ DMA_ClearITPendingBit(HMI_ETH_DMATx_IT_TC); /* 清除数据长度 */ DMA_SetCurrDataCounter(HMI_ETH_DMATx_Channel, 0); USART_ITConfig(HMI_ETH, USART_IT_TC, DISABLE); if(NULL != mutexHmiEthSend){ /* 释放 OS 数据发送权限 */ xSemaphoreGiveFromISR(mutexHmiEthSend, &xSendWoken); portYIELD_FROM_ISR(xSendWoken); } } } #endif /************************************************************ * @funName : BSP_Send2HmiEth * @Input : NULL * @Output : ***************** * @Description : 人机交互网络通信 DMA 数据发送 ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 * *************************************************************/ void BSP_Send2HmiEth(uint8_t* sbuf, const uint16_t slen) { uint16_t len = slen; if(len == 0 ||NULL == sbuf) { return; } /******************************************** *获取OS 数据发送权限 * <DMA发送完成后,在串行通信中断服务中释放> *********************************************/ if(NULL != mutexHmiEthSend) { xSemaphoreTake(mutexHmiEthSend, portMAX_DELAY); } #if HMI_ETH_DMATx_ENABLE /* 开启人机交互网络通信 DMA 发送中断 */ else { //检查是否设置了DMA1通道标志 DMA1_IT_TC4 while(!DMA_GetFlagStatus(HMI_ETH_DMATx_IT_TC)); } #endif #if HMI_ETH_DMATx_ENABLE //开启人机交互网络通信 DMA 发送中断 //设置当前DMA1通道传输中的数据单元数 DMA_SetCurrDataCounter(HMI_ETH_DMATx_Channel, len);//DMA1_Channel4 /*发送DMA流的地址不自增*/ HMI_ETH_DMATx_Channel->CCR |= (1 << 10); /*设置接收和发送的内存地址*/ HMI_ETH_DMATx_Channel->CMAR = (uint32_t)sbuf; //启用DMA1通道4 DMA_Cmd(HMI_ETH_DMATx_Channel, ENABLE); //启用USART1的DMA接口 USART DMA传输请求 USART_DMACmd(HMI_ETH, USART_DMAReq_Tx, ENABLE); #else { uint16_t i = 0; while(i < len) { USART_SendData(HMI_ETH, sbuf[i]); } if(NULL != mutexHmiEthSend) { xSemaphoreGive(mutexHmiEthSend); } } #endif } /************************************************************ * @funName : BSP_Send2QueueHmiEth * @Input : NULL * @Output : ***************** * @Description: 从人机交互网络通信接收数据队列获取数据 ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/3/22 *************************************************************/ void BSP_Recv4HmiEth(uint8_t *rbuf, uint16_t *rlen) { uint16_t iCnt = 0; *rlen = 0; if(NULL == queueRecvData || NULL == rbuf) { return; } for(iCnt = 0; iCnt < HMI_ETH_RX_QUEUE_SIZE; ++iCnt){ if(pdFALSE == xQueueReceive(queueRecvData, &rbuf[iCnt], 0)){ break; } } *rlen = iCnt; } /************************ End of file *************************/ STM32F105 USART3收到400个字节数据后再通过USART1发送给上位机,但上位机最终接收到的400个字节有215个结果都为0,数据发生异常,该如何解决,用标准库写出详细代码和注释

#include "ucos_ii.h" #include "stm32f10x.h" #include <stdio.h> #include <stdlib.h> #define ITM_PORT (*(volatile unsigned char *)(0xe0000000)) #define DEMCR_ (*(volatile unsigned long *)(0xE000EDFC)) #define TRCENA_ 0X01000000 #define BufferLen 100 typedef struct { void (*task_func)(void *p_arg); void *pdata; OS_STK *ptos; INT8U prio; } TaskCreate; //char buffer[BufferLen]; uint8_t fputcp(char ch) { if(DEMCR_ & TRCENA_) { while(ITM_PORT == 0); ITM_PORT = ch; } else { return 0; } return 1; } uint8_t print_str(char *str) { uint32_t i; i = 0; while(1) { if (*(str+i) == '\0') { return 1; } if(fputcp(*(str+i))==0) { return 0; } i++; } } void *buffer; static void systick_init(void) { RCC_ClocksTypeDef rcc_clocks; RCC_GetClocksFreq(&rcc_clocks); *((uint32_t *)buffer)=rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC; SysTick_Config(rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC); } static void syscall_systick_init(void) { RCC_ClocksTypeDef rcc_clocks; RCC_GetClocksFreq(&rcc_clocks); *((uint32_t *)buffer)=rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC; __asm { SWI 0x02 } //SysTick_Config(rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC); } /*void syscall_OSIntExit() { __ASM { SWI 0x06 } }*/ /*void syscall_OSIntEnter() { __ASM { SWI 0x07 } }*/ void syscall_print_str(char *str) { int i=0; while(1) { if (*(str+i) == '\0') { ((char *)buffer)[i] = str[i]; break; } ((char *)buffer)[i] = str[i]; i++; } __ASM{ SWI 0x01 } } void syscall_OSTaskCreate(void (*task)(void *), void *pdata, OS_STK *ptos, INT8U prio) { TaskCreate *partfo = (TaskCreate *)buffer; partfo->task_func = task; partfo->pdata = pdata; partfo->ptos = ptos; partfo->prio = prio; __ASM { SWI 0x03 } } void syscall_OSTimeDly(int time) { *(int*)buffer=time; __ASM { SWI 0x04 } } void syscall_OSStart() { __ASM { SWI 0x05 } } void ASM_Switch_To_Unprivileged(void); //#define FIRST_TASK 1 #define SECOND_TASK 1 #ifdef FIRST_TASK int main(void) { buffer = malloc(BufferLen); ASM_Switch_To_Unprivileged(); syscall_print_str("Hello world!\n"); syscall_systick_init(); while(1){} } #endif #ifdef SECOND_TASK static OS_STK task1_stk[TASK1_STK_SIZE]; static OS_STK task2_stk[TASK2_STK_SIZE]; void task1(void *p_arg); void task2(void *p_arg); int main(void) { OSInit(); buffer = malloc(BufferLen); ASM_Switch_To_Unprivileged(); syscall_print_str("Hello world!\n"); syscall_systick_init(); syscall_OSTaskCreate(task1, (void *)0, &task1_stk[TASK1_STK_SIZE-1], TASK1_PRIO); syscall_OSTaskCreate(task2, (void *)0, &task2_stk[TASK2_STK_SIZE-1], TASK2_PRIO); syscall_OSStart(); return 0; } static void task1(void *p_arg) { for (;;) { syscall_OSTimeDly(100); syscall_print_str("Hello from Task 1!\n"); syscall_OSTimeDly(100); } } static void task2(void *p_arg) { for (;;) { syscall_OSTimeDly(100); syscall_print_str("Hello from Task 2!\n"); syscall_OSTimeDly(100); } } #endif /*END OF THE FILE*/ /** ****************************************************************************** * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main Interrupt Service Routines. * This file provides template for all exceptions handler and * peripherals interrupt service routine. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *
© COPYRIGHT 2011 STMicroelectronics
****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_it.h" #include "ucos_ii.h" void print_str(char *); /** @addtogroup STM32F10x_StdPeriph_Template * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /******************************************************************************/ /* Cortex-M3 Processor Exceptions Handlers */ /******************************************************************************/ /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ print_str("Hard Fault exception occurs!\n"); while (1) { } } void EXTI0_IRQHandler(void) { print_str("EXTI0_IRQHandler!\n"); } /** * @brief This function handles Memory Manage exception. * @param None * @retval None */ void MemManage_Handler(void) { /* Go to infinite loop when Memory Manage exception occurs */ while (1) { } } /** * @brief This function handles Bus Fault exception. * @param None * @retval None */ void BusFault_Handler(void) { /* Go to infinite loop when Bus Fault exception occurs */ while (1) { } } /** * @brief This function handles Usage Fault exception. * @param None * @retval None */ void UsageFault_Handler(void) { /* Go to infinite loop when Usage Fault exception occurs */ while (1) { } } typedef struct { void (*task_func)(void *p_arg); void *pdata; OS_STK *ptos; INT8U prio; } TaskCreate; extern void * buffer; void SVC_Handler_Main(int flag) { OSIntEnter(); switch (flag) { case 0x01: { char *str = (char *)buffer; print_str(str); // Your code here break; } case 0x02: { uint32_t ticks = *((uint32_t *)buffer); SysTick_Config(ticks); // Your code here break; } case 0x03: { TaskCreate *partfo = (TaskCreate *)buffer; OSTaskCreate(partfo->task_func,partfo->pdata,partfo->ptos,partfo->prio); break; } case 0x04: { OSTimeDly(*(int*)buffer); break; } case 0x05: { OSStart(); break; } /*case 0x06: { OSIntExit(); break; } case 0x07: { OSIntEnter(); break; }*/ } OSIntExit(); } /** * @brief This function handles Debug Monitor exception. * @param None * @retval None */ void DebugMon_Handler(void) { } /** * @brief This function handles PendSVC exception. * @param None * @retval None */ void PendSV_Handler(void) { } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { //print_str("hello from sysTick!\n"); OSIntEnter(); OSTimeTick(); OSIntExit(); } /******************************************************************************/ /* STM32F10x Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* available peripheral interrupt handler's name please refer to the startup */ /* file (startup_stm32f10x_xx.s). */ /******************************************************************************/ /** * @brief This function handles PPP interrupt request. * @param None * @retval None */ /*void PPP_IRQHandler(void) { }*/ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/为什么只能输出任务1无法输出任务2

#ifndef LIGHT_SENSOR_H #define LIGHT_SENSOR_H #include <stdint.h> #include "hal_adc.h" // 假设使用TI HAL ADC库,根据实际平台替换 #ifdef __cplusplus extern "C" { #endif /********************************************************************* * CONSTANTS */ // 光敏传感器使用的ADC通道 #define LIGHT_SENSOR_ADC_CHANNEL HAL_ADC_CH6 // 使用AIN6作为输入 // 光照强度等级阈值(根据实际传感器校准) #define LIGHT_LEVEL_DARK 500 // 暗 #define LIGHT_LEVEL_LOW 800 // 弱光 #define LIGHT_LEVEL_BRIGHT 1024 // 明亮 // 返回类型定义 typedef enum { LIGHT_STATE_DARK, // 黑暗 LIGHT_STATE_LOW, // 弱光 LIGHT_STATE_BRIGHT // 明亮 } LightState_t; /********************************************************************* * API FUNCTIONS */ /** * @brief 初始化光照传感器 * @return 成功返回0,失败返回错误码 */ int LightSensor_Init(void); /** * @brief 读取当前光照ADC原始值 * @param[out] pValue 指向存储ADC值的变量 * @return 成功返回0,失败返回错误码 */ int LightSensor_ReadRaw(uint16_t *pValue); /** * @brief 获取当前光照强度等级 * @return 光照状态枚举值(LightState_t) */ LightState_t LightSensor_GetState(void); /** * @brief 将ADC原始值转换为光照强度等级 * @param adcValue ADC原始值 * @return 光照状态枚举值(LightState_t) */ LightState_t LightSensor_ConvertToState(uint16_t adcValue); /** * @brief 设置光照等级检测阈值 * @param darkThreshold 黑暗阈值 * @param lowThreshold 弱光阈值 */ void LightSensor_SetThresholds(uint16_t darkThreshold, uint16_t lowThreshold); #ifdef __cplusplus } #endif #endif /* LIGHT_SENSOR_H */根据这个头文件,帮我生成一个光敏传感器的.c文件,要求能采集到数据,并在串口上看到

最新推荐

recommend-type

工程项目管理的高效团队建设与管理.docx

工程项目管理的高效团队建设与管理.docx
recommend-type

信息化设计说课市公开课一等奖百校联赛获奖课件.pptx

信息化设计说课市公开课一等奖百校联赛获奖课件.pptx
recommend-type

基于ASP手机销售网站设计与实现的毕业论文模板.doc

基于ASP手机销售网站设计与实现的毕业论文模板.doc
recommend-type

胶圈接口PVCU管道综合项目施工设计专项方案.doc

胶圈接口PVCU管道综合项目施工设计专项方案.doc
recommend-type

软件项目开发和管理规范.doc

软件项目开发和管理规范.doc
recommend-type

ASP.NET新闻管理系统:用户管理与内容发布功能

知识点: 1. ASP.NET 概念:ASP.NET 是一个开源、服务器端 Web 应用程序框架,用于构建现代 Web 应用程序。它是 .NET Framework 的一部分,允许开发者使用 .NET 语言(例如 C# 或 VB.NET)来编写网页和 Web 服务。 2. 新闻发布系统功能:新闻发布系统通常具备用户管理、新闻分级、编辑器处理、发布、修改、删除等功能。用户管理指的是系统对不同角色的用户进行权限分配,比如管理员和普通编辑。新闻分级可能是为了根据新闻的重要程度对它们进行分类。编辑器处理涉及到文章内容的编辑和排版,常见的编辑器有CKEditor、TinyMCE等。而发布、修改、删除功能则是新闻发布系统的基本操作。 3. .NET 2.0:.NET 2.0是微软发布的一个较早版本的.NET框架,它是构建应用程序的基础,提供了大量的库和类。它在当时被广泛使用,并支持了大量企业级应用的构建。 4. 文件结构分析:根据提供的压缩包子文件的文件名称列表,我们可以看到以下信息: - www.knowsky.com.txt:这可能是一个文本文件,包含着Knowsky网站的一些信息或者某个页面的具体内容。Knowsky可能是一个技术社区或者文档分享平台,用户可以通过这个链接获取更多关于动态网站制作的资料。 - 源码下载.txt:这同样是一个文本文件,顾名思义,它可能包含了一个新闻系统示例的源代码下载链接或指引。用户可以根据指引下载到该新闻发布系统的源代码,进行学习或进一步的定制开发。 - 动态网站制作指南.url:这个文件是一个URL快捷方式,它指向一个网页资源,该资源可能包含关于动态网站制作的教程、指南或者最佳实践,这对于理解动态网站的工作原理和开发技术将非常有帮助。 - LixyNews:LixyNews很可能是一个项目文件夹,里面包含新闻发布系统的源代码文件。通常,ASP.NET项目会包含多个文件,如.aspx文件(用户界面)、.cs文件(C#代码后台逻辑)、.aspx.cs文件(页面的代码后台)等。这个文件夹中应该还包含Web.config配置文件,它用于配置整个项目的运行参数和环境。 5. 编程语言和工具:ASP.NET主要是使用C#或者VB.NET这两种语言开发的。在该新闻发布系统中,开发者可以使用Visual Studio或其他兼容的IDE来编写、调试和部署网站。 6. 新闻分级和用户管理:新闻分级通常涉及到不同的栏目分类,分类可以是按照新闻类型(如国际、国内、娱乐等),也可以是按照新闻热度或重要性(如头条、焦点等)进行分级。用户管理则是指系统需具备不同的用户身份验证和权限控制机制,保证只有授权用户可以进行新闻的发布、修改和删除等操作。 7. 编辑器处理:一个新闻发布系统的核心组件之一是所使用的Web编辑器。这个编辑器可以是内置的简单文本框,也可以是富文本编辑器(WYSIWYG,即所见即所得编辑器),后者能够提供类似于Word的编辑体验,并能输出格式化后的HTML代码。CKEditor和TinyMCE是常用的开源Web编辑器,它们支持插入图片、视频、表格等多种媒体,并能对文本进行复杂的格式化操作。 8. 发布、修改和删除功能:这是新闻发布系统的基本操作功能。发布功能允许用户将编辑好的新闻内容上线;修改功能可以对已发布的新闻内容进行更新;删除功能则用于移除不再需要的新闻文章。这些操作通常需要后台管理界面来支持,并且系统会在数据库中记录相关操作的记录,以便管理历史版本和审计日志。 以上知识点覆盖了从ASP.NET基础、新闻发布系统的具体功能实现到系统开发过程中的细节处理等多个方面。开发者在构建类似系统时,需要深入了解这些知识点,才能设计和实现一个功能完备、易用、安全的新闻发布系统。
recommend-type

【实战派量化投资秘籍】:Pair Trading策略全方位解析

# 摘要 量化投资中的Pair Trading策略是一种依赖统计套利和市场效率假说的交易方法,其核心在于选择相关性高的资产作为交易对并应用协整理论进行市场中立投资。本文首先概述了Pair Trading策略的理论基础,随后详细探讨了策略的实操技巧,包括数据预处理、模型建立和交易信号生成。接着,文章重点介绍了策略的编程实现,提供了环境搭建
recommend-type

fpga中保持时间建立时间时序约束

<think>我们讨论的是FPGA中的建立时间(Setup Time)和保持时间(Hold Time)时序约束问题。建立时间是指在时钟有效边沿到来之前,数据必须保持稳定的最小时间。保持时间是指在时钟有效边沿到来之后,数据必须保持稳定的最小时间。时序约束就是确保设计满足这些时间要求。 在FPGA设计中,我们通过时序约束(如时钟约束、输入输出延迟约束等)来告知工具设计的时序要求,工具会根据这些约束进行优化和验证。 以下是关于建立时间和保持时间时序约束的详细说明: ### 1. 建立时间和保持时间的基本概念 - **建立时间(Setup Time)**:时钟边沿到达前,数据必须稳定的时间。 -
recommend-type

Notepad2: 高效替代XP系统记事本的多功能文本编辑器

### 知识点详解 #### 标题解析 - **Vista记事本(Notepad2)**: Vista记事本指的是一款名为Notepad2的文本编辑器,它不是Windows Vista系统自带的记事本,而是一个第三方软件,具备高级编辑功能,使得用户在编辑文本文件时拥有更多便利。 - **可以替换xp记事本Notepad**: 这里指的是Notepad2拥有替换Windows XP系统自带记事本(Notepad)的能力,意味着用户可以安装Notepad2来获取更强大的文本处理功能。 #### 描述解析 - **自定义语法高亮**: Notepad2支持自定义语法高亮显示,可以对编程语言如HTML, XML, CSS, JavaScript等进行关键字着色,从而提高代码的可读性。 - **支持多种编码互换**: 用户可以在不同的字符编码格式(如ANSI, Unicode, UTF-8)之间进行转换,确保文本文件在不同编码环境下均能正确显示和编辑。 - **无限书签功能**: Notepad2支持设置多个书签,用户可以根据需要对重要代码行或者文本行进行标记,方便快捷地进行定位。 - **空格和制表符的显示与转换**: 该编辑器可以将空格和制表符以不同颜色高亮显示,便于区分,并且可以将它们互相转换。 - **文本块操作**: 支持使用ALT键结合鼠标操作,进行文本的快速选择和编辑。 - **括号配对高亮显示**: 对于编程代码中的括号配对,Notepad2能够高亮显示,方便开发者查看代码结构。 - **自定义代码页和字符集**: 支持对代码页和字符集进行自定义,以提高对中文等多字节字符的支持。 - **标准正则表达式**: 提供了标准的正则表达式搜索和替换功能,增强了文本处理的灵活性。 - **半透明模式**: Notepad2支持半透明模式,这是一个具有视觉效果的功能,使得用户体验更加友好。 - **快速调整页面大小**: 用户可以快速放大或缩小编辑器窗口,而无需更改字体大小。 #### 替换系统记事本的方法 - **Windows XP/2000系统替换方法**: 首先关闭系统文件保护,然后删除系统文件夹中的notepad.exe,将Notepad2.exe重命名为notepad.exe,并将其复制到C:\Windows和C:\Windows\System32目录下,替换旧的记事本程序。 - **Windows 98系统替换方法**: 直接将重命名后的Notepad2.exe复制到C:\Windows和C:\Windows\System32目录下,替换旧的记事本程序。 #### 关闭系统文件保护的方法 - 通过修改Windows注册表中的"SFCDisable"键值,可以临时禁用Windows系统的文件保护功能。设置键值为"FFFFFF9D"则关闭文件保护,设置为"0"则重新启用。 #### 下载地址 - 提供了Notepad2的下载链接,用户可以通过该链接获取安装包。 #### 文件压缩包内文件名 - **Notepad2MOD1.1.0.8CN.exe**: 这是压缩包内所含的Notepad2编译版本,表明这是一个中文版的安装程序,版本号为1.1.0.8。 ### 总结 Notepad2是一款强大的文本编辑器,它继承了传统的记事本程序界面,同时引入了诸多增强功能,如语法高亮、编码格式转换、书签管理、文本操作快捷键、括号高亮匹配等。这使得它在处理代码、标记语言和其他文本文件时具备极大的优势。用户可以通过替换系统默认记事本的方式,将Notepad2融入到操作系统中,充分享受这些高级功能带来的便捷。同时,提供了关闭系统文件保护的方法,以便用户能够顺利完成替换工作。最后,给出了下载地址,方便用户获取软件安装包。
recommend-type

【mPower1203驱动故障全攻略】:排除新手疑难杂症,提升部署效率

# 1. mPower1203驱动概述与故障诊断基础 在当今信息技术飞速发展的时代,高效准确地诊断和解决驱动故障对于确保企业级IT系统的稳定运行至关重要。mPower1203驱动作为一个广泛应用于高性能计算和数据处理领域的驱动程序,它的稳定性和性能优化对于很多关键业务系统都是不可忽视的。本章节将为您提供一个mPower1203驱动的概述,并对故障诊断的