prt_cnt.c

  name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-5572165936844014&dt=1194442938015&lmt=1194190197&format=336x280_as&output=html&correlator=1194442937843&url=file%3A%2F%2F%2FC%3A%2FDocuments%2520and%2520Settings%2Flhh1%2F%E6%A1%8C%E9%9D%A2%2FCLanguage.htm&color_bg=FFFFFF&color_text=000000&color_link=000000&color_url=FFFFFF&color_border=FFFFFF&ad_type=text&ga_vid=583001034.1194442938&ga_sid=1194442938&ga_hid=1942779085&flash=9&u_h=768&u_w=1024&u_ah=740&u_aw=1024&u_cd=32&u_tz=480&u_java=true" frameborder="0" width="336" scrolling="no" height="280" allowtransparency="allowtransparency"> #include <stdio.h>

void main(void)
 {
   int first_count;
   int second_count;

   printf("Jamsa%n/'s C/C++ Programmer/'s Bible%n/n", &first_count, &second_count);
   printf("First count %d Second count %d/n", first_count, second_count);
 }

 

unsigned char last_sitf_mode_flag; MT_KEY_PARAM keyParam; HI_S32 ret = -1; if(rtd2121_sitf_mode == 1) { if(sitf_cfg_flag == 0) { last_sitf_mode_flag = sitf_mode_flag; if(video_Frame_cnt % 50 == 1) { if(dtemp_sensor_val < 640) { printf("111 set_sitf_cfg_mode -20-20 %d \n", dtemp_sensor_val); sitf_mode_flag = 1; } else if(dtemp_sensor_val > 960 && dtemp_sensor_val < 1920) { printf("222 set_sitf_cfg_mode 30-60 %d \n", dtemp_sensor_val); sitf_mode_flag = 2; } else { printf("333 set_sitf_cfg_mode %d \n", dtemp_sensor_val); sitf_mode_flag = 2; } } if (sitf_mode_flag != last_sitf_mode_flag) { g_add_shut_count = 1; last_sitf_mode_flag = sitf_mode_flag; // 更新上一次的值 sensor_sitf_mode_cfg(rtd2121_sitf_mode, lens_type, 0, sitf_mode_flag); keyParam.index = MT_IDX_SENS_LEVEL; keyParam.pValue = &(sitf_mode_flag - 1); printf("11111111111111 keyParam.index = %d, sens_leval = %d, keyParam.pValue = %p\n", keyParam.index, sens_leval, keyParam.pValue); ret = MT_SetConfig(g_SctmParam.handle, MT_SET_CFG_SINGLE_PARAM, &keyParam, sizeof(keyParam)); if (ret != SC_RET_OK) { MT_PRT_ERROR(g_SctmParam.printParam.mainLevel, "\033[1;31m"" MT_SetConfig:MT_IDX_SENS_LEVEL failed! ret = %#x\n""\033[0;39m", ret); } }// 标志位改变 } if(last_sitf_cfg_flag != sitf_cfg_flag) { printf("111 set_sitf_cfg_mode -20-20 %d ,last_sitf_cfg_flag = %d\n", sitf_cfg_flag, last_sitf_cfg_flag); if(sitf_cfg_flag == 1) { g_add_shut_count = 1; printf("444 set_sitf_cfg_mode -20-20 %d \n", dtemp_sensor_val); sensor_sitf_mode_cfg(rtd2121_sitf_mode, lens_type, 0, sitf_cfg_flag); } else if(sitf_cfg_flag == 2) { g_add_shut_count = 1; printf("555 set_sitf_cfg_mode 30-60 %d \n", dtemp_sensor_val); sensor_sitf_mode_cfg(rtd2121_sitf_mode, lens_type, 0, sitf_cfg_flag); } printf("11111111111111111111111111\n"); keyParam.index = MT_IDX_SENS_LEVEL; if(sitf_cfg_flag == 1 && sitf_cfg_flag == 2) { int sens_leval = keyParam.pValue = &sens_leval; printf("22222222222222 keyParam.index = %d, sens_leval = %d, keyParam.pValue = %p\n", keyParam.index, sens_leval, keyParam.pValue); ret = MT_SetConfig(g_SctmParam.handle, MT_SET_CFG_SINGLE_PARAM, &keyParam, sizeof(keyParam)); if (ret != SC_RET_OK) { MT_PRT_ERROR(g_SctmParam.printParam.mainLevel, "\033[1;31m"" MT_SetConfig:MT_IDX_SENS_LEVEL failed! ret = %#x\n""\033[0;39m", ret); } printf("3333333333333333333333\n"); last_sitf_cfg_flag = sitf_cfg_flag; printf("222 set_sitf_cfg_mode -20-20 %d ,last_sitf_cfg_flag = %d\n", sitf_cfg_flag, last_sitf_cfg_flag); } } }
08-13
#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
int thml_mt_calc_process(HI_U8 *pSrcImg, SCTM_PARAM *pSctmParam, HI_U32 chan, HI_U8 *mtCalibBuf, HI_U32 mtParamSize, int *mtAlarmStatus, int *mtPreAlarmStatus) { SC_RET err; int i, bAlarmStatusChanged = 0; char arg[7] = {0}; pSctmInitParam = &g_sctmInitParam; pSctmParam->rawImage.imageAddr = pSrcImg; err = SetRawTmParam(pSctmParam); //配置最后两行参数 if (err != SC_RET_OK) { printf("\033[1;31m"" SetRawTmParam failed! err = %#x\n""\033[0;39m",err); return err; } if (bRunTMAlg(chan)) //判断是否需要测温 { //SemDbg_pend(&semOnTMProcess, 0, SYS_FOREVER); //pC674Status->debug[3]++; //WaitForSingleObject(g_hSemOnTMProcess, INFINITE);//等待信号量>0 //sem_wait(&semOnTMProcess); if (HI_TRUE != pSctmParam->rawCtrlInfo.bFreezeTM) //判断是否冻结帧 { //计算温度灰度查找表 err = MT_SubFunction(pSctmParam->handle, MT_FUNC_TYPE_GET_TEMPTABLE, pSrcImg, 0, &pSctmParam->mtTempTableOutput, sizeof(MT_TEMPTABLE_OUTPUT), 0); if (err != SC_RET_OK) { printf("\033[1;31m"" MT_SubFunction GET_TEMPTABLE failed! err = 0x%#x\n""\033[0;39m", err); return err; } // usleep(10*1000); //全屏温度计算(暂时先放在同一个线程里面) //if (pSctmInitParam->sctmCtrlParam.bFSTempFlag == 1) #if defined(YTWS_VERSION) if ((pSctmInitParam->sctmCtrlParam.bFSTempFlag == 1) && (mt_Frame_cnt % 2 == 1)) #elif defined(ZYR_VERSION) if (pSctmInitParam->sctmCtrlParam.bFSTempFlag == 1) #elif defined(CZHC_VERSION) if (pSctmInitParam->sctmCtrlParam.bFSTempFlag == 1) #else if ((pSctmInitParam->sctmCtrlParam.bFSTempFlag == 1) && (mt_Frame_cnt % 5 == 4)) #endif { MT_FSTMAP_INPUT mtFSTempInput; mtFSTempInput.pRawData = pSrcImg; mtFSTempInput.pTempTable = pSctmParam->mtTempTableOutput.pTempTable; bSyncFST = 0; semTake(fstMSem, -1); err = MT_SubFunction(pSctmParam->handle, MT_FUNC_TYPE_MAP_FSTEMP, &mtFSTempInput, sizeof(MT_FSTMAP_INPUT), pSctmParam->pFSTempImage, 0, 0); if (err != SC_RET_OK) { printf("\033[1;31m"" MT_SubFunction MAP_FSTEMP failed! err = 0x%#x\n""\033[0;39m", err); semGive(fstMSem); return err; } semGive(fstMSem); } #if defined(ZYR_VERSION) #elif defined(CZHC_VERSION) #else #ifndef YTWS_VERSION if (mt_Frame_cnt % 5 == 0) //每隔5帧计算一次 #else if (mt_Frame_cnt % 2 == 0) #endif { HI_U16 *ptr = (HI_U16 *)pSrcImg; // 温度测量和报警判断 if ((pSctmInitParam->sctmCtrlParam.mtMode == MT_MODE_RULE) || (pSctmInitParam->sctmCtrlParam.mtMode == MT_MODE_COMM) || (pSctmInitParam->sctmCtrlParam.mtMode == MT_MODE_MAN)) { //if(pSctmInitParam->sctmCtrlParam.mtMode == MT_MODE_MAN) // pSctmParam->pMTRuleParam->ruleRgionList.presetId = 0xff; semTake(fstMSem, -1); /* printf("fffffffff %.2f %.2f %.2f %.2f %.2f %.2f\n", pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].emissionRate, pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].distance, pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[2].emissionRate, pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[2].distance, pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[3].emissionRate, pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[3].distance ); */ err = MTRule_TmpProcess(pSctmParam->pMTRuleParam, pSrcImg, pSctmParam->handle, &pSctmParam->mtTempTableOutput); if (err != SC_RET_OK) { printf("\033[1;31m" "ERR = 0x%#x, MTRule_TmpProcess error!\n" "\033[0;39m", err); semGive(fstMSem); return err; } semGive(fstMSem); #ifdef HTTP_NEWADD memcpy(http_tempData, pSctmParam->pFSTempImage, 256*192*2*2); #endif bSyncFST = 1; #ifdef TESTMT_MT_DBG_VERSION printf("\033[1;31m" "processCnt = %d, MTRule_TmpProcess OK!\n" "\033[0;39m", video_Frame_cnt); printf("=====mt-ret====%f %f %f==%f %f %f==%f %f %f==\n", pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[0].outputInfo.outputTemp[0], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[0].outputInfo.outputTemp[1], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[0].outputInfo.outputTemp[2], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].outputInfo.outputTemp[0], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].outputInfo.outputTemp[1], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].outputInfo.outputTemp[2], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[2].outputInfo.outputTemp[0], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[2].outputInfo.outputTemp[1], pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[2].outputInfo.outputTemp[2]); #endif #ifdef SUPPORT_PTZ #ifdef DEV_BUG_REPAIR if(!mtBindPreFlag) #endif #endif { copy_mt_rule_list(); } // usleep(20*1000); } else if (pSctmInitParam->sctmCtrlParam.mtMode == MT_MODE_AUTO) { //printf("\033[1;31m" "HAS_Process mode!\n" "\033[0;39m"); err = HAS_Process(pSctmParam->pMTHasParam, pSrcImg, pSctmParam->handle, &pSctmParam->mtTempTableOutput); if (err != SC_RET_OK) { printf("\033[1;31m" "ERR = 0x%#x, HAS_Process error!\n" "\033[0;39m", err); return err; } #if 0 int i = 0; for(i = 0; i < pSctmParam->pMTHasParam->regionList.regionNum; i++) { MT_PRT_INFO(pSctmParam->printParam.mainLevel,"rect.x0 = %d, y0 = %d, x1 = %d y1 = %d, temp = %.2f\n", pSctmParam->pMTHasParam->regionList.regionInfo[0].rect.x1, pSctmParam->pMTHasParam->regionList.regionInfo[0].rect.y1, pSctmParam->pMTHasParam->regionList.regionInfo[0].rect.x2, pSctmParam->pMTHasParam->regionList.regionInfo[0].rect.y2, pSctmParam->pMTHasParam->regionList.regionInfo[0].hotTemp); } #endif } else { printf( "\033[1;31m" "MT mode not supported!\n" "\033[0;39m"); return err; } #if 0 if(pSctmParam->pMTRuleParam->ruleRgionList.regionNum.pointNum>0) { int x = pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].polygon.pointList[0].s32X * 255 / 1000; int y = pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[1].polygon.pointList[0].s32Y * 191 / 1000; //printf("11111111111 x=%d y=%d\n", x, y); unsigned short temp = *(unsigned short *)(pSctmParam->pFSTempImage + ((y)*256 + x) * 2); //printf("3333333333333333 temp = %u\n", temp); temp = temp ^ ((y)*256 + x); //printf("4444444444 temp = %u\n", temp); short temp1 = (signed short)(((temp * 1.0f)/64 - 273.15) * 10); printf("22222222222 temp=%d\n", temp1); } #endif #if 1 // 报警、温度等数据上传与打包 //ifrOutcomeUpload(chan, pCtrl); #if 1 //#ifdef SZDW_7 //#ifdef SZDW_VERSION // int szdw_bRuleAlarm = 0; //#endif //#endif bNeedPreAlarm = bNeedAlarm = bNeedDiffPreAlarm = bNeedDiffAlarm = 0; if(pSctmInitParam->sctmCtrlParam.mtMode == MT_MODE_COMM) { MTRULE_ALARM_RULE_PARAM *pAlarmRuleParam = &(pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[0].alarmRuleParam); if(pAlarmRuleParam->alarmkey == 1) { if(pAlarmRuleParam->alarmLevel == MTRULE_ALARM_LEVEL_ALARM) { bNeedAlarm = 1; #ifdef SUPPORT_PELCO_D_EX mt_rule_alarm_id |= 1<<i; mt_rule_alarm_level |= 1<<i; #endif } else if(pAlarmRuleParam->alarmLevel == MTRULE_ALARM_LEVEL_PRE_ALARM) { bNeedPreAlarm = 1; #ifdef SUPPORT_PELCO_D_EX mt_rule_alarm_id |= 1<<i; mt_rule_alarm_level &= ~(1<<i); #endif } #ifdef SUPPORT_PELCO_D_EX else { mt_rule_alarm_id &= ~(1<<i); mt_rule_alarm_level &= ~(1<<i); } #endif } #ifdef SUPPORT_PELCO_D_EX else { mt_rule_alarm_id &= ~(1<<i); mt_rule_alarm_level &= ~(1<<i); } #endif } else { for(i=0; i<MTRULE_MAX_REGION_DIFF_NUM; i++) { MTRULE_DIFF_ALARM_INFO *pDiffAlarm = &(pSctmParam->pMTRuleParam->ruleRgionList.diffAlarmInfo[i]); if(pDiffAlarm->enable == 1) { //printf("aaaa33333\n"); if(pDiffAlarm->alarmLevel == MTRULE_ALARM_LEVEL_ALARM) { bNeedDiffAlarm = 1; #ifdef SUPPORT_PELCO_D_EX mt_rule_alarm_id |= 1<<i; mt_rule_alarm_level |= 1<<i; #endif } else if(pDiffAlarm->alarmLevel == MTRULE_ALARM_LEVEL_PRE_ALARM) { bNeedDiffPreAlarm = 1; #ifdef SUPPORT_PELCO_D_EX mt_rule_alarm_id |= 1<<i; mt_rule_alarm_level &= ~(1<<i); #endif } #ifdef SUPPORT_PELCO_D_EX else { mt_rule_alarm_id &= ~(1<<i); mt_rule_alarm_level &= ~(1<<i); } #endif } #ifdef SUPPORT_PELCO_D_EX else { mt_rule_alarm_id &= ~(1<<i); mt_rule_alarm_level &= ~(1<<i); } #endif } if(pSctmParam->pMTRuleParam->ruleRgionList.regionNum.total > 0) { i=1; } else { i=0; } int maxRuleNum = 25; if(!bStayOnPreset) { #ifdef QIAN_VERSION i = 1; maxRuleNum = 0; #else //i = 0; #endif } #ifdef SZDW_6 #ifdef SZDW_VERSION i=0; #endif #endif for(; i<=MIN2(pSctmParam->pMTRuleParam->ruleRgionList.regionNum.total, maxRuleNum); i++) { MTRULE_ALARM_RULE_PARAM *pAlarmRuleParam = &(pSctmParam->pMTRuleParam->ruleRgionList.regionInfo[i].alarmRuleParam); if(pAlarmRuleParam->alarmkey == 1) { if(pAlarmRuleParam->alarmLevel == MTRULE_ALARM_LEVEL_ALARM) { bNeedAlarm = 1; #ifdef SUPPORT_PELCO_D_EX mt_rule_alarm_id |= 1<<i; mt_rule_alarm_level |= 1<<i; #endif //#ifdef SZDW_7 //#ifdef SZDW_VERSION // if(i != 0) // { // szdw_bRuleAlarm = 2; // } //#endif //#endif } else if(pAlarmRuleParam->alarmLevel == MTRULE_ALARM_LEVEL_PRE_ALARM) { bNeedPreAlarm = 1; #ifdef SUPPORT_PELCO_D_EX mt_rule_alarm_id |= 1<<i; mt_rule_alarm_level &= ~(1<<i); #endif //#ifdef SZDW_7 //#ifdef SZDW_VERSION // if(i != 0) // { // szdw_bRuleAlarm = 1; // } //#endif //#endif } #ifdef SUPPORT_PELCO_D_EX else { mt_rule_alarm_id &= ~(1<<i); mt_rule_alarm_level &= ~(1<<i); } #endif } #ifdef SUPPORT_PELCO_D_EX else { mt_rule_alarm_id &= ~(1<<i); mt_rule_alarm_level &= ~(1<<i); } #endif } } #endif #ifdef SZDW_6 #ifdef SZDW_VERSION if(0) #else if(bNeedDiffPreAlarm || bNeedPreAlarm) #endif #else if(bNeedDiffPreAlarm || bNeedPreAlarm) #endif { arg[0] = 0; arg[1] += 1; #ifdef SUPPORT_PELCO_D_EX arg[2] = bNeedDiffPreAlarm << 1 | bNeedPreAlarm; #endif *mtPreAlarmStatus = 1; bAlarmStatusChanged = 1; } else if(*mtPreAlarmStatus) { arg[0] = 0; arg[1] += 0; *mtPreAlarmStatus = 0; bAlarmStatusChanged = 1; } if(bNeedDiffAlarm || bNeedAlarm) { arg[0] = 0; arg[1] += 2; #ifdef SUPPORT_PELCO_D_EX arg[2] = (bNeedDiffAlarm << 1 | bNeedAlarm); #endif //#ifdef SZDW_7 //#ifdef SZDW_VERSION // arg[3] = szdw_bRuleAlarm; //#endif //#endif *mtAlarmStatus = 1; bAlarmStatusChanged = 1; } else if(*mtAlarmStatus) { arg[0] = 0; arg[1] += 0; *mtAlarmStatus = 0; bAlarmStatusChanged = 1; } if(bAlarmStatusChanged) { char *pMtAlarmIn = getMtAlarmIn(); eventTriggerAlarmIn(pMtAlarmIn, MT_EXCEPTION, arg); } #ifdef SZDW_7 #ifdef SZDW_VERSION g_szdw_alarm_status = 0; if(bNeedAlarm) g_szdw_alarm_status = 2; else if(bNeedPreAlarm) g_szdw_alarm_status = 1; #endif #endif #endif } #endif } else //如果是冻结帧则不处理算法 { if (video_Frame_cnt % 5 == 0) { //printf("freezen! processCnt = %d\n",video_Frame_cnt); // 报警、温度等数据上传与打包 //ifrOutcomeUpload(chan, pCtrl); } } //ifrDebugInfoPrt(); #if 0 if (video_Frame_cnt % processInterval == 0) { printf("TMKey %d, ptz %d, isIfrRegionSet %d, bcross %d\n", pSctmInitParam->sctmCtrlParam.TMKey, 0,//pSctmInitParam->ptzPackInfo[chan].domePtzInfo.ptz_state, pSctmParam->isIfrRegionSet, pSctmInitParam->sctmCtrlParam.bcross); } //SemDbg_post(&semOnTMProcess, 0); //sem_post(&semOnTMProcess); #endif } else { if (video_Frame_cnt % processInterval == 0) { printf("\033[40;33m" "TM Alg does not run! TMKey %d, ptz %d, isIfrRegionSet %d, bfreezeTM %d\n" "\033[m", pSctmInitParam->sctmCtrlParam.TMKey, 0,//pSctmInitParam->ptzPackInfo[chan].domePtzInfo.ptz_state, pSctmParam->isIfrRegionSet, pSctmParam->rawCtrlInfo.bFreezeTM); //PRT("\033[40;33m" "pCtrl->rawImage.ImageWidth/Height/ImageAddr %d/%d/%p, rawImage.ImageWidth/Height/ImageAddr %d/%d/%p\n" "\033[m", // pSctmParam->rawImage.ImageWidth, pSctmParam->rawImage.ImageHeight, pSctmParam->rawImage.ImageAddr, g_rawImage.ImageWidth, g_rawImage.ImageHeight, g_rawImage.ImageAddr); } } return err; }
07-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值