这是2018年TI杯电流信号检测装置一等奖作品,有原理图,源代码资料
主控是STM32F103ZET6
原理图是用AD画的。
摘要:设计并制作了一种电流信号检测装置,系统主要由功率放大电路,电流传感、检测及调理电路,由ARM单片机为核心的数据采集、参数测量以及显示电路组成。功率放大电路以TDA2030为核心搭成电压增益为1的电流放大电路,驱动10Ω负载产生10mA~1A的电流,使用漆包线绕制成的线圈作为电流传感器感应电流信号,使用INA2134和OP07构成信号调理电路,将感应到的微弱信号变为易于单片机采集和处理的电压信号,由STM32单片机采集电压信号,实现被测信号峰峰值检测、频率计算、FFT分析与显示。当该系统输入频率范围为50Hz~200Hz非正弦信号时,通过FFT算法能实现电流信号基波频率的测量,以及基波和各次谐波分量幅度的测量。 经过测量表明,作品指标全部满足竞赛题目要求。
1.任务 如图1所示,由任意波信号发生器产生的信号经功率放大电路驱动后,通过导线连接10Ω电阻负载,形成一电流环路;设计一采用非接触式传感的电流信号检测装置,检测环路电流信号的幅度及频率,并将信号的参数显示出来。 图1 电流信号检测连接图
一、方案设计与选择 系统主要由功率放大电路,电流传感、检测及调理电路,由ARM单片机为核心的数据采集、参数测量以及显示电路组成 1.电流传感方案选择 方案一:使用集成电流传感器件。集成电流传感器,使用方便,测量结果准确,但是它的缺点是线圈的匝数固定不变,不能根据自己实际电路和测量要求来改变线圈匝数。 方案二:漆包线手工绕制电流传感器。采用漆包线手工绕制电流传感器。可根据自己的需求,改变磁芯材质、漆包线粗细和线圈的绕制匝数,来适应测量电路,满足测量要求。绕制简单,易于实现。 综上所述,本次系统设计选用方案二。 2.功率放大电路的论证与选择 方案一:使用分立器件制作功率放大电路。功率管用大功率三极管。使用分立器件制作的功率放大电路,静态电流大,非线性失真小,管耗大,且效率低。用该电路作为前级功率放大电路输出的电流峰峰值远远大于1A,但是输入方波时有些谐波会丢失,导致经过功放后输出的方波波形有点失真。 方案二:TDA2030芯片。TDA2030是一款单芯片音频功率放大器集成电路,具有高电流输出和高工作电压,低谐波和交越失真等特点。该电路输出的电流能满足题目要求,并且非线性失真小,即使输入方波,三角波也不会丢失谐波分量。 综上所述,本次系统设计选用方案二。 3.差动放大器的论证与选择 方案一:选择INA217仪表放大器将差分电流信号转化为单端输出电流信号,该芯片具有低噪声,低失真,高带宽等特点,但是检测小电流信号时,检测的波形有些失真。 方案二:AD620芯片。选择AD620仪表放大器将差分电流信号转化为单端输出电流信号,AD620是低功耗仪表放大器,该芯片具有低功耗,低噪音,直流性能出色等特点,但是检测微弱信号时会出现噪声干扰,波形出现的毛刺多,单片机很难检测。 方案三:INA2134芯片。该INA2134是一个差分线路接收机组成的高性能运算放大器,具有片上精密电阻器,低失真和高的转换速率。该电路能够检测出50Hz~1kHz,100mV~10V的正弦波和50Hz~200Hz的方波,并且波形不失真,噪声好。 综上所述,本次系统设计选用方案三。 4.后级运算放大器的论证与选择 方案一:LM358双差分输入运算放大器作为微弱信号放大,该芯片的低频特性很好但是高频特性差,由于有偏置电流所以输出的波形不是很好,并且最后给单片机的信号是正的,所以需要把信号往上偏置到正半轴,但是LM358的失调电压大,所以这里不选择LM358。 方案二:OP07芯片是一种低噪声,非斩波稳零的双极性运算放大器集成电路。由于OP07具有非常低的失调电压,所以OP07不需要额外的调零措施,OP07同时具有输入偏置电流低和开环增益高的特点,这种低失调,高增益的特性使得OP07在检测小信号时效果出色。 综上所述,本次系统设计选用方案二。
二、系统结构论述与框图 系统主要由功率放大电路,电流传感、检测及调理电路,由ARM单片机为核心的数据采集、参数测量以及显示电路组成。系统总体框图如图2.1所示。 由任意波形发生器提供所需信号,输入到功率放大电路进行功率放大,放大后的信号经过10Ω负载转化为电流信号,该电流信号以非接触的方式,通过磁耦合在由漆包线绕制的线圈两侧产生感应电流。由于感应电流信号非常微弱,需经过信号调理电路,将微弱信号变为单片机可识别检测的信号,进行采集。单片机采集到数据之后,进行FFT计算,对数据进行处理,并将处理后的数据显示到屏幕上。
图2.1 系统结构框图 三、理论分析及相关参数计算 1.功率放大器理论分析 功率放大器以TDA2030音频放大器制作,TDA2030具有体积小、输出功率大、失真小等特点。该功放可实现电流和电压的放大,根据题目要求,将电压增益设计为1。 2.电流检测分析电路的理论分析 电流检测分析电路包括差分电路、跟随器、同相放大电路、反相加法电路、反相电路和基准源电路组成。 差分电路是将从电流传感器输出的差分信号转化为单端输出信号,差分电路用INA2134芯片设计,该芯片是高性能的运算放大器,内部具有导通芯片的精密电阻。后面跟一级电压跟随器,起到前后级缓冲、隔离的作用,再经过一级放大,因此可以将微弱信号放大,便于单片机检测。反相加法器将稳压源AMS1117-1.8V输出的直流电压和放大器输出的信号相加使得信号偏置到正半轴,但因为采用反相加法,信号全部在负半轴,需要一级反相器来使信号在正半轴。 四、电路设计 1.硬件设计 1.1功率放大电路设计 功率放大电路用TDA2030芯片设计,电压放大倍数为1,设计电路图如下:
图4.1 功率放大器TDA2030电路图 1.2电流检测分析电路 电流检测分析电路大致分为三个部分,信号放大部分、稳压源部分、信号偏移部分。 信号放大部分包括差分电路、跟随电路、放大电路。差分输入端并一个100欧姆的电阻,将差分输入的电流信号转化为电压信号。经过差分电路转化为单端输出信号,再经过跟随,放大。放大倍数为电路图如下: 图4.2信号放大部分电路图
稳压源部分用固定式低压降线性稳压器AMS1117-1.8V设计,输出1.8V直流电压,电路如图: 图4.3 稳压源部分电路图
信号偏移部分由反向加法器和反向电路组成,电路如图: 图4.4 信号偏移部分电路 2.软件设计 STM32单片机对送入的非正弦信号进行AD采样,并进行FFT分析,根据分析结果即可得到被测信号的基波频率、谐波频率和幅值。主控程序的流程如图4.5所示。
图4.5 主控程序流程图
五、测试方案与测试结果 1.测试仪器 数字信号发生器:DG4062; 台式万用表:DM3058; 双踪示波器:DS2202E。 2.测试方案 分析可知,输入信号的频率、幅度都有可能影响测量结果,这两者都属于变量,故采用控制变量法进行结果测量;使用双踪示波器观察电流信号有无明显失真。 (1)当输入正弦信号频率范围为50Hz-1kHz时,测量流过10Ω负载电阻的电流峰峰值,用示波器观察系统输出波形; (2)控制输入信号的幅度不变,测量输入信号频率对测量结果的影响,并记录数据; (3)控制输入信号的频率不变,测量输入信号幅度对测量结果的影响,并记录数据; (4)信号发生器输出非正弦信号,基波频率范围为50Hz-200Hz,测量电流信号基波频率和基波及各次谐波分量的幅度,并记录数据。 3.测试数据及结果 (1)分别设置输入信号的频率为50Hz、500Hz、1kHz,测量流过10Ω负载电阻电流峰峰值,并用双踪示波器观察输出信号的波形。测试结果如表5.1所示。 表5.1 不同频率下的电流峰峰值 结论:满足竞赛题目要求,输出电流峰峰值大于1A (2)控制输入信号的幅度不变,改变频率测量。分别设置输入信号幅度峰峰值为100mA、5V、10V,改变频率进行测量。测试结果如表5.2、5.3、5.4所示。
单片机源程序如下:
- /**
- ADC + DMA + 定时器
- 定时器触发ADC转换。
- 采样出来的点进行 FFT 分析。
-
- ******************************************************************************
- **/
- #include "stm32f10x.h"
- #include "sys.h"
- #include "_SysTick.h"
- #include "_Usart.h"
- #include "lcd.h"
- #include "./key/bsp_key.h"
- #include "_Led.h"
- #include "_ADC.h"
- #include "math.h"
- #include "arm_math.h"
- #define FFT_LENGTH 4096 //FFT长度,默认是1024点FFT
- float FFT_PARAMETERS(float * pSrc,u16 numSamples);
- float fft_inputbuf[FFT_LENGTH*2]; //FFT输入数组
- float fft_outputbuf[FFT_LENGTH]; //FFT输出数组
- float MAX_AMP = 0;
- u16 base_fre = 0;
- float harmonic_waves[20] = {0};//前20次谐波的幅度存储
- arm_cfft_radix4_instance_f32 scfft; //
- ///===============================================================================================
- ///* Private variables ---------------------------------------------------------*/
- ///
- extern uint8_t _DisplayTemp[60]; //存放 需要屏幕显示的 字符串
- ///
- uint8_t dis_temp=0; //默认0, 按键1切换1,显示频谱
- //float mode_temp = 2.96;//测试模式,默认,串联电流表检测,系数是2.96。 按键2切换1,并联测电压检测
- float mode_temp = 1;//2.965;//修正系数,默认,2.965并联测电压检测.串联电流表检测。 按键2切换1,
- uint8_t k=0;
- //uint8_t _Flag_DMA_IT=0;
- extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];// ADC1转换的电压值通过DMA方式传到SRAM
- //float ADC_ConvertedValueLocal[NOFCHANEL]; // 局部变量,用于保存转换计算后的电压值
- ///
- /* Private function prototypes -----------------------------------------------*/
- void _ADC_Process1(void);//ADC处理
- //显示各频点的柱条
- void dsp_column(void);
- void display(void);
- ///===============================================================================================
- ///===============================================================================================
- int main(void)
- {
- ///====== 变量 =====================
-
-
- ///====== 初始化 ===================
- SysTick_Init();/* 配置SysTick 为1us中断一次 */
- USART_Config();//初始化串口1
-
- LED_GPIO_Config();
- Key_GPIO_Config();
- LCD_Init();
-
- ADCx_Init(); //开了ADC1,4个通道。通道10~13对PC0~3。
- _TIM3_Config();
- ///===============================================================================================
- POINT_COLOR = BLACK;
- //LCD_ShowString(8,8,240,300,16,"Measuring System");
-
-
-
- while(1)
- {
- #if 1 ///// 引脚 PC0 , ADC1, ADC_Channel_10
- DMA_Cmd( DMA1_Channel1 , ENABLE);
- TIM_Cmd( TIM3, ENABLE);
-
- if( Key_Scan( KEY1_GPIO_PORT ,KEY1_GPIO_PIN) == KEY_ON )
- {
- dis_temp = !dis_temp; //默认0, 按键1切换1,显示频谱
- LCD_Clear( WHITE); //清屏
- LCD_Display_Dir( dis_temp); //设置屏幕显示方向
- }
- ///~~~~~~~~~~~~////
- if( Key_Scan( KEY2_GPIO_PORT ,KEY2_GPIO_PIN) == KEY_ON )
- {
- mode_temp = 2.96; // 按键2切换1,2.96串联电流表检测。默认,2.965并联测电压检测,系数.。
- LED1_0;
- }
-
- ///////// 按下KEY4.切换到另一组模块
- /*检测是否有按键按下 */
- if(GPIO_ReadInputDataBit(KEY4_GPIO_PORT,KEY4_GPIO_PIN) == 1 )
- {
- /*等待按键释放 */
- while(GPIO_ReadInputDataBit(KEY4_GPIO_PORT,KEY4_GPIO_PIN) == 1 ) ;
- mode_temp = 1.478; // 默认,并联测电压检测,系数。 按键2切换1,串联电流表检测
- LED1_0;LED2_0;
- }
-
-
- if( Key_Scan( KEY3_GPIO_PORT ,KEY3_GPIO_PIN) == KEY_ON )
- {
- mode_temp = 1.414; //按键3切换,串联电流表检测。。 默认,并联测电压检测,系数2.96.。
- LED1_1;
- }
- #endif
- /////
-
- }
- }
- ////////////////////////////////////////////////////////////
- void DMA1_Channel1_IRQHandler (void)
- {
- u16 i ;
-
- DMA_ClearITPendingBit( DMA1_IT_TC1);
- TIM_Cmd( TIM3, DISABLE);
- DMA_Cmd( DMA1_Channel1 , DISABLE);
- TIM_SetCounter(TIM3,0);
-
- arm_cfft_radix4_init_f32( &scfft,FFT_LENGTH,0,1 );//初始化scfft结构体,设定FFT相关参数
-
- for( i=0;i<FFT_LENGTH;i++)//
- {
- fft_inputbuf[2*i]=ADC_ConvertedValue[i]*3.3/4096;//
- fft_inputbuf[2*i+1] = 0;
- }
- arm_cfft_radix4_f32( &scfft, fft_inputbuf); //FFT计算(基4)
- arm_cmplx_mag_f32( fft_inputbuf, fft_outputbuf, FFT_LENGTH); //把运算结果复数求模得幅值
- FFT_PARAMETERS( fft_outputbuf, FFT_LENGTH); //FFT_LENGTH 4096 //FFT长度,默认是1024点FFT
- //////////////////////////
- ////////////
- if(dis_temp)//默认0, 按键1切换1,显示频谱
-
- dsp_column();//显示柱条。
- else
- display ();//显示
-
- }
- ////====================================================///
- float FFT_PARAMETERS(float * pSrc,u16 numSamples)
- {
- u16 i;
- float temp_MAX=0;
- u16 temp_FRE=0;
- pSrc[0] = 0;
- for(i=0;i<numSamples/2;i++)
- {
- // printf("test[%d]:%f\r\n",i,pSrc[i]);
- temp_MAX = 0;
- if (pSrc[i]>pSrc[temp_FRE])
- {
- // temp_MAX = pSrc[i];
- temp_FRE = i;
- }
- // else
- // {
- // temp_MAX = temp_MAX;
- // temp_FRE = temp_FRE;
- // }
- }
- MAX_AMP = temp_MAX;
- base_fre = temp_FRE;
- for(i=0;i<20;i++)
- {
- if(temp_FRE*(i+1)<=1000)
- harmonic_waves[i]=pSrc[temp_FRE*(i+1)]/2048*1.02;
- else
- { //k++;
- harmonic_waves[i] = 10101;
- }
- }
- return 0 ;
- }/////
- //////////////////////////////////////////////
- //显示 V单位
- #if 0
- void display(void)
- {
- uint8_t i;
-
- //谐波振幅
- for(i=0;i<20;i++)
- {
- if( harmonic_waves[i] == 10101 ) //超过题目要求的1k范围的 不显示
- {
- // printf("harmonic_waves[%d]:%c\r\n",i,'-');
-
- //sprintf((char*)_DisplayTemp," fre(%2d)_V = -- ", i+1 );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString(56,40+13*i,240,24,12," ");//显示
- // k--;
- }
- else
- {
- // printf("harmonic_waves[%d]:%f\r\n",i,harmonic_waves[i]/2.8);
-
- sprintf((char*)_DisplayTemp," f(%2d) I =%f mA ", i+1 , harmonic_waves[i]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString( 56,40+13*i,240,24,12,_DisplayTemp);//显示
- }
- }
- //printf("base_fre:%d\r\n",base_fre);
- //printf("Ipp=%f A \r\n", 2*harmonic_waves[0]/2.8 );
- //频率
- sprintf((char*)_DisplayTemp," Fre = %d Hz ", base_fre );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString(26,16,240,24,12,_DisplayTemp);//显示
- //基波
- sprintf((char*)_DisplayTemp," Ipp = %f mA ", 2 * harmonic_waves[0]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString(116,16,240,24,12,_DisplayTemp);//显示
-
- }
- #endif
- //显示 mV单位
- #if 1
- void display(void)
- {
- uint8_t i;
-
- //谐波振幅
- for(i=0;i<20;i++)
- {
- if( harmonic_waves[i] == 10101 ) //超过题目要求的1k范围的 不显示
- {
- // printf("harmonic_waves[%d]:%c\r\n",i,'-');
-
- //sprintf((char*)_DisplayTemp," fre(%2d)_V = -- ", i+1 );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString(56,40+13*i,240,24,12," ");//显示
- // k--;
- }
- else
- {
- // printf("harmonic_waves[%d]:%f\r\n",i,harmonic_waves[i]/2.8);
-
- sprintf((char*)_DisplayTemp," f(%2d) I =%7.3f mA ", i+1 , harmonic_waves[i]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString( 56,40+13*i,240,24,12,_DisplayTemp);//显示
- }
- }
- //printf("base_fre:%d\r\n",base_fre);
- //printf("Ipp=%f A \r\n", 2*harmonic_waves[0]/2.8 );
- //频率
- sprintf((char*)_DisplayTemp," Fre = %d Hz ", base_fre );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString(26,16,240,24,12,_DisplayTemp);//显示
- //基波
- sprintf((char*)_DisplayTemp," Ipp = %.3f mA ", 2 * harmonic_waves[0]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString(116,16,240,24,12,_DisplayTemp);//显示
-
- }
- #endif
- //显示各频点的柱条
- void dsp_column(void)
- {
- uint16_t i,j=0,m;
- //
- LCD_Clear( WHITE); //清屏
- // LCD_Display_Dir(1); //设置屏幕显示方向
-
- // LCD_Fill(0,228,320,240, WHITE );//填充指定颜色
- for(i=0;i<20;i++)
- {
- LCD_Fill(3+j, 228 - (uint16_t)(harmonic_waves[i]*90),12+j, 228 , BRRED );
- LCD_ShowxNum(2+j,228, i+1 ,2, 12,0); //显示一个数字
- if( harmonic_waves[i] != 10101 )
- {
- sprintf((char*)_DisplayTemp,"%d", (uint16_t)(harmonic_waves[i]*1000/ mode_temp) );//将信息打印到_DisplayTemp地址空间里。
- LCD_ShowString( 2+j, 216 - (uint16_t)(harmonic_waves[i]*90),240,24,12,_DisplayTemp);//显示
- j=j+16;
- }
- }
- LCD_ShowString( 2, 0 ,240,24,12,"Ip/mV");//显示
-
- }
- /////////////
- /*********************************************END OF FILE**********************/
复制代码
所有资料51hei提供下载:
2018年电赛电流信号检测装置.rar
(2.39 MB, 下载次数: 236)
|