启动系统日志i8042prt错误

本文介绍了解决Windows系统启动时出现i8042prt加载失败的方法。i8042prt用于控制PS/2接口的键盘和鼠标,在使用USB设备时可能导致该错误。提供了两种解决方案:一是通过修改注册表禁用i8042prt服务;二是对于使用PS/2 KVM的情况,可通过修改注册表设置以支持热插拔。
 

==========================================
Type: Error
Time: 2006-10-12 10:23:17
Source: Service Control Manager
Category: None
User: N/A
Computer:SZFF-6E48A8BE2
Event ID: 7026
Description:
下列引导或系统启动驱动程序无法加载:
i8042prt
==========================================

什么原因 如何解决 是不是键盘兼容性问题?


i8042prt 控制ps/2的键盘和鼠标, 如果你使用的为USB键盘和鼠标, 就可能出现此错误,
可修改注册表, 禁用i8042prt
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt]
把start的键值从1变为4, 就是SERVICE_DISABLED

原因: i8042prt 是控制 PS/2 的鍵盤及滑鼠,如果使用 USB 鍵盤和滑鼠或移除 PS/2 鍵盤及滑鼠,就會出現此錯誤訊息。

解決方法:方法一: 如果使用 USB 鍵盤及滑鼠,修改機碼,Disable i8042prt  

 Key:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt]  

Value:Start  

Type:REG_DWORD  

Data:1(Start Service)|4(Stop Service)

方法二 如果有使用 PS/2 的 KVM,可能會發生此問題,修改機碼讓 OS 支援 hotplug  

Key:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters]  

Value:Headless  

Type:REG_DWORD  

Data:1(Allow Hotplugging)|0(Hotplugging not allowed)

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/611609/viewspace-605746/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/611609/viewspace-605746/

#ifndef ADC_PROCESS_H #define ADC_PROCESS_H #include "stm32g0xx_hal.h" // 修正枚举名:添加ADC_PROC_前缀,避免与HAL库冲突 typedef enum { ADC_PROC_CHANNEL_4 = 0, // 对应硬件ADC通道4 ADC_PROC_CHANNEL_5, // 对应硬件ADC通道5 ADC_PROC_CHANNEL_6, // 对应硬件ADC通道6 ADC_PROC_CHANNEL_7, // 对应硬件ADC通道7 ADC_PROC_CHANNEL_MAX } ADC_ProcChannelTypeDef; // ADC处理结构体(封装所有ADC相关数据) typedef struct { ADC_HandleTypeDef *hadc; // ADC句柄 DMA_HandleTypeDef *hdma; // DMA句柄 TIM_HandleTypeDef *htim; // 定时器句柄(用于数据更新) uint16_t dma_buf[512]; // DMA接收缓冲区 uint16_t ch_buf[ADC_PROC_CHANNEL_MAX][30]; // 各通道循环缓冲区(深度30) float ref_voltage; // 参考电压 float voltage_offset; // 电压偏移量 float calibration_factor; // 校准系数 uint16_t adc_offset; // 偏移量对应的ADC值 uint16_t average[ADC_PROC_CHANNEL_MAX];// 各通道平均值 uint8_t buf_index; // 循环缓冲区索引 } ADC_ProcessHandleTypeDef; // 初始化ADC处理模块 HAL_StatusTypeDef AdcProcess_Init(ADC_ProcessHandleTypeDef *hadc_proc, ADC_HandleTypeDef *hadc, DMA_HandleTypeDef *hdma, TIM_HandleTypeDef *htim); // 获取通道平均值(对外接口) uint16_t AdcProcess_GetAverage(ADC_ProcessHandleTypeDef *hadc_proc, ADC_ProcChannelTypeDef channel); // DMA数据处理(定时器中断中调用) void AdcProcess_HandleDMAData(ADC_ProcessHandleTypeDef *hadc_proc); #endif // ADC_PROCESS_H #include "adc_process.h" #include <string.h> // 初始化ADC处理模块 HAL_StatusTypeDef AdcProcess_Init(ADC_ProcessHandleTypeDef *hadc_proc, ADC_HandleTypeDef *hadc, DMA_HandleTypeDef *hdma, TIM_HandleTypeDef *htim) { if (hadc_proc == NULL || hadc == NULL || hdma == NULL || htim == NULL) { return HAL_ERROR; } // 初始化句柄 hadc_proc->hadc = hadc; hadc_proc->hdma = hdma; hadc_proc->htim = htim; // 校准参数配置 hadc_proc->ref_voltage = 2.5f; hadc_proc->voltage_offset = 0.06f; hadc_proc->calibration_factor = hadc_proc->ref_voltage / (hadc_proc->ref_voltage + 0.07f); hadc_proc->adc_offset = (uint16_t)(hadc_proc->voltage_offset * 4095 / hadc_proc->ref_voltage); // 清空缓冲区 memset(hadc_proc->dma_buf, 0, sizeof(hadc_proc->dma_buf)); for (uint8_t i = 0; i < ADC_PROC_CHANNEL_MAX; i++) { memset(hadc_proc->ch_buf[i], 0, sizeof(hadc_proc->ch_buf[i])); hadc_proc->average[i] = 0; } hadc_proc->buf_index = 0; // 启动ADC DMA和定时器 HAL_ADC_Start_DMA(hadc, (uint32_t*)hadc_proc->dma_buf, sizeof(hadc_proc->dma_buf)/sizeof(uint16_t)); HAL_TIM_Base_Start_IT(htim); return HAL_OK; } // 处理DMA数据,计算校准值和平均值 void AdcProcess_HandleDMAData(ADC_ProcessHandleTypeDef *hadc_proc) { uint32_t ch_sum[ADC_PROC_CHANNEL_MAX] = {0}; uint16_t samples = 0; // 1. 计算单次DMA缓冲区的各通道总和(映射:i+0=通道4,i+1=通道5,i+2=通道6,i+3=通道7) for (uint16_t i = 0; i < sizeof(hadc_proc->dma_buf)/sizeof(uint16_t); i += ADC_PROC_CHANNEL_MAX) { // 通道4:ADC_PROC_CHANNEL_4(索引0) if (i + 0 < sizeof(hadc_proc->dma_buf)/sizeof(uint16_t)) { ch_sum[ADC_PROC_CHANNEL_4] += hadc_proc->dma_buf[i + 0] & 0x0FFF; } // 通道5:ADC_PROC_CHANNEL_5(索引1) if (i + 1 < sizeof(hadc_proc->dma_buf)/sizeof(uint16_t)) { ch_sum[ADC_PROC_CHANNEL_5] += hadc_proc->dma_buf[i + 1] & 0x0FFF; } // 通道6:ADC_PROC_CHANNEL_6(索引2) if (i + 2 < sizeof(hadc_proc->dma_buf)/sizeof(uint16_t)) { ch_sum[ADC_PROC_CHANNEL_6] += hadc_proc->dma_buf[i + 2] & 0x0FFF; } // 通道7:ADC_PROC_CHANNEL_7(索引3) if (i + 3 < sizeof(hadc_proc->dma_buf)/sizeof(uint16_t)) { ch_sum[ADC_PROC_CHANNEL_7] += hadc_proc->dma_buf[i + 3] & 0x0FFF; } samples++; } // 2. 校准并存储到循环缓冲区 for (uint8_t ch = 0; ch < ADC_PROC_CHANNEL_MAX; ch++) { uint16_t avg_single = (uint16_t)(ch_sum[ch] / samples); // 校准:系数校准 + 偏移校准 uint16_t calibrated = (uint16_t)(avg_single * hadc_proc->calibration_factor); calibrated = (calibrated > hadc_proc->adc_offset) ? (calibrated - hadc_proc->adc_offset) : 0; hadc_proc->ch_buf[ch][hadc_proc->buf_index] = calibrated; } // 3. 计算循环缓冲区的平均值 for (uint8_t ch = 0; ch < ADC_PROC_CHANNEL_MAX; ch++) { uint32_t total = 0; for (uint8_t i = 0; i < 30; i++) { total += hadc_proc->ch_buf[ch][i]; } hadc_proc->average[ch] = (uint16_t)(total / 30); } // 4. 更新缓冲区索引 hadc_proc->buf_index = (hadc_proc->buf_index + 1) % 30; } // 获取通道平均值 uint16_t AdcProcess_GetAverage(ADC_ProcessHandleTypeDef *hadc_proc, ADC_ProcChannelTypeDef channel) { if (channel >= ADC_PROC_CHANNEL_MAX) { return 0; } return hadc_proc->average[channel]; } #ifndef SENSOR_UART_H #define SENSOR_UART_H #include "stm32g0xx_hal.h" #include <stdint.h> // 传感器ID枚举 typedef enum { SENSOR_ID_2 = 0, SENSOR_ID_3, SENSOR_ID_4, SENSOR_ID_MAX } SensorIDTypeDef; // 传感器状态机状态 typedef enum { SENSOR_STATE_IDLE = 0, // 空闲状态 SENSOR_STATE_SEND_REQ, // 发送请求状态 SENSOR_STATE_WAIT_RESP, // 等待响应状态 SENSOR_STATE_PROCESS_DATA // 处理数据状态 } SensorStateTypeDef; // 传感器数据缓存结构体 typedef struct { uint16_t reg_11; // 寄存器11数据 uint8_t updated; // 数据更新标志 uint32_t timestamp; // 时间戳 uint8_t valid; // 数据有效标志 } SensorDataCacheTypeDef; // 传感器处理结构体(封装所有传感器相关数据) typedef struct { UART_HandleTypeDef *huart; // UART句柄 SensorIDTypeDef id; // 传感器ID uint8_t dev_addr; // 设备地址 uint8_t func_code; // 功能码 uint8_t reg_addr; // 寄存器地址 uint8_t tx_buf[8]; // 发送缓冲区 uint8_t rx_buf[8]; // 接收缓冲区 SensorStateTypeDef state; // 状态机状态 uint32_t last_op_time; // 上次操作时间(ms) uint16_t timeout; // 超时时间(ms) uint8_t error_count; // 连续错误计数 uint8_t rx_ok_flag; // 接收完成标志 uint8_t rx_count; // 接收字节数 SensorDataCacheTypeDef data; // 数据缓存 } SensorUartHandleTypeDef; // 初始化传感器 HAL_StatusTypeDef SensorUart_Init(SensorUartHandleTypeDef *hsensor, SensorIDTypeDef id, UART_HandleTypeDef *huart, uint8_t dev_addr, uint8_t func_code, uint8_t reg_addr, uint16_t timeout); // 传感器状态机处理(非阻塞,主循环调用) void SensorUart_Process(SensorUartHandleTypeDef *hsensor); // 获取传感器数据(对外接口) SensorDataCacheTypeDef SensorUart_GetData(SensorUartHandleTypeDef *hsensor); // UART接收完成回调函数(需要在stm32g0xx_it.c中调用) void SensorUart_RxCpltCallback(SensorUartHandleTypeDef *hsensor); #endif // SENSOR_UART_H #include "sensor_uart.h" #include "delay.h" #include "string.h" // CRC计算函数(内部使用) static uint16_t CRC16_CreatTx(uint8_t *buf, uint16_t len) { uint16_t crc = 0; uint8_t crc1 = 0, crc2 = 0; for (uint8_t i = 0; i < len; i++) { if (i % 2 == 0) crc1 += buf[i]; crc2 += buf[i]; } crc = crc2 * crc1 * 7639; return crc; } // CRC校验函数(内部使用) static uint8_t CRC16_CheckRx(uint8_t *buf, uint16_t len) { uint16_t crc_calc = 0, crc_rx = 0; uint8_t crc1 = 0, crc2 = 0; for (uint8_t i = 0; i < len - 2; i++) { if (i % 2 == 0) crc1 += buf[i]; crc2 += buf[i]; } crc_rx = (buf[len-2] << 8) | buf[len-1]; crc_calc = crc2 * crc1 * 7639; return (crc_calc == crc_rx) ? 1 : 0; } // 初始化传感器 HAL_StatusTypeDef SensorUart_Init(SensorUartHandleTypeDef *hsensor, SensorIDTypeDef id, UART_HandleTypeDef *huart, uint8_t dev_addr, uint8_t func_code, uint8_t reg_addr, uint16_t timeout) { if (hsensor == NULL || huart == NULL || id >= SENSOR_ID_MAX) { return HAL_ERROR; } hsensor->id = id; hsensor->huart = huart; hsensor->dev_addr = dev_addr; hsensor->func_code = func_code; hsensor->reg_addr = reg_addr; hsensor->timeout = timeout; memset(hsensor->tx_buf, 0, sizeof(hsensor->tx_buf)); memset(hsensor->rx_buf, 0, sizeof(hsensor->rx_buf)); hsensor->state = SENSOR_STATE_IDLE; hsensor->last_op_time = HAL_GetTick(); hsensor->error_count = 0; hsensor->rx_ok_flag = 0; hsensor->rx_count = 0; hsensor->data = (SensorDataCacheTypeDef){0, 0, 0, 0}; return HAL_OK; } // 构建并发送请求帧(内部使用) static HAL_StatusTypeDef SensorUart_SendRequest(SensorUartHandleTypeDef *hsensor) { hsensor->tx_buf[0] = hsensor->dev_addr; hsensor->tx_buf[1] = 0xAA; hsensor->tx_buf[2] = hsensor->func_code; hsensor->tx_buf[3] = hsensor->reg_addr; hsensor->tx_buf[4] = 0x00; hsensor->tx_buf[5] = 0x01; uint16_t crc = CRC16_CreatTx(hsensor->tx_buf, 6); hsensor->tx_buf[6] = (crc >> 8) & 0xFF; hsensor->tx_buf[7] = crc & 0xFF; // 发送数据并启动接收中断 HAL_UART_Abort(hsensor->huart); hsensor->rx_ok_flag = 0; hsensor->rx_count = 0; memset(hsensor->rx_buf, 0, sizeof(hsensor->rx_buf)); if (HAL_UART_Transmit(hsensor->huart, hsensor->tx_buf, 8, 100) != HAL_OK) { return HAL_ERROR; } return HAL_UART_Receive_IT(hsensor->huart, hsensor->rx_buf, 8); } // 处理接收数据(内部使用) static void SensorUart_ProcessData(SensorUartHandleTypeDef *hsensor) { if (hsensor->rx_count != 8) { hsensor->error_count++; hsensor->data.valid = 0; return; } // 校验CRC和功能码 if (CRC16_CheckRx(hsensor->rx_buf, 8) && hsensor->rx_buf[2] == hsensor->func_code) { hsensor->data.reg_11 = (hsensor->rx_buf[4] << 8) | hsensor->rx_buf[5]; hsensor->data.updated = 1; hsensor->data.timestamp = HAL_GetTick(); hsensor->data.valid = 1; hsensor->error_count = 0; } else { hsensor->error_count++; hsensor->data.valid = 0; } // 错误计数上限 if (hsensor->error_count > 10) { hsensor->error_count = 10; } } // 传感器状态机处理(非阻塞) void SensorUart_Process(SensorUartHandleTypeDef *hsensor) { uint32_t current_time = HAL_GetTick(); uint32_t elapsed = (current_time >= hsensor->last_op_time) ? (current_time - hsensor->last_op_time) : (UINT32_MAX - hsensor->last_op_time + current_time + 1); switch (hsensor->state) { case SENSOR_STATE_IDLE: // 空闲状态:间隔发送请求(10ms更新一次) if (elapsed >= 10) { if (SensorUart_SendRequest(hsensor) == HAL_OK) { hsensor->state = SENSOR_STATE_WAIT_RESP; hsensor->last_op_time = current_time; } } break; case SENSOR_STATE_WAIT_RESP: // 等待响应:检查超时或接收完成 if (hsensor->rx_ok_flag) { hsensor->rx_ok_flag = 0; hsensor->state = SENSOR_STATE_PROCESS_DATA; } else if (elapsed >= hsensor->timeout) { hsensor->error_count++; hsensor->data.valid = 0; hsensor->state = SENSOR_STATE_IDLE; } break; case SENSOR_STATE_PROCESS_DATA: // 处理数据:校验并更新缓存 SensorUart_ProcessData(hsensor); hsensor->state = SENSOR_STATE_IDLE; hsensor->last_op_time = current_time; break; default: hsensor->state = SENSOR_STATE_IDLE; break; } } // 获取传感器数据 SensorDataCacheTypeDef SensorUart_GetData(SensorUartHandleTypeDef *hsensor) { SensorDataCacheTypeDef data = hsensor->data; hsensor->data.updated = 0; // 重置更新标志 return data; } // UART接收完成回调 void SensorUart_RxCpltCallback(SensorUartHandleTypeDef *hsensor) { hsensor->rx_count = 8; hsensor->rx_ok_flag = 1; } #ifndef SOFT_I2C_H #define SOFT_I2C_H #include "stm32g0xx_hal.h" #include "adc_process.h" #include "sensor_uart.h" // 配置参数 #define SW_I2C_SLAVE_ADDR 0x48 #define SW_I2C_SCL_PIN GPIO_PIN_6 #define SW_I2C_SDA_PIN GPIO_PIN_7 #define SW_I2C_SCL_PRT GPIOB #define SW_I2C_SDA_PRT GPIOB #define SW_I2C_TIMEOUT_MS 500 #define SW_I2C_BUF_SIZE 256 #define SW_I2C_HOST_FRAME_LEN 5 #define SW_I2C_SLAVE_FRAME_LEN 12 #define SW_I2C_FRAME_HEADER1 0x01 #define SW_I2C_FRAME_HEADER2 0xAA // I2C状态枚举 typedef enum { I2C_STATE_IDLE = 0, I2C_STATE_START, I2C_STATE_DATA, I2C_STATE_ACK, I2C_STATE_NACK, I2C_STATE_STOP } I2cStateTypeDef; // I2C读写标志 typedef enum { I2C_WRITE = 0, I2C_READ } I2cRwTypeDef; // 环形缓冲区结构体 typedef struct { uint8_t data[SW_I2C_BUF_SIZE]; uint16_t head; uint16_t tail; uint16_t count; } I2cRingBufferTypeDef; // I2C从机处理结构体(封装所有I2C相关数据) typedef struct { I2cStateTypeDef state; // I2C状态 I2cRwTypeDef rw; // 读写标志 uint8_t scl_fall_cnt; // SCL下降沿计数 uint8_t addr_match_flag; // 地址匹配标志 uint32_t start_ms; // 通信起始时间 uint8_t rx_buf[SW_I2C_BUF_SIZE];// 接收缓冲区 uint8_t tx_buf[SW_I2C_BUF_SIZE];// 发送缓冲区 uint8_t rx_idx; // 接收索引 uint8_t tx_idx; // 发送索引 uint8_t host_func_code; // 主机功能码 uint8_t frame_received; // 帧接收完成标志 uint8_t ignore_data; // 忽略数据标志 I2cRingBufferTypeDef rx_debug_buf; // 接收调试缓冲区 I2cRingBufferTypeDef tx_debug_buf; // 发送调试缓冲区 uint8_t last_tx_frame[SW_I2C_SLAVE_FRAME_LEN]; // 上次发送帧缓存 volatile uint8_t frame_updated; // 帧更新标志 // 外部模块句柄(通过初始化传入) ADC_ProcessHandleTypeDef *hadc_proc; SensorUartHandleTypeDef *hsensors[SENSOR_ID_MAX]; } SwI2cSlaveHandleTypeDef; // 初始化I2C从机 HAL_StatusTypeDef SwI2cSlave_Init(SwI2cSlaveHandleTypeDef *hi2c, ADC_ProcessHandleTypeDef *hadc_proc, SensorUartHandleTypeDef *hsensors[SENSOR_ID_MAX]); // I2C超时检查(主循环调用) void SwI2cSlave_CheckTimeout(SwI2cSlaveHandleTypeDef *hi2c); // I2C中断处理(EXTI4_15_IRQHandler中调用) void SwI2cSlave_IRQHandler(SwI2cSlaveHandleTypeDef *hi2c); // 读取调试缓冲区(对外接口) int SwI2cSlave_ReadDebugRx(SwI2cSlaveHandleTypeDef *hi2c, uint8_t *byte); int SwI2cSlave_ReadDebugTx(SwI2cSlaveHandleTypeDef *hi2c, uint8_t *byte); #endif // SOFT_I2C_SLAVE_H #include "soft_i2c.h" #include <string.h> // 环形缓冲区初始化(内部使用) static void I2cRingBuffer_Init(I2cRingBufferTypeDef *buf) { buf->head = 0; buf->tail = 0; buf->count = 0; } // 环形缓冲区写入(内部使用) static void I2cRingBuffer_Write(I2cRingBufferTypeDef *buf, uint8_t byte) { uint32_t primask = __get_PRIMASK(); __disable_irq(); if (buf->count < SW_I2C_BUF_SIZE) { buf->data[buf->head] = byte; buf->head = (buf->head + 1) % SW_I2C_BUF_SIZE; buf->count++; } else { // 缓冲区满,覆盖最旧数据 buf->data[buf->head] = byte; buf->head = (buf->head + 1) % SW_I2C_BUF_SIZE; buf->tail = (buf->tail + 1) % SW_I2C_BUF_SIZE; } __set_PRIMASK(primask); } // 环形缓冲区读取(内部使用) static int I2cRingBuffer_Read(I2cRingBufferTypeDef *buf, uint8_t *byte) { if (buf->count == 0) { return -1; } *byte = buf->data[buf->tail]; buf->tail = (buf->tail + 1) % SW_I2C_BUF_SIZE; buf->count--; return 0; } // 配置SDA为输入中断模式(内部使用) static void SwI2cSlave_SetSdaIt(SwI2cSlaveHandleTypeDef *hi2c) { GPIO_InitTypeDef gpio = {0}; gpio.Pin = SW_I2C_SDA_PIN; gpio.Mode = GPIO_MODE_IT_RISING_FALLING; gpio.Pull = GPIO_PULLUP; gpio.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SW_I2C_SDA_PRT, &gpio); } // 配置SDA为开漏输出(内部使用) static void SwI2cSlave_SetSdaOut(SwI2cSlaveHandleTypeDef *hi2c) { GPIO_InitTypeDef gpio = {0}; gpio.Pin = SW_I2C_SDA_PIN; gpio.Mode = GPIO_MODE_OUTPUT_OD; gpio.Pull = GPIO_PULLUP; gpio.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SW_I2C_SDA_PRT, &gpio); } // 异或校验(内部使用) static uint8_t SwI2cSlave_CalcXorChecksum(uint8_t *buf, uint8_t len) { uint8_t checksum = 0; for (uint8_t i = 0; i < len; i++) { checksum ^= buf[i]; } return checksum; } // 解析主机帧(内部使用) static uint8_t SwI2cSlave_ParseHostFrame(SwI2cSlaveHandleTypeDef *hi2c) { if (hi2c->rx_idx != SW_I2C_HOST_FRAME_LEN) return 0; if (hi2c->rx_buf[1] != SW_I2C_FRAME_HEADER1 || hi2c->rx_buf[2] != SW_I2C_FRAME_HEADER2) return 0; uint8_t crc = SwI2cSlave_CalcXorChecksum(&hi2c->rx_buf[1], 3); if (crc != hi2c->rx_buf[4]) return 0; hi2c->host_func_code = hi2c->rx_buf[3]; return 1; } // 准备发送帧(内部使用) static void SwI2cSlave_PrepareTxFrame(SwI2cSlaveHandleTypeDef *hi2c) { uint32_t primask = __get_PRIMASK(); __disable_irq(); // 填充帧头 hi2c->tx_buf[0] = SW_I2C_FRAME_HEADER1; hi2c->tx_buf[1] = SW_I2C_FRAME_HEADER2; hi2c->tx_buf[2] = hi2c->host_func_code; // 清空数据区 memset(&hi2c->tx_buf[3], 0, 8); // 根据功能码填充数据 switch (hi2c->host_func_code) { case 0x01: // ADC数据(使用修正后的ADC通道枚举) hi2c->tx_buf[3] = (AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_4) >> 8) & 0xFF; hi2c->tx_buf[4] = AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_4) & 0xFF; hi2c->tx_buf[5] = (AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_5) >> 8) & 0xFF; hi2c->tx_buf[6] = AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_5) & 0xFF; hi2c->tx_buf[7] = (AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_6) >> 8) & 0xFF; hi2c->tx_buf[8] = AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_6) & 0xFF; hi2c->tx_buf[9] = (AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_7) >> 8) & 0xFF; hi2c->tx_buf[10] = AdcProcess_GetAverage(hi2c->hadc_proc, ADC_PROC_CHANNEL_7) & 0xFF; break; case 0x02: { // 传感器数据 SensorDataCacheTypeDef sensor2 = SensorUart_GetData(hi2c->hsensors[SENSOR_ID_2]); SensorDataCacheTypeDef sensor3 = SensorUart_GetData(hi2c->hsensors[SENSOR_ID_3]); SensorDataCacheTypeDef sensor4 = SensorUart_GetData(hi2c->hsensors[SENSOR_ID_4]); hi2c->tx_buf[3] = sensor2.valid ? (sensor2.reg_11 >> 8) : 0xFF; hi2c->tx_buf[4] = sensor2.valid ? (sensor2.reg_11 & 0xFF) : 0xFF; hi2c->tx_buf[5] = sensor3.valid ? (sensor3.reg_11 >> 8) : 0xFF; hi2c->tx_buf[6] = sensor3.valid ? (sensor3.reg_11 & 0xFF) : 0xFF; hi2c->tx_buf[7] = sensor4.valid ? (sensor4.reg_11 >> 8) : 0xFF; hi2c->tx_buf[8] = sensor4.valid ? (sensor4.reg_11 & 0xFF) : 0xFF; } break; default: hi2c->tx_buf[2] = 0xFF; // 错误标识 break; } // 计算校验和 hi2c->tx_buf[11] = SwI2cSlave_CalcXorChecksum(hi2c->tx_buf, 11); // 保存上次发送帧 memcpy(hi2c->last_tx_frame, hi2c->tx_buf, SW_I2C_SLAVE_FRAME_LEN); hi2c->frame_updated = 1; __set_PRIMASK(primask); } // 初始化I2C从机 HAL_StatusTypeDef SwI2cSlave_Init(SwI2cSlaveHandleTypeDef *hi2c, ADC_ProcessHandleTypeDef *hadc_proc, SensorUartHandleTypeDef *hsensors[SENSOR_ID_MAX]) { if (hi2c == NULL || hadc_proc == NULL || hsensors == NULL) { return HAL_ERROR; } // 保存外部模块句柄 hi2c->hadc_proc = hadc_proc; for (uint8_t i = 0; i < SENSOR_ID_MAX; i++) { hi2c->hsensors[i] = hsensors[i]; } // 初始化状态和缓冲区 hi2c->state = I2C_STATE_IDLE; hi2c->rw = I2C_WRITE; hi2c->scl_fall_cnt = 0; hi2c->addr_match_flag = 0; hi2c->start_ms = 0; hi2c->rx_idx = 0; hi2c->tx_idx = 0; hi2c->host_func_code = 0x00; hi2c->frame_received = 0; hi2c->ignore_data = 0; hi2c->frame_updated = 0; memset(hi2c->rx_buf, 0, sizeof(hi2c->rx_buf)); memset(hi2c->tx_buf, 0, sizeof(hi2c->tx_buf)); memset(hi2c->last_tx_frame, 0, sizeof(hi2c->last_tx_frame)); I2cRingBuffer_Init(&hi2c->rx_debug_buf); I2cRingBuffer_Init(&hi2c->tx_debug_buf); // 初始化GPIO GPIO_InitTypeDef gpio = {0}; __HAL_RCC_GPIOB_CLK_ENABLE(); // SCL引脚:输入中断(上升/下降沿) gpio.Pin = SW_I2C_SCL_PIN; gpio.Mode = GPIO_MODE_IT_RISING_FALLING; gpio.Pull = GPIO_PULLUP; gpio.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(SW_I2C_SCL_PRT, &gpio); // SDA引脚:初始为输入中断 SwI2cSlave_SetSdaIt(hi2c); // 配置中断 HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI4_15_IRQn); // 准备默认发送帧 SwI2cSlave_PrepareTxFrame(hi2c); return HAL_OK; } // 超时检查 void SwI2cSlave_CheckTimeout(SwI2cSlaveHandleTypeDef *hi2c) { if (hi2c->state == I2C_STATE_IDLE) return; uint32_t current_ms = HAL_GetTick(); uint32_t elapsed = (current_ms >= hi2c->start_ms) ? (current_ms - hi2c->start_ms) : (UINT32_MAX - hi2c->start_ms + current_ms + 1); if (elapsed >= SW_I2C_TIMEOUT_MS) { // 超时重置 hi2c->state = I2C_STATE_IDLE; hi2c->rx_idx = 0; hi2c->tx_idx = 0; hi2c->frame_received = 0; hi2c->host_func_code = 0x00; hi2c->ignore_data = 0; HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(SW_I2C_SCL_PRT, SW_I2C_SCL_PIN, GPIO_PIN_SET); SwI2cSlave_SetSdaIt(hi2c); } } // 中断处理函数 void SwI2cSlave_IRQHandler(SwI2cSlaveHandleTypeDef *hi2c) { // 清除中断标志 if (__HAL_GPIO_EXTI_GET_IT(SW_I2C_SCL_PIN)) { __HAL_GPIO_EXTI_CLEAR_IT(SW_I2C_SCL_PIN); } if (__HAL_GPIO_EXTI_GET_IT(SW_I2C_SDA_PIN)) { __HAL_GPIO_EXTI_CLEAR_IT(SW_I2C_SDA_PIN); } hi2c->start_ms = HAL_GetTick(); uint8_t scl_level = HAL_GPIO_ReadPin(SW_I2C_SCL_PRT, SW_I2C_SCL_PIN); uint8_t sda_level = HAL_GPIO_ReadPin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN); // 处理SDA中断(起始/停止条件) if (__HAL_GPIO_EXTI_GET_IT(SW_I2C_SDA_PIN)) { if (sda_level == GPIO_PIN_RESET && scl_level == GPIO_PIN_SET) { // 起始条件 hi2c->state = I2C_STATE_START; hi2c->rx_idx = 0; hi2c->tx_idx = 0; hi2c->ignore_data = 0; SwI2cSlave_SetSdaIt(hi2c); } else if (sda_level == GPIO_PIN_SET && scl_level == GPIO_PIN_SET) { // 停止条件 hi2c->state = I2C_STATE_IDLE; hi2c->rx_idx = 0; hi2c->tx_idx = 0; hi2c->ignore_data = 0; SwI2cSlave_SetSdaIt(hi2c); } } // 处理SCL中断(数据传输) if (__HAL_GPIO_EXTI_GET_IT(SW_I2C_SCL_PIN)) { if (scl_level == GPIO_PIN_RESET) { // SCL下降沿 switch (hi2c->state) { case I2C_STATE_START: hi2c->scl_fall_cnt = 0; hi2c->rx_buf[hi2c->rx_idx] = 0; hi2c->state = I2C_STATE_DATA; SwI2cSlave_SetSdaIt(hi2c); break; case I2C_STATE_DATA: hi2c->scl_fall_cnt++; if (hi2c->rw == I2C_READ) { // 发送数据 SwI2cSlave_SetSdaOut(hi2c); if (hi2c->tx_idx < SW_I2C_SLAVE_FRAME_LEN) { uint8_t bit = (hi2c->tx_buf[hi2c->tx_idx] >> (7 - hi2c->scl_fall_cnt)) & 0x01; HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, bit ? GPIO_PIN_SET : GPIO_PIN_RESET); } else { HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_SET); } } else { SwI2cSlave_SetSdaIt(hi2c); } // 8位数据传输完成,准备ACK if (hi2c->scl_fall_cnt == 8) { if (hi2c->rw == I2C_WRITE) { // 地址匹配检查 if (hi2c->rx_idx == 0) { if ((hi2c->rx_buf[0] & 0xFE) == (SW_I2C_SLAVE_ADDR << 1)) { hi2c->addr_match_flag = 1; hi2c->rw = (I2cRwTypeDef)(hi2c->rx_buf[0] & 0x01); if (hi2c->rw == I2C_READ) { SwI2cSlave_PrepareTxFrame(hi2c); } } } // 发送ACK/NACK SwI2cSlave_SetSdaOut(hi2c); if (hi2c->addr_match_flag) { HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_RESET); } else { HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_SET); } } else { SwI2cSlave_SetSdaIt(hi2c); } // 调试日志 if (hi2c->rw == I2C_WRITE && hi2c->addr_match_flag) { I2cRingBuffer_Write(&hi2c->rx_debug_buf, hi2c->rx_buf[hi2c->rx_idx]); } if (hi2c->rw == I2C_READ) { I2cRingBuffer_Write(&hi2c->tx_debug_buf, hi2c->tx_buf[hi2c->tx_idx]); } hi2c->state = I2C_STATE_ACK; } break; case I2C_STATE_ACK: if (hi2c->rw == I2C_WRITE) { SwI2cSlave_SetSdaIt(hi2c); HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_SET); // 更新接收索引 if (!hi2c->ignore_data) { hi2c->rx_idx++; if (hi2c->rx_idx >= SW_I2C_HOST_FRAME_LEN) { hi2c->ignore_data = 1; if (SwI2cSlave_ParseHostFrame(hi2c)) { hi2c->frame_received = 1; SwI2cSlave_PrepareTxFrame(hi2c); } hi2c->rx_idx = 0; } } if (!hi2c->ignore_data && hi2c->rx_idx < SW_I2C_BUF_SIZE) { hi2c->rx_buf[hi2c->rx_idx] = 0; } hi2c->scl_fall_cnt = 0; hi2c->state = I2C_STATE_DATA; } else { if (hi2c->state == I2C_STATE_NACK) { HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_SET); hi2c->state = I2C_STATE_IDLE; SwI2cSlave_SetSdaIt(hi2c); } else if (hi2c->tx_idx < SW_I2C_SLAVE_FRAME_LEN - 1) { hi2c->tx_idx++; hi2c->scl_fall_cnt = 0; hi2c->state = I2C_STATE_DATA; } } break; case I2C_STATE_NACK: hi2c->scl_fall_cnt = 0; HAL_GPIO_WritePin(SW_I2C_SDA_PRT, SW_I2C_SDA_PIN, GPIO_PIN_SET); SwI2cSlave_SetSdaIt(hi2c); hi2c->state = I2C_STATE_IDLE; break; default: hi2c->state = I2C_STATE_IDLE; break; } } else { // SCL上升沿 if (hi2c->state == I2C_STATE_DATA && hi2c->rw == I2C_WRITE && !hi2c->ignore_data) { // 读取数据位 if (sda_level == GPIO_PIN_SET) { hi2c->rx_buf[hi2c->rx_idx] |= (1 << (7 - hi2c->scl_fall_cnt)); } } else if (hi2c->state == I2C_STATE_ACK && hi2c->rw == I2C_READ) { // 检测主机ACK/NACK if (sda_level == GPIO_PIN_SET) { hi2c->state = I2C_STATE_NACK; SwI2cSlave_SetSdaIt(hi2c); } else if (hi2c->tx_idx >= SW_I2C_SLAVE_FRAME_LEN - 1) { hi2c->state = I2C_STATE_NACK; SwI2cSlave_SetSdaIt(hi2c); } } } } } // 读取调试接收缓冲区 int SwI2cSlave_ReadDebugRx(SwI2cSlaveHandleTypeDef *hi2c, uint8_t *byte) { return I2cRingBuffer_Read(&hi2c->rx_debug_buf, byte); } // 读取调试发送缓冲区 int SwI2cSlave_ReadDebugTx(SwI2cSlaveHandleTypeDef *hi2c, uint8_t *byte) { return I2cRingBuffer_Read(&hi2c->tx_debug_buf, byte); } /* 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" #include "adc.h" #include "dma.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "delay.h" #include "soft_i2c.h" #include "stm32g0xx_hal.h" #include <string.h> #include <stdio.h> #include "stm32g0xx_it.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ //typedef uint32_t u32; //typedef uint16_t u16; //typedef uint8_t u8; //typedef const uint8_t uc8; // //#ifndef __cplusplus //typedef enum {FALSE = 0, TRUE = !FALSE} bool; //#endif // 模块句柄实例(全局,仅主函数和中断使用) static ADC_ProcessHandleTypeDef hadc_proc; static SensorUartHandleTypeDef hsensor2, hsensor3, hsensor4; static SensorUartHandleTypeDef *hsensors[SENSOR_ID_MAX] = {&hsensor2, &hsensor3, &hsensor4}; static SwI2cSlaveHandleTypeDef hi2c_slave; /* 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 */ // 重定向printf到USART1(调试用) int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); return ch; } int __io_putchar(int ch) { HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY); return ch; } // 定时器3中断回调(ADC数据更新) void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim3) { AdcProcess_HandleDMAData(&hadc_proc); } } // UART接收完成回调(传感器) void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart2) { SensorUart_RxCpltCallback(&hsensor2); } else if (huart == &huart3) { SensorUart_RxCpltCallback(&hsensor3); } else if (huart == &huart4) { SensorUart_RxCpltCallback(&hsensor4); } } /* 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(); MX_DMA_Init(); MX_ADC1_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_USART3_UART_Init(); MX_USART4_UART_Init(); MX_TIM3_Init(); MX_TIM2_Init(); /* USER CODE BEGIN 2 */ // 初始化各模块 AdcProcess_Init(&hadc_proc, &hadc1, &hdma_adc1, &htim3); SensorUart_Init(&hsensor2, SENSOR_ID_2, &huart2, 0x01, 0x03, 0x0B, 500); // 寄存器11=0x0B SensorUart_Init(&hsensor3, SENSOR_ID_3, &huart3, 0x01, 0x03, 0x0B, 500); SensorUart_Init(&hsensor4, SENSOR_ID_4, &huart4, 0x01, 0x03, 0x0B, 500); SwI2cSlave_Init(&hi2c_slave, &hadc_proc, hsensors); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { // 处理3个传感器的状态机(并行非阻塞) SensorUart_Process(&hsensor2); SensorUart_Process(&hsensor3); SensorUart_Process(&hsensor4); // 处理I2C超时 SwI2cSlave_CheckTimeout(&hi2c_slave); // 调试日志打印(可选,注释可关闭) uint8_t byte; while (SwI2cSlave_ReadDebugRx(&hi2c_slave, &byte) == 0) { printf("I2C RX: 0x%02X\r\n", byte); } while (SwI2cSlave_ReadDebugTx(&hi2c_slave, &byte) == 0) { printf("I2C TX: 0x%02X\r\n", byte); } if (hi2c_slave.frame_updated) { hi2c_slave.frame_updated = 0; printf("I2C Prepared TX Frame: "); for (uint8_t i = 0; i < SW_I2C_SLAVE_FRAME_LEN; i++) { printf("%02X ", hi2c_slave.last_tx_frame[i]); } printf("\r\n"); } HAL_Delay(10); /* USER CODE END WHILE */ /* 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}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); /** 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.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; RCC_OscInitStruct.PLL.PLLN = 8; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; 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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* 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 */ 检查代码逻辑以及复杂度
最新发布
11-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值