logo资料库

2019年TI杯 简易电路特性测试仪 制作过程(4)——程序总体分析 20/04/20.pdf

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
2019年年TI杯杯 简易电路特性测试仪 分析分析 20/04/20 简易电路特性测试仪 制作过程( 制作过程(4))——程序总体 程序总体 一、程序流程说明 一、程序流程说明   程序中使用了嵌入式实时操作系统FreeRTOS,如果以前没有使用过嵌入式实时操作系统(RTOS)的同学,阅读或修改 代码的时候可能会有点吃力。带RTOS的编程方式和传统的不带操作系统的编程还是有很大的区别的,如果已经接触STM32编 程有段时间的同学,可以去学习一下RTOS,如果在一些较为复杂的项目中,使用RTOS进行编程会相对简单一些。推荐可以 学习FreeRTOS,这个操作系统是完全开源并且免费的。 /************************************************* main函数说明 函数说明 ************************************************/ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//中断分组4 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO复用时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试 这两句话非常重要,因为开发板中的 按键和EEPROM中的引脚和JTAG引脚复用 DBGMCU->CR &= ~((uint32_t)1MAPR & ~((uint32_t)0x7 << 24)) | (2 << 24); /* PA15 PB3 PB4 */ delay_init(); //初始化延时函数 LED_Init(); //初始化led KEY_Init(); //按键初始化 Display_Init(); //显示初始化 Menu_Init(); //菜单初始化 MY_ADC_Init(); //ADC初始化 MYTIMER_Init(); //定时器初始化 DO_Init(); AD9850_Init(); AT24CXX_Init(); //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 } main函数中先是设定中断分组,然后禁用JTAG开启了SWD(因为引脚冲突),在之后初始化一些需要用到的外设,最后 创建开始任务再开启FreeRTOS(就是开启任务调度)。main函数比较简单就是开启了一些外设和系统初始化。 /************************************************* start_task说明说明 ************************************************/ void start_task(void *pvParameters) { /********* cpu使用率统计功能 **********/ #if (usercfgCPU_USAGE_CALCULATE==1) uTaskCPUUsageInit(); //不可以在临界区内调用 // 此种方法计算CPU使用率的原理为: // 1、在系统启动后,所有用户任务都未开始运行时,统计一段时间T(如1s)内空闲任务被调用的次数M,此时可认为这个次数 是CPU占用率最小(接近0)时能够调用空闲任务的最大次数。 // 2、任务开始运行后,在滴答时钟中断处理函数中,每隔T时间,记录空闲任务被调用的次数m。 // 3、CPU占用率为:(1-m/M)*100% #endif taskENTER_CRITICAL(); //进入临界区 /************** 创建BASIC任务 ***************/ xTaskCreate((TaskFunction_t )basic_task, (const char* )"bac", (uint16_t )BASIC_STK_SIZE, (void* )NULL, (UBaseType_t )BASIC_TASK_PRIO, (TaskHandle_t* )&BASICTask_Handler); /************** 创建MENU任务 ***************/ xTaskCreate((TaskFunction_t )menu_task, (const char* )"meu", (uint16_t )MENU_STK_SIZE, (void* )NULL, (UBaseType_t )MENU_TASK_PRIO,
(TaskHandle_t* )&MENUTask_Handler); /************** 创建MAESURE任务 ***************/ xTaskCreate((TaskFunction_t )measure_task, (const char* )"CAL", (uint16_t )MEASURE_STK_SIZE, (void* )NULL, (UBaseType_t )MEASURE_TASK_PRIO, (TaskHandle_t* )&MEASURETask_Handler); Key_QueueHandle = xQueueCreate(KEY_QUEUELEN,KEY_QUEUESIZE); /* 创建key消息队列 */ while(Key_QueueHandle == NULL); /* 队列创建不成功 */ Measure_SemaphoreHandle = xSemaphoreCreateCounting( MEASURE_MAXCOUNT, MEASURE_INITCOUNT );//创建 measure_task信号量 while(Measure_SemaphoreHandle == NULL); Read_Gain(); //读取EEPROM中的增益数据 vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } start_task任务中主要是进行其他任务、信号量、消息队列的创建,可以看到分别创建了basic_task、menu_task、 measure_task三个任务,三个任务的具体内容会在下文进行说明。创建了句柄为Key_QueueHandle的消息队列,用来向 menu_task任务发送key消息,按键扫描在basic_task中进行,任务间的消息传递用消息队列实现。创建了句柄为 Measure_SemaphoreHandle的计数型信号量,这个信号量用于任务同步,每当ADC采集完成了一组数据之后,发送这个信号 量给measure_task任务,这个任务主要进行数据的计算和判断。Read_Gain函数读取保存的校准参数,之后删除开始任务 (开始任务主要就是创建其他任务,创建完成之后就用不到了,进行删除。) usercfgCPU_USAGE_CALCULATE宏定义用于开启CPU使用率统计,FreeRTOS是没有CPU使用率统计功能的,这个功 能是我额外加入的,开启这个宏就可以查看CPU的使用率统计了。一般调试的时候可以开启,正式程序发布之后关闭这个功 能(这个功能还是会占用CPU使用率的)。 关于如何在FreeRTOS中添加CPU使用率统计功能,可以参考这篇博客: https://blog.csdn.net/wenyuexunyin/article/details/68937150 二、二、basic_task任务分析 任务分析 void basic_task(void *pvParameters) { uint8_t i = 0,key; Measure_Rs.R6_value = 3015; //电阻值根据实际值填写 电阻精度较差时可用万用表测量之后填写精确值 Measure_Rs.R8_value = 20150; Measure_Rs.R40_value = 1000; Measure_Rs.R42_value = 3000; if(Measure_Dc.dc_gain == 0) Measure_Dc.dc_gain = 40;//设为默认4.0 while(1) { i++; fptx_rand++;//用于随机选择幅频曲线显示 if(i == 100) { i = 0; LED0 = !LED0; //run灯闪 } key = KEY_Scan(0); /* 按键扫描 */ if(key != 0) /* 有按键按下了 */ { if(Current_Menu == NULL) //界面 { if((key == KEY0_PRES) && (device_mode == DEVICE_MODE_MEASURE)) //测量模式 向上键 { Measure_data.data_reg.Measure = 1;//开始测量 DC_OFFSET_MEASURE();//测直流偏置 vTaskDelay(100); measure_sta = MEASURE_DC_STA; //测量直流偏置 } else if(key == KEY1_PRES)//向下键 { if(device_mode == DEVICE_MODE_MEASURE) { device_mode = DEVICE_MODE_JUDGE; //判断 Measure_data.data_reg.Measure = 1;//开始测量 DC_OFFSET_MEASURE();//测直流偏置 vTaskDelay(100); measure_sta = MEASURE_DC_STA; //测量直流偏置
} else device_mode = DEVICE_MODE_MEASURE; //测量 DDS_reg.fre_num = 1000; DDS_reg.fre_sta = 1; Display_Clear(); } } if(Key_QueueHandle != NULL) { xQueueSend(Key_QueueHandle,&key,0); } } //DDS频率变化 if(DDS_reg.fre_sta == 1) { DDS_reg.fre_sta = 0; ad9850_wr_serial(0x00,DDS_reg.fre_num);//改变频率输出 } vTaskDelay(10); } } basic_task任务中主要进行一些基本工作,比如运行指示灯、按键扫描、改变DDS频率输出,本任务10ms会被调用一 次。 key1进行模式切换,一个是测量模式,一个是判断模式,测量模式下按下key0按键进行一次数据测量。如果按键被按 下,就会将按下按键的键值插入创建的消息队列进行发送。 三、三、menu_task任务分析 任务分析 void menu_task(void *pvParameters) { uint8_t key_que,que_res; while(1) { que_res = xQueueReceive( Key_QueueHandle,&key_que,50); /* 等key消息50ms */ if(que_res == pdTRUE) { Menu_Handler(key_que); Menu_Display(); } else { Main_Display();//主界面显示 } } } menu_task任务主要是处理显示一块的任务,Menu_Handler(key_que); Menu_Display();两个函数主要是处理菜单显示和 菜单操作逻辑的,实现菜单结构,这里不做详细的分析,有兴趣的同学可以仔细研究一下菜单实现的原理(后续有空的话写一 篇讲讲实现多级菜单的方法,为自己挖个坑。)。菜单中的任务函数会进行装置的校准,根据选择进入不同的菜单,进行不同 参数的校准,校准的过程会在后面的博客中进行详细分析。 Main_Display()函数主要是主界面的显示,测量模式下显示测量的数据,故障判断模式下显示电路的故障种类。 四、四、measure_task任务分析 任务分析 void measure_task(void *pvParameters) { uint8_t cal_res; while(1) { xSemaphoreTake(Measure_SemaphoreHandle,portMAX_DELAY); //死等信号量 if(measure_sta != MEASURE_NONE_STA) //需要测量 { switch(measure_sta) //根据状态来采样 { case(MEASURE_DC_STA): //测量直流偏置电压 cal_res = DC_Cal_Handle(); if(cal_res == 1) //直流偏置电压计算完成 { Measure_data.data_reg.Dc_sta = 1; //DC测量完毕 Measure_data.Dc = Measure_Dc.dc_value; measure_sta = MEASURE_NONE_STA;//停止采样 /***************** 测量输入电阻 ******************/ R6_MEASURE_UI2_IN();//切继电器 接入R6
Measure_Rs.Rs_Ri_sta = 0;//R6 DDS_reg.fre_num = 1000; ad9850_wr_serial(0x00,DDS_reg.fre_num);//1K 默认输出 vTaskDelay(200);//延时 等待继电器切换 memset(&Measure_Ri_Jun,0,sizeof(Measure_Ri_Jun));//清空缓存 Measure_Dc.dc_sample_count = 0; measure_sta = MEASURE_RI_STA; //测量输入电阻 Measure_Dc.dc_sample_count = 0; } break; case(MEASURE_RI_STA): //测量输入电阻 if(DDS_reg.fre_num == 1000) //1K cal_res = Ri_Cal_1KHz_Handle(); if(cal_res == 1) //直流输入电阻计算完成 { Measure_data.data_reg.Ri_sta = 1; //输入电阻测量完毕 measure_sta = MEASURE_NONE_STA;//停止采样 /***************** 测量输出电阻 ******************/ MEASURE_UO1_OUT();//Uo1 Measure_Rs.Rs_Ro_sta = 1;//R42 DDS_reg.fre_num = 1000; ad9850_wr_serial(0x00,DDS_reg.fre_num);//1K 默认输出 vTaskDelay(200);//延时 等待继电器切换 if(DDS_reg.fre_num == 1000) //1K memset(&Measure_Ri_Jun,0,sizeof(Measure_Ri_Jun));//清缓存 measure_sta = MEASURE_RO_STA; //测量输出电阻 } break; case(MEASURE_RO_STA): //测量输出电阻 if(DDS_reg.fre_num == 1000) //1K cal_res = Ro_Cal_1KHz_Handle(); if(cal_res == 1) //直流输出电阻计算完成 { Measure_data.data_reg.Ro_sta = 1; //输出电阻测量完毕 measure_sta = MEASURE_NONE_STA;//停止采样 /***************** 测量增益 ******************/ AV_MEASURE_UO_IN() ;//切继电器 Ui DDS_reg.fre_num = 1000; ad9850_wr_serial(0x00,DDS_reg.fre_num);//1K 默认输出 vTaskDelay(200);//延时 等待继电器切换 if(DDS_reg.fre_num == 1000) //1K memset(&Measure_Ro_Jun,0,sizeof(Measure_Ro_Jun));//清缓存 measure_sta = MEASURE_AV_STA; //测量增益 } break; case(MEASURE_AV_STA): //测量增益 if(DDS_reg.fre_num == 1000) //1K cal_res = Av_Cal_1KHz_Handle(); if(cal_res == 1) //直流增益计算完成 { if(device_mode == DEVICE_MODE_MEASURE) //测量模式 { Measure_data.data_reg.Av_sta = 1; //增益测量完毕 measure_sta = MEASURE_FPTX_STA; //测量幅频特性 //这里需要将里面的缓存里的数据显示出XY图 fptx_bmp_sta = fptx_rand%3; FPTX_MEASURE();//幅频特性 /***************** 测量幅频特性 ******************/ memset(&Measure_Av_Jun,0,sizeof(Measure_Av_Jun));//清缓存 DMA_Cmd(DMA2_Channel5,ENABLE);//使能 } else //故障判断模式 { measure_sta = MEASURE_NONE_STA; //不测量 if(Judge_5K_Av_Sta == 0)//5K增益没测 DDS_reg.fre_num = 5000; //5k else DDS_reg.fre_num = 200000; //200k DDS_reg.fre_sta = 1; //改变频率 FPTX_MEASURE() ;//切继电器 幅频特性 vTaskDelay(50);//延时 等待继电器切换 和增益继电器一样不用等待 /***************** 测量幅频特性 ******************/ memset(&Measure_Av_Jun,0,sizeof(Measure_Av_Jun));//清缓存 DMA_Cmd(DMA2_Channel5,ENABLE);//使能 measure_sta = MEASURE_FPTX_STA; //测量幅频特性 }
} break; case(MEASURE_FPTX_STA): //测量幅频特性 if(device_mode == DEVICE_MODE_MEASURE) { cal_res = FPTX_Cal_Scan_Handle();//扫描法 if(cal_res == 1) //找到截止频率了 { Measure_data.fre_stop = DDS_reg.fre_num;//上限频率 measure_sta = MEASURE_NONE_STA; //停止测量 Measure_data.data_reg.Measure = 0;//测试停止 //这里需要将里面的缓存里的数据显示出XY图 fptx_bmp_sta = fptx_rand%3; NORMAL_STATE();//正常状态 Measure_data.data_reg.Fptx_sta = 1; DDS_reg.fre_num = 1000; ad9850_wr_serial(0x00,DDS_reg.fre_num);//1K 默认输出 max_av = 0; } else //没找到 { if(DDS_reg.fre_num = 30000)//30k以上 DDS_reg.fre_num = DDS_reg.fre_num*103/100;//3% ad9850_wr_serial(0x00,DDS_reg.fre_num);//改变频率输出 delay_ms(10); DMA_Cmd(DMA2_Channel5,ENABLE);//使能 } } else //判断模式 { if(Judge_5K_Av_Sta == 0)//5K增益没测 { if(FPTX_Cal_5K_Handle() == 0) { Judge_5K_Av_Sta = 1; DDS_reg.fre_num = 200000; //200k ad9850_wr_serial(0x00,DDS_reg.fre_num);//改变频率输出 delay_ms(50); DMA_Cmd(DMA2_Channel5,ENABLE);//使能 } } else { if(DDS_reg.fre_num == 200000) { if(Judge_Change() == 0) { cal_res = FPTX_Cal_200K_Handle(); if(cal_res == 0) //C3开路 { //C3开路 Judge_Change_Mark.Judge_type = C3_OPEN; Judge_Change_Mark.Jude_sta = 1; } else if(cal_res == 2) //C3to2 { Judge_Change_Mark.Judge_type = C3_TO_2; Judge_Change_Mark.Jude_sta = 1; } else //C1to2 C2To2 或者无故障 { TIM_Cmd(TIM2,DISABLE);//失能定时器2 TIM_SetAutoreload(TIM2,1250);//6.4K 200Hz32个点的均方根 TIM_SetCounter(TIM2,0); DDS_reg.fre_num = 200; //200Hz ad9850_wr_serial(0x00,DDS_reg.fre_num);//改变频率输出 delay_ms(100); TIM_Cmd(TIM2,ENABLE);//使能定时器2
} } } else if(DDS_reg.fre_num == 200) { cal_res = Av_Cal_200Hz_Handle(); if(cal_res == 0) { Judge_Change_Mark.Judge_type = C2_TO_2; Judge_Change_Mark.Jude_sta = 1; } if(cal_res != 2) measure_sta = MEASURE_NONE_STA; } } if((Judge_Change_Mark.Jude_sta == 1) || (measure_sta == MEASURE_NONE_STA))//找到故障或者幅频测试完毕 { TIM_Cmd(TIM2,DISABLE);//失能定时器2 TIM_SetAutoreload(TIM2,250);//32K 1KHz32个点的均方根 TIM_SetCounter(TIM2,0); TIM_Cmd(TIM2,ENABLE);//使能定时器2 Judge_Change_Mark.Judge_Over = 1;//循环一次 DC_OFFSET_MEASURE();//测直流偏置 vTaskDelay(50); DDS_reg.fre_num = 1000; //1000 DDS_reg.fre_sta = 1; //改变频率 measure_sta = MEASURE_DC_STA; //测量直流偏置 //循环 memset(&Measure_200HzAv_Jun,0,sizeof(Measure_200HzAv_Jun));//清缓存 } } break; } } Check_Cal_Data();//校准时的测量 } } measure_task任务是本程序的重点,这个任务中进行各个量的测量,采用状态机的方式实现,通过判断状态标志得知当 前测量的是哪个量,然后进入到对应的计算函数中进行计算。 程程序中测量模式下的测量顺序分别为直流量、输入电阻、输出电阻、1kHz下的增益Av、截止频率。由于我使用的显示屏 为OLED12864,没办法显示详细的幅频特性曲线,而且评分标准中主要要求测量截止频率,所以程序中并未测量实际的幅频 特性曲线,只是测量完成之后会随机显示一幅事先准备好的幅频特性曲线图片。测量完成所有量之后,程序将状态标志设置为 MEASURE_NONE_STA停止测量,然后显示测量值。 判判断模式下,程序中的测量顺序基本和测量模式下一样,只不过在幅频特性测量环节会有所差异,并且判断模式下程序不 会主动停止测量,会进行循环测量,当测量的到的数据异常时,程序会根据异常显示出具体是什么故障。切换到测量模式后, 程序才会停止循环测量。 这这个任务之后还会进行具体分析,这里只做简单的介绍。 五、五、ADC配置及数据采集说明 配置及数据采集说明 void MY_ADC_Init(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC3,ENABLE);//开启ADC1 ADC3的时钟 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M ADC_IO_Init(); ADC_DeInit(ADC1); //复位ADC1 ADC_DeInit(ADC3); //复位ADC3 ADC_DeInit需要放置在所有ADC初始化配置之前 不然会造成数据错乱 配置错误 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在多通道模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在多次转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = ADC1_CHANNL_NUM; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 #if (PCB_TYPE == 1) ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_7Cycles5 ); //测量放大器输入信号 PC0- >UI_ADC ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_7Cycles5 ); //测量放大器输出直流 PC1- >UO_DC ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_7Cycles5 ); //测量放大器输出信号 PC2- >UO_1 ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_7Cycles5 ); //测量放大器输出信号 PC3- >UO_2 均方根 #endif #if (PCB_TYPE == 2) #endif #if (PCB_TYPE == 3) #endif /******************** ADC1 *****************/ ADC_DMACmd(ADC1,ENABLE);//开启ADC1的DMA ADC_Cmd(ADC1, ENABLE); //使能指定ADC1 ADC_ResetCalibration(ADC1); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件开启ADC1转换 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //模数转换工作在单通道模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在多次转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC3, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 ADC_RegularChannelConfig(ADC3, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5 ); //测量放大器输出信号 PA0->UO_2 扫描 /******************** ADC3 *****************/ ADC_DMACmd(ADC3,ENABLE);//开启ADC3的DMA ADC_Cmd(ADC3, ENABLE); //使能指定ADC3 ADC_ResetCalibration(ADC3); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC3)); //等待复位校准结束 ADC_StartCalibration(ADC3); //开启AD校准 while(ADC_GetCalibrationStatus(ADC3)); //等待校准结束 ADC_SoftwareStartConvCmd(ADC3,ENABLE);//软件开启ADC3转换 ADC_DMA_Init(); } 程程序中一共需要测量5路信号,其中ADC1测量4路信号,ADC3测量1路信号,两个ADC都工作在独立模式下。 ADC1配置为多通道、多次转换、数据右对齐、软件触发转换,调用ADC_RegularChannelConfig函数配置4个通道。然后 开启ADC1的DMA,配置为循环模式,16位数据,传输量为4,不开启中断,这样配置后缓存数组的的4个值依次就是 ADC_RegularChannelConfig函数配置的通道顺序,所对应的AD转换值最新值。使用TIM2中断进行数据采样,中断中只需要 读取缓存数组中的对应元素值即可,TIM2工作在32k的频率下,1k的信号可以采集32个点做均方根计算。——定时器触发 ADC采样 ADC3配置为单通道、多次转换、数据右对齐、软件触发转换,调用ADC_RegularChannelConfig函数配置1个通 道,ADC3_Channel_0上的信号和ADC1_Channel_12的信号是相同的,都是Uo_1信号,ADC1_Channel_12只在信号频率不 超过1k时进行均方根计算时使用。ADC3_Channel_0通道则是进行扫描法,专门用来测量截止频率的,信号频率大于1k时使 用。由于ADC3_Channel_0完成单次转换需要(12.5+1.5)/12M=1.167us,所以要保证1kHz下的信号可以完成一个周期的测 量,DMA的传输数据量必须大于(1000/1.167=857)。最后ADC3的DMA配置为单次模式,传输量设置为2000,开启传输完 成中断。 200k频率下周期为5us,5us和76us\frac{7}{6}us67​us的最小公倍数为35us,也就是转换30次即可得到一组最值,所以 2000次的转换中可以得到多组波形信号的最值,将最值做差即可得到信号的峰峰值。——高频信号测量原理 这这篇博客对程序流程等进行了整体分析,之后的博客会对程序进行更为具体细致的分析,主要是测量、判断和校准部分的 分析。
作者:绿茶与白茶
分享到:
收藏