问个globle的问题,如何定时更新论坛的数据啊?

本文介绍了一种使用.NET技术实现论坛数据定时更新的方法。通过在Application_Start事件中启动一个定时器,每分钟触发一次,执行特定任务,如更新论坛帖子的状态等。

问个globle的问题,如何定时更新论坛的数据啊?

楼主mychinabc(来碗牛肉面,不要牛肉不要面!)2006-12-09 22:46:35 在 .NET技术 / ASP.NET 提问

protected   void   Application_Start(Object   sender,   EventArgs   e)  
  {  
  System.Timers.Timer   aTimer   =   new   Timer(1000*60);  
  aTimer.Elapsed   +=   new   ElapsedEventHandler(aTimer_Elapsed);//调用的函数  
  aTimer.AutoReset   =   true;   //   '   AutoReset   属性为   true   时,每隔指定时间循环一次;     如果为   false,则只执行一次。  
  aTimer.Enabled   =   true;  
  }  
  private   void   aTimer_Elapsed(object   source,   ElapsedEventArgs   e)  
  {  
  string   strFileName   =   @"D:/abc.txt";  
  StreamWriter   sr   =   File.CreateText(strFileName);  
  sr.WriteLine(DateTime.Now.ToString());  
  sr.Close();  
  return;  
  //string   sql="update   bbs_board   set   today=0";  
  //Db.dataedit(sql);  
  }  

// 保存SWV数据到CSV文件(修复版本) void save_SWV_data_to_csv(lv_SWV_Param* params, int** current_data_all, uint16_t* data_counts, data_result* peak_data, uint8_t total_scans) { FRESULT res; FIL file; UINT bytes_written; char filename[50]; char date_str[10], time_str[10]; uint32_t number; char buffer[100]; // 获取当前日期和时间 get_current_datetime(date_str, time_str); // 获取下一个文件编号 number = get_next_file_number(); // 生成文件名 sprintf(filename, "%s_%s%s_%08lu.csv", s_Globle.ps_Parpam->sensor_type, date_str, time_str, number); // 创建并打开文件 res = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE); if (res != FR_OK) { printf("Failed to create file: %d\n", res); return; } // 写入参数头信息 f_printf(&file, "Scan Type,SWV\n"); f_printf(&file, "InitEval,%d\n", params->InitEval); f_printf(&file, "FinalEval,%d\n", params->FinalEval); f_printf(&file, "IncrEval,%d\n", params->IncrEval); f_printf(&file, "AmplitudeE,%d\n", params->AmplitudeE); f_printf(&file, "QuiteTime,%d\n", params->QuiteTime); f_printf(&file, "Frequency,%d\n", params->Frequency); f_printf(&file, "Range,%d\n", params->Range); f_printf(&file, "Number of Scans,%d\n", params->Number); f_printf(&file, "Analyse Potential,%d\n", params->analyse_potential); f_printf(&file, "Light Type,%d\n", params->light_type); f_printf(&file, "Light Power (mW),%d\n", params->light_mW); f_printf(&file, "Min Range,%d\n", params->minrange); f_printf(&file, "Max Range,%d\n", params->maxrange); f_printf(&file, "Date,=\"%s\"\n", date_str); f_printf(&file, "Time,=\"%s\"\n", time_str); f_printf(&file, "File Number,%08lu\n", number); f_printf(&file, "\n"); // 空行分隔参数和数据 // 写入峰值数据 f_printf(&file, "Peak Data\n"); f_printf(&file, "Scan,Voltage(mV),Current(uA)\n"); for (int i = 0; i < total_scans; i++) { f_printf(&file, "%d,%d,%d\n", i+1, peak_data[i].voltage, peak_data[i].current); } // 计算平均峰值 int avg_voltage = 0; int avg_current = 0; for (int i = 0; i < total_scans; i++) { avg_voltage += peak_data[i].voltage; avg_current += peak_data[i].current; } if (total_scans > 0) { avg_voltage /= total_scans; avg_current /= total_scans; } f_printf(&file, "Average,%d,%d\n", avg_voltage, avg_current); f_printf(&file, "\n"); // 空行分隔峰值数据和扫描数据 // 生成电压序列 int init = params->InitEval; int final = params->FinalEval; int incr = params->IncrEval; int dir = (init < final) ? 1 : -1; // 计算预期的数据点数 int expected_points = abs(final - init) / incr + 1; // 写入扫描数据表头 f_printf(&file, "Voltage(mV)"); for (int i = 0; i < total_scans; i++) { f_printf(&file, ",Scan%d(uA)", i+1); } f_printf(&file, "\n"); // 找出所有扫描中的最大数据点数 int max_data_points = 0; for (int i = 0; i < total_scans; i++) { if (data_counts[i] > max_data_points) { max_data_points = data_counts[i]; } } // 确保超过预期点数 if (max_data_points > expected_points) { max_data_points = expected_points; } // 写入扫描数据(按电压对齐) for (int i = 0; i < max_data_points; i++) { int voltage = init + incr * i * dir; f_printf(&file, "%d", voltage); for (int scan_idx = 0; scan_idx < total_scans; scan_idx++) { // 确保越界访 if (i < data_counts[scan_idx]) { f_printf(&file, ",%d", current_data_all[scan_idx][i]); } else { f_printf(&file, ","); // 数据足时留空 } } f_printf(&file, "\n"); } // 关闭文件 f_close(&file); printf("Data saved to %s\n", filename); } uint8_t CMD; uint8_t status; uint8_t Sensor; uint16_t Year; uint8_t Month; uint8_t Day; uint8_t Hour; uint8_t Minute; uint8_t Second; uint8_t battery; char* timeStr; uint8_t CurrentMode; float Res_val; uint16_t data_index; uint16_t swv_data_index; float* ITData=NULL; float* CVData=NULL; float* SWVData=NULL; float* diffData=NULL; int* current_data=NULL; int* voltage_data=NULL; uint16_t last_cont = 0; bool Dire = true; // 用于判断当前扫描方向 uint32_t DataCount = 0; // 总数据点计数(需初始化) uint32_t ScandataCount = 0; // 已完成扫描数据计数(需初始化) #define MAX_TOTAL_DATA_POINTS 200 // 所有扫描的总数据点最大数量 #define MAX_SCANS 3 // 最大扫描次数 data_result anodic_peak, cathodic_peak; // 保存所有电压和电流值 int voltage_data_all[MAX_TOTAL_DATA_POINTS]; int current_data_all[MAX_TOTAL_DATA_POINTS]; uint32_t total_data_count = 0; // 总数据点数 data_result anodic_peak_data[MAX_SCANS],cathodic_peak_data[MAX_SCANS]; // 每个扫描的峰值数据 // 在合适的位置定义二维数组 int *current_data_scans[MAX_SCANS]; // 存储每次扫描的电流数据 int voltage_sequence[200]; // 存储电压序列(所有扫描相同) // 在开始扫描前初始化最大最小值(仅第一次扫描) static bool first_scan = true; // 增加扫描计数 static uint8_t cv_scan_count = 1; // 在CV模式中添加静态数组来存储所有扫描的数据 static int* voltage_data_scans[MAX_SCANS] = {NULL}; static int* current_data_scans[MAX_SCANS] = {NULL}; // 增加扫描计数 static uint8_t scan_count = 1; // 在合适的地方定义数据点数数组 uint16_t data_counts[MAX_SCANS]; //命令处理函数 static uint8_t ExecuteCMD(s_Globle_Para *ps_Globle) { ps_Globle->u8_CMD = UART_ACK_FAULT_ALL; ps_Globle->u8_CMD_Data_LEN = UART_DATA_0_BYTE; switch (ps_Globle->u8_ACK) { case UART_ACK_Uart_DeviceOK://通信方式设置完成 if (ps_Globle->u8_ACK_Data_LEN == UART_DATA_20_BYTE) { printf("UARTOK\r\n"); HEARTBEAT_flag=1; } break; case UART_ACK_HEARTBEAT_OK: printf("UART_ACK_HEARTBEAT_OK\r\n"); // 假设mPackAfterUnpack是接收缓冲区,UART_BUF_DATA_SHIFT是数据起始偏移 // 解包基础信息 CMD = ps_Globle->u8_ACK_Data[0]; // 下位机当前命令(对应u8_ACK_Data[0]) status = ps_Globle->u8_ACK_Data[1]; // 下位机当前状态(对应u8_ACK_Data[1]) Sensor = ps_Globle->u8_ACK_Data[2]; // 传感器状态(对应u8_ACK_Data[2]) // 解包时间信息(年、月、日、时、分、秒) Year = (ps_Globle->u8_ACK_Data[3] << 8) | ps_Globle->u8_ACK_Data[4]; // 年(对应u8_ACK_Data[3-4]) Month = ps_Globle->u8_ACK_Data[5]; // 月(对应u8_ACK_Data[5]) Day = ps_Globle->u8_ACK_Data[6]; // 日(对应u8_ACK_Data[6]) Hour = ps_Globle->u8_ACK_Data[7]; // 时(对应u8_ACK_Data[7]) Minute = ps_Globle->u8_ACK_Data[8]; // 分(对应u8_ACK_Data[8]) Second = ps_Globle->u8_ACK_Data[9]; // 秒(对应u8_ACK_Data[9]) // 解包设备状态 battery = ps_Globle->u8_ACK_Data[10]; // 电量(对应u8_ACK_Data[10]) CurrentMode = ps_Globle->u8_ACK_Data[11]; // 当前测试模式(对应u8_ACK_Data[11]) //获取对应状态用于LVGL界面更新 ps_Globle->ps_DeviceStatus->battery_percent=battery;//获取电量 //ps_Globle->ps_DeviceStatus->sensor=Sensor;//获取传感器状态 //时间字符串 sprintf(timeStr, "%04d-%02d-%02d %02d:%02d:%02d", Year, Month, Day,Hour,Minute,Second); // 打印基础信息 printf("===== 设备状态 =====\r\n"); printf("CMD: %x\r\n",CMD); printf("status:%d\r\n",status); // 可根据枚举值转换为文字(如0=空闲,1=测量中) printf("Sensor:%d\r\n",Sensor); printf("timeStr:%s\r\n",timeStr); printf("battery: %d\r\n",battery); printf("CurrentMode:%d\r\n",CurrentMode); // 可转换为文字(如1=CV模式,2=IT模式) break; case UART_ACK_SET_IT_PARAM_OK: printf("UART_ACK_SET_IT_PARAM_OK\r\n"); //处理计算参数 uint32_t raw = (ps_Globle->u8_ACK_Data[0] << 24) | (ps_Globle->u8_ACK_Data[1] << 16) | (ps_Globle->u8_ACK_Data[2] << 8) | ps_Globle->u8_ACK_Data[3]; memcpy(&Res_val, &raw, sizeof(float)); printf("cal:%f\r\n",Res_val); // HEARTBEATTimer->start();//0716 lytest break; case UART_ACK_SET_CV_PARAM_OK: printf("UART_ACK_SET_CV_PARAM_OK\r\n"); //处理计算参数 uint32_t raw2 = (ps_Globle->u8_ACK_Data[0] << 24) | (ps_Globle->u8_ACK_Data[1] << 16) | (ps_Globle->u8_ACK_Data[2] << 8) | ps_Globle->u8_ACK_Data[3]; memcpy(&Res_val, &raw2, sizeof(float)); printf("cal:%f\r\n",Res_val); // HEARTBEATTimer->start();//0716 lytest break; case UART_ACK_SET_SWV_PARAM_OK: printf("UART_ACK_SET_SWV_PARAM_OK\r\n"); //处理计算参数 uint32_t raw3 = (ps_Globle->u8_ACK_Data[0] << 24) | (ps_Globle->u8_ACK_Data[1] << 16) | (ps_Globle->u8_ACK_Data[2] << 8) | ps_Globle->u8_ACK_Data[3]; memcpy(&Res_val, &raw3, sizeof(float)); printf("cal:%f\r\n",Res_val); // HEARTBEATTimer->start();//0716 lytest break; case UART_ACK_CHECK_SENSOR_OK: if (ps_Globle->u8_ACK_Data_LEN == UART_DATA_1_BYTE) { printf("UART_ACK_CHECK_SENSOR_OK\r\n"); ps_Globle->ps_DeviceStatus->sensor=(ps_Globle->u8_ACK_Data[0]);//获取传感器状态 printf("sensorstate:%d\r\n",ps_Globle->ps_DeviceStatus->sensor); //处理传感器状态 handle_sensor_state_update(ps_Globle->ps_DeviceStatus->sensor); } break; case UART_CMD_START_IT_MEASURE_OK: printf("UART_CMD_START_IT_MEASURE_OK\r\n"); // 释放旧内存 if (ITData != NULL) myfree(SRAMEX, ITData); if (current_data != NULL) myfree(SRAMEX, current_data); if (voltage_data != NULL) myfree(SRAMEX, voltage_data); //分配内存 ITData = (float*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(float)); current_data = (int*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(int)); voltage_data = (int*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(int)); // 检查分配结果 if (ITData == NULL || current_data == NULL || voltage_data == NULL) { printf("内存分配失败!\r\n"); break; } // 重置计数器 data_index = 0; last_cont = 0; //创建定时器开始定时获取数据 handle_sensor_getdata(); break; case UART_CMD_START_CV_MEASURE_OK: printf("UART_CMD_START_CV_MEASURE_OK\r\n"); // 释放旧内存 if (CVData != NULL) myfree(SRAMEX, CVData); if (current_data != NULL) myfree(SRAMEX, current_data); if (voltage_data != NULL) myfree(SRAMEX, voltage_data); //分配内存 CVData = (float*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(float)); current_data = (int*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(int)); voltage_data = (int*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(int)); // 检查分配结果 if (CVData == NULL || current_data == NULL || voltage_data == NULL) { printf("内存分配失败!\r\n"); break; } // 重置计数器 data_index = 0; last_cont = 0; //创建定时器开始定时获取数据 handle_sensor_getdata(); break; case UART_CMD_START_SWV_MEASURE_OK: printf("UART_CMD_START_SWV_MEASURE_OK\r\n"); // 释放旧内存 if (SWVData != NULL) myfree(SRAMEX, SWVData); if (current_data != NULL) myfree(SRAMEX, current_data); if (voltage_data != NULL) myfree(SRAMEX, voltage_data); //分配内存 SWVData = (float*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(float)); diffData = (float*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(float)); current_data = (int*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(int)); voltage_data = (int*)mymalloc(SRAMEX, s_Globle.ps_Parpam->sensor_datasum * sizeof(int)); // 检查分配结果 if (SWVData == NULL || current_data == NULL || voltage_data == NULL || diffData==NULL) { printf("内存分配失败!\r\n"); break; } // 重置计数器 data_index = 0; last_cont = 0; //创建定时器开始定时获取数据 handle_sensor_getdata(); break; case UART_ACK_GET_DATA_OK://获取数据成功 { // 静态变量跟踪上次模式,用于检测模式变化 static int last_mode = -1; // 检查模式是否变化,如果变化则重置滤波器 if (last_mode != s_Globle.ps_Parpam->current_mode && s_Globle.ps_Parpam->filter) { ResetAllFilters(); last_mode = s_Globle.ps_Parpam->current_mode; } if(s_Globle.ps_Parpam->current_mode==ITMode){ // 接收新数据并存储到ITData for (uint16_t i = 0; i < ps_Globle->u8_ACK_Data_LEN; i += 2) { uint16_t raw = (ps_Globle->u8_ACK_Data[i] << 8) | ps_Globle->u8_ACK_Data[i+1]; float raw_current = AppCHRONOAMPCalcCurrent((int16_t)raw, Res_val); if(s_Globle.ps_Parpam->filter)ITData[data_index] = IT_RealTimeFilter(raw_current);// 应用IT模式实时滤波 else ITData[data_index] = raw_current; data_index++; // 累计总数据量 } // 更新进度条 float persent = (float)data_index / s_Globle.ps_Parpam->sensor_datasum * 100; handle_sensor_scanbar_update(persent); // 实时处理新增数据更新曲线 if (data_index > last_cont) { uint16_t new_count = data_index - last_cont; // 新增数据数量 uint16_t start_idx = last_cont; // 新增数据起始索引 //计算扩展因子 // uint32_t scale = compute_scale_factor_fast(ITData, new_count); // printf("scale:%d\r\n",scale); //滤波处理 // LinearSmooth7(ITData, cont); // 计算新增数据的电压和电流 for (int i = 0; i < new_count; i++) { uint16_t idx = start_idx + i; voltage_data[idx] = (idx + 1) * s_Globle.ps_Parpam->IT_Param.sampleInterval; // 电压=索引+1 current_data[idx] = (int)(ITData[idx] * 1000000); // 电流计算,统一扩展因子 } // 调用增量更新函数,仅更新最新的new_count个数据点 update_chart_with_voltage_current(voltage_data, current_data, start_idx, new_count, ITMode); first_scan=false;//是第一次扫描 // 更新上次处理位置,下次从这里开始 last_cont = data_index; draw_flag=1; } if(data_index==s_Globle.ps_Parpam->sensor_datasum){//累加数据点数等于测量数据总数 control_getdata_timer(0);//停止定时器 float analyse_time = (float)lv_Mode_Parpam.IT_Param.analyse_time / lv_Mode_Parpam.IT_Param.sampleInterval; anodic_peak.voltage=voltage_data[(int)analyse_time-1]; anodic_peak.current=current_data[(int)analyse_time-1];//保留分析电流值 //处理传感器状态 handle_sensor_result_update(&anodic_peak,&cathodic_peak); //保存数据到SD卡 save_IT_data_to_csv(&s_Globle.ps_Parpam->IT_Param, voltage_data, current_data, data_index, &anodic_peak); first_scan=true;//第一次扫描 } } else if(s_Globle.ps_Parpam->current_mode==CVMode){ // 接收新数据并存储到CVData for (uint16_t i = 0; i < ps_Globle->u8_ACK_Data_LEN; i += 2) { uint16_t raw = (ps_Globle->u8_ACK_Data[i] << 8) | ps_Globle->u8_ACK_Data[i+1]; float raw_current = AppCHRONOAMPCalcCurrent((int16_t)raw, Res_val); if(s_Globle.ps_Parpam->filter)CVData[data_index] = CV_RealTimeFilter(raw_current);// 应用IT模式实时滤波 else CVData[data_index] = raw_current; data_index++; // 累计总数据量 } // 更新进度条 float persent = (float)data_index / s_Globle.ps_Parpam->sensor_datasum * 100; handle_sensor_scanbar_update(persent); // 计算当前方向下的总步数 uint16_t totalstep = Dire ? (s_Globle.ps_Parpam->CV_Param.HighEval - s_Globle.ps_Parpam->CV_Param.InitEval) / s_Globle.ps_Parpam->CV_Param.SampleInt : (s_Globle.ps_Parpam->CV_Param.InitEval - s_Globle.ps_Parpam->CV_Param.LowEval) / s_Globle.ps_Parpam->CV_Param.SampleInt; if (totalstep == 0) totalstep = 1; // 避免除零错误 // 实时处理新增数据 if (data_index > last_cont) { uint16_t new_count = data_index - last_cont; // 新增数据点数 uint16_t start_idx = last_cont; // 起始索引 for (int i = 0; i < new_count; i++) { uint16_t idx = start_idx + i; uint16_t currentStep = DataCount - ScandataCount; // 当前周期内的步数 // 计算电压值(关键修改) if (currentStep < totalstep) { // 第一个半周期 if (Dire) { voltage_data[idx] = s_Globle.ps_Parpam->CV_Param.InitEval + currentStep * s_Globle.ps_Parpam->CV_Param.SampleInt; } else { voltage_data[idx] = s_Globle.ps_Parpam->CV_Param.InitEval - currentStep * s_Globle.ps_Parpam->CV_Param.SampleInt; } } else { // 第二个半周期 uint16_t stepInHalf = currentStep - totalstep; if (Dire) { voltage_data[idx] = s_Globle.ps_Parpam->CV_Param.HighEval - stepInHalf * s_Globle.ps_Parpam->CV_Param.SampleInt; } else { voltage_data[idx] = s_Globle.ps_Parpam->CV_Param.LowEval + stepInHalf * s_Globle.ps_Parpam->CV_Param.SampleInt; } } // 计算电流值(带缩放) current_data[idx] = (int)(CVData[idx] * 1000000); // 缩放因子根据需求调整 // 更新全局计数 DataCount++; // 检查周期结束并更新状态 if (currentStep + 1 == 2 * totalstep) { ScandataCount += 2 * totalstep; if (s_Globle.ps_Parpam->CV_Param.InitEval != s_Globle.ps_Parpam->CV_Param.LowEval) { Dire = !Dire; // 切换扫描方向 } } } // 调用增量更新函数,仅更新最新的new_count个数据点 update_chart_with_voltage_current(voltage_data, current_data, start_idx, new_count, first_scan); last_cont = data_index; // 更新已处理位置 draw_flag = 1; first_scan=false;//是第一次扫描了 } if(data_index >= s_Globle.ps_Parpam->sensor_datasum){//完成一圈扫描 control_getdata_timer(0);//停止定时器 // 确保数据索引一致 if (data_index > 0) { // 执行峰值检测 find_CV_peaks(voltage_data, current_data, data_index, &anodic_peak, &cathodic_peak); // 输出峰值信息(可根据需要显示在UI上) if (anodic_peak.index != -1) { printf("阳极峰: 电压=%d mV, 电流=%d A (索引=%d)\n", anodic_peak.voltage, anodic_peak.current, anodic_peak.index); // // 在图表上标记阳极峰 // mark_peak_on_chart(anodic_peak.voltage, anodic_peak.current, "Anodic Peak"); } if (cathodic_peak.index != -1) { printf("阴极峰: 电压=%d mV, 电流=%d A (索引=%d)\n", cathodic_peak.voltage, cathodic_peak.current, cathodic_peak.index); // // 在图表上标记阴极峰 // mark_peak_on_chart(cathodic_peak.voltage, cathodic_peak.current, "Cathodic Peak"); } // 计算峰电位差(ΔEp) if (anodic_peak.index != -1 && cathodic_peak.index != -1) { int delta_ep = abs(anodic_peak.voltage - cathodic_peak.voltage); printf("峰电位差(ΔEp) = %d mV\n", delta_ep); // // 判断是否为可逆体系(ΔEp ≈ 59mV/n) // if (delta_ep > 50 && delta_ep < 70) { // printf("体系显示可逆电化学行为\n"); // } } } // // 增加扫描计数 // static uint8_t cv_scan_count = 1; //处理传感器状态 handle_sensor_result_update(&anodic_peak,&cathodic_peak); // 保存当前扫描的峰值数据 anodic_peak_data[cv_scan_count-1] = anodic_peak; cathodic_peak_data[cv_scan_count-1]=cathodic_peak; // 在每次扫描完成后保存数据 voltage_data_scans[cv_scan_count-1] = mymalloc(SRAMEX, data_index * sizeof(int)); current_data_scans[cv_scan_count-1] = mymalloc(SRAMEX, data_index * sizeof(int)); for (uint16_t i = 0; i < data_index; i++) { voltage_data_scans[cv_scan_count-1][i] = voltage_data[i]; current_data_scans[cv_scan_count-1][i] = current_data[i]; } // 检查是否需要再次扫描 if(cv_scan_count < s_Globle.ps_Parpam->CV_Param.SweepSegments) { cv_scan_count++; // 增加扫描计数 // 重置数据索引 data_index = 0; last_cont = 0; // 切换到下一个图表系列 lv_chart_series_t* next_ser = lv_chart_get_series_next(guider_ui.screen_scan_scan_chart, guider_ui.screen_factorypattern_chart_elect_0); if(!next_ser) { next_ser = lv_chart_get_series_next(guider_ui.screen_scan_scan_chart, NULL); } guider_ui.screen_factorypattern_chart_elect_0 = next_ser; lv_chart_hide_series(guider_ui.screen_scan_scan_chart, guider_ui.screen_factorypattern_chart_elect_0, false); // 发送开始测试指令 TX_CMD_Pack(UART_CMD_START_CV_MEASURE); // 确保发送缓冲区缓存一致性 SCB_CleanDCache_by_Addr((uint32_t *)s_UART.u_Buffer_Tx[0].u8_Buffer_T, UART_TX_BUFFER_SIZE); // 启动DMA接收 HAL_UART_Receive_DMA(&g_uart7_handle, s_UART.u_Buffer_Rx[s_UART.u8_Uart_Rx_index].u8_Buffer_R, UART_RX_BUFFER_SIZE); s_UART.u8_Uart_Rx_DmaComplete = 0; HAL_UART_Transmit_DMA(&g_uart7_handle, s_UART.u_Buffer_Tx[0].u8_Buffer_T, UART_TX_BUFFER_SIZE); // 更新状态 lv_label_set_text(guider_ui.screen_scan_scan_label_state, "SCANNING"); s_Globle.ps_Parpam->current_status=TEST_STATUS_TESTING;//正在测量状态 } else { // 所有扫描完成,停止定时器 control_getdata_timer(0); // 在保存CSV时,调用修改后的函数 save_CV_data_to_csv(&s_Globle.ps_Parpam->CV_Param, voltage_data_scans, current_data_scans, data_index, anodic_peak_data, cathodic_peak_data, cv_scan_count); // 传递扫描次数 // 重置计数器 cv_scan_count = 1; total_data_count = 0; first_scan=false;//设置第一次扫描,为下次扫描做准备 // 在CV模式完成后释放内存 for (int i = 0; i < cv_scan_count; i++) { if (voltage_data_scans[i] != NULL) { myfree(SRAMEX, voltage_data_scans[i]); voltage_data_scans[i] = NULL; } if (current_data_scans[i] != NULL) { myfree(SRAMEX, current_data_scans[i]); current_data_scans[i] = NULL; } } } } } else if(s_Globle.ps_Parpam->current_mode == SWVMode) { // 接收新数据并存储到ITData for (uint16_t i = 0; i < ps_Globle->u8_ACK_Data_LEN; i += 2) { uint16_t raw = (ps_Globle->u8_ACK_Data[i] << 8) | ps_Globle->u8_ACK_Data[i+1]; float raw_current = AppCHRONOAMPCalcCurrent((int16_t)raw, Res_val); if(s_Globle.ps_Parpam->filter)SWVData[data_index] = SWV_RealTimeFilter(raw_current);// 应用IT模式实时滤波 else SWVData[data_index] = raw_current; data_index++; // 累计总数据量 } // 更新进度条 float persent = (float)data_index / (s_Globle.ps_Parpam->sensor_datasum *2) * 100; handle_sensor_scanbar_update(persent); // 实时处理新增数据更新曲线 if (data_index > last_cont) { uint16_t new_count = data_index - last_cont; // 新增数据数量 uint16_t start_idx = last_cont; // 新增数据起始索引 uint16_t diff_count = 0; // 计算SWV差值数据 for (uint16_t i = start_idx; i < data_index; i += 2) { if (i + 1 < data_index) { // 计算正向和反向脉冲的差值 float diff = SWVData[i] - SWVData[i+1]; diffData[diff_count] = diff; diff_count++; } } // 电压计算 float init = s_Globle.ps_Parpam->SWV_Param.InitEval; float incr = s_Globle.ps_Parpam->SWV_Param.IncrEval; int dir = (init < s_Globle.ps_Parpam->SWV_Param.FinalEval) ? 1 : -1; // 为新增数据计算电压和电流 for (uint16_t i = 0; i < diff_count; i++) { uint16_t idx = start_idx/2 + i; int voltage_val = init + (incr * (idx+1)) * dir; int current_val = (int)(diffData[i] * 1000000); // 保存到全局数据数组 if (total_data_count < MAX_TOTAL_DATA_POINTS) { voltage_data_all[total_data_count] = voltage_val; current_data_all[total_data_count] = current_val; total_data_count++; } // 实时更新图表 voltage_data[idx] = voltage_val; current_data[idx] = current_val; } // 调用增量更新函数 update_chart_with_voltage_current(voltage_data, current_data, start_idx/2, diff_count, first_scan); first_scan=false;//是第一次扫描了 // 更新上次处理位置 last_cont = data_index; draw_flag = 1; } // 检查是否完成 if(data_index >= s_Globle.ps_Parpam->sensor_datasum * 2) { // 所有扫描完成,停止定时器 control_getdata_timer(0); // 处理当前扫描的结果 float analyse_potential = (float)(lv_Mode_Parpam.SWV_Param.analyse_potential - lv_Mode_Parpam.SWV_Param.InitEval)/lv_Mode_Parpam.SWV_Param.IncrEval; int analyse_index = (int)analyse_potential - 1; if (analyse_index < 0) analyse_index = 0; if (analyse_index >= data_index/2) analyse_index = data_index/2 - 1; anodic_peak.voltage = voltage_data[analyse_index]; anodic_peak.current = current_data[analyse_index]; // 处理传感器状态 handle_sensor_result_update(&anodic_peak, &cathodic_peak); // 保存当前扫描的峰值数据 anodic_peak_data[scan_count-1] = anodic_peak; // 分配内存并复制当前扫描的数据 current_data_scans[scan_count-1] = mymalloc(SRAMEX, (data_index/2) * sizeof(int)); for (uint16_t i = 0; i < data_index/2; i++) { current_data_scans[scan_count-1][i] = current_data[i]; } // 检查是否需要再次扫描 if(scan_count < s_Globle.ps_Parpam->SWV_Param.Number) { scan_count++; // 增加扫描计数 // 重置数据索引 data_index = 0; last_cont = 0; // 切换到下一个图表系列 lv_chart_series_t* next_ser = lv_chart_get_series_next(guider_ui.screen_scan_scan_chart, guider_ui.screen_factorypattern_chart_elect_0); if(!next_ser) { next_ser = lv_chart_get_series_next(guider_ui.screen_scan_scan_chart, NULL); } guider_ui.screen_factorypattern_chart_elect_0 = next_ser; lv_chart_hide_series(guider_ui.screen_scan_scan_chart, guider_ui.screen_factorypattern_chart_elect_0, false); // 发送开始测试指令 TX_CMD_Pack(UART_CMD_START_SWV_MEASURE); // 确保发送缓冲区缓存一致性 SCB_CleanDCache_by_Addr((uint32_t *)s_UART.u_Buffer_Tx[0].u8_Buffer_T, UART_TX_BUFFER_SIZE); // 启动DMA接收 HAL_UART_Receive_DMA(&g_uart7_handle, s_UART.u_Buffer_Rx[s_UART.u8_Uart_Rx_index].u8_Buffer_R, UART_RX_BUFFER_SIZE); s_UART.u8_Uart_Rx_DmaComplete = 0; HAL_UART_Transmit_DMA(&g_uart7_handle, s_UART.u_Buffer_Tx[0].u8_Buffer_T, UART_TX_BUFFER_SIZE); // 更新状态 lv_label_set_text(guider_ui.screen_scan_scan_label_state, "SCANNING"); s_Globle.ps_Parpam->current_status=TEST_STATUS_TESTING;//正在测量状态 } else { // 所有扫描完成,停止定时器 control_getdata_timer(0); // 在每次扫描完成后记录数据点数 data_counts[scan_count-1] = data_index/2; // 保存数据时传递数据点数数组 save_SWV_data_to_csv(&s_Globle.ps_Parpam->SWV_Param, current_data_scans, data_counts, // 改为传递数组 anodic_peak_data, scan_count); // 重置计数器 scan_count = 1; total_data_count = 0; first_scan=true;//第一次扫描 } } } break; } case UART_ACK_STOP_OK: printf("UART_ACK_STOP_OK\r\n"); // 停止获取数据定时器 control_getdata_timer(0);//停止定时器 if(s_Globle.ps_Parpam->current_mode==ITMode){ float analyse_time=(float)lv_Mode_Parpam.IT_Param.analyse_time/lv_Mode_Parpam.IT_Param.sampleInterval;//存储分析电流 if(data_index>=(int)analyse_time){ anodic_peak.voltage=voltage_data[(int)analyse_time-1]; anodic_peak.current=current_data[(int)analyse_time-1];//保留分析电流值 }else{ //赋值结果 anodic_peak.voltage=voltage_data[data_index-1]; anodic_peak.current=current_data[data_index-1];//保留分析电流值 } //保存当前数据到SD卡 save_IT_data_to_csv(&s_Globle.ps_Parpam->IT_Param, voltage_data, current_data, data_index, &anodic_peak); }else if(s_Globle.ps_Parpam->current_mode==CVMode){ // 执行峰值检测 find_CV_peaks(voltage_data, current_data, data_index, &anodic_peak, &cathodic_peak); // 输出峰值信息(可根据需要显示在UI上) if (anodic_peak.index != -1) { printf("阳极峰: 电压=%d mV, 电流=%d A (索引=%d)\n", anodic_peak.voltage, anodic_peak.current, anodic_peak.index); } if (cathodic_peak.index != -1) { printf("阴极峰: 电压=%d mV, 电流=%d A (索引=%d)\n", cathodic_peak.voltage, cathodic_peak.current, cathodic_peak.index); } // 计算峰电位差(ΔEp) if (anodic_peak.index != -1 && cathodic_peak.index != -1) { int delta_ep = abs(anodic_peak.voltage - cathodic_peak.voltage); printf("峰电位差(ΔEp) = %d mV\n", delta_ep); } // 只保存当前扫描的数据(单次扫描) // 分配临时数组存储当前扫描数据 int* temp_voltage = (int*)mymalloc(SRAMEX, data_index * sizeof(int)); int* temp_current = (int*)mymalloc(SRAMEX, data_index * sizeof(int)); memcpy(temp_voltage, voltage_data, data_index * sizeof(int)); memcpy(temp_current, current_data, data_index * sizeof(int)); // 在保存CSV时,调用修改后的函数 save_CV_data_to_csv(&s_Globle.ps_Parpam->CV_Param, &temp_voltage, &temp_current, data_index, anodic_peak_data, cathodic_peak_data, cv_scan_count); // 传递扫描次数 // 释放临时内存 myfree(SRAMEX, temp_voltage); myfree(SRAMEX, temp_current); } else if(s_Globle.ps_Parpam->current_mode==SWVMode){ // 计算分析点的位置 float analyse_potential = (float)(lv_Mode_Parpam.SWV_Param.analyse_potential - lv_Mode_Parpam.SWV_Param.InitEval)/lv_Mode_Parpam.SWV_Param.IncrEval; int analyse_index = (int)analyse_potential - 1; // 确保索引有效 if (analyse_index < 0) analyse_index = 0; if (analyse_index >= data_index/2) analyse_index = data_index/2 - 1; if(data_index >= (int)analyse_potential){ anodic_peak.voltage = voltage_data[analyse_index]; anodic_peak.current = current_data[analyse_index];//保留分析电流值 } else { //赋值结果 anodic_peak.voltage = voltage_data[data_index/2 - 1]; anodic_peak.current = current_data[data_index/2 - 1];//保留分析电流值 } // 保存当前扫描的数据到current_data_scans数组 if (scan_count <= MAX_SCANS) { current_data_scans[scan_count-1] = mymalloc(SRAMEX, (data_index/2) * sizeof(int)); for (uint16_t i = 0; i < data_index/2; i++) { current_data_scans[scan_count-1][i] = current_data[i]; } } // 保存峰值数据 anodic_peak_data[scan_count-1] = anodic_peak; // 在每次扫描完成后记录数据点数 data_counts[scan_count-1] = data_index/2; // 保存数据时传递数据点数数组 save_SWV_data_to_csv(&s_Globle.ps_Parpam->SWV_Param, current_data_scans, data_counts, // 改为传递数组 anodic_peak_data, scan_count); } //处理传感器状态 handle_sensor_result_update(&anodic_peak,&cathodic_peak); break; } return 0; }Scan Type SWV InitEval 200 FinalEval 600 IncrEval 4 AmplitudeE 25 QuiteTime 2000 Frequency 10 Range 0 Number of Scans 2 Analyse Potential 500 Light Type 0 Light Power (mW) 2 Min Range 200 Max Range 400 Date 20250412 Time 011000 File Number 1 Peak Data Scan Voltage(mV) Current(uA) 1 500 140 2 488 139 Average 494 139 Voltage(mV) Scan1(uA) Scan2(uA) 200 139 204 139 208 140 212 138 216 141 220 139 224 139 228 139 232 137 236 139 240 138 244 140 248 138 252 140 256 140 260 140 264 140 268 139 272 140 276 139 280 140 284 139 288 140 292 140 296 140 300 140 304 138 308 140 312 138 316 140 320 138 324 139 328 140 332 140 336 140 340 138 344 140 348 137 352 138 356 139 360 139 364 138 368 139 372 139 376 136 380 139 384 137 388 139 392 136 396 139 400 141 404 139 408 140 412 138 416 140 420 139 424 140 428 139 432 140 436 139 440 139 444 140 448 138 452 140 456 139 460 140 464 139 468 140 472 138 476 140 480 140 484 139 为什么会这样,第一圈数据直接为空了,而且第一圈数据已经是200-600的这里为什么又被省略了
最新发布
09-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值