找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9882|回复: 3
打印 上一主题 下一主题
收起左侧

2018年TI杯电流信号检测装置STM32代码,电路原理图和文档

  [复制链接]
跳转到指定楼层
楼主
这是2018年TI杯电流信号检测装置一等奖作品,有原理图,源代码资料
主控是STM32F103ZET6
原理图是用AD画的。

摘要:设计并制作了一种电流信号检测装置,系统主要由功率放大电路,电流传感、检测及调理电路,由ARM单片机为核心的数据采集、参数测量以及显示电路组成。功率放大电路以TDA2030为核心搭成电压增益为1的电流放大电路,驱动10Ω负载产生10mA~1A的电流,使用漆包线绕制成的线圈作为电流传感器感应电流信号,使用INA2134OP07构成信号调理电路,将感应到的微弱信号变为易于单片机采集和处理的电压信号,由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 不同频率下的电流峰峰值
频率
50Hz
500Hz
1kHz
电流峰峰值
1.152A
1.149A
1.155A
结论:满足竞赛题目要求,输出电流峰峰值大于1A
(2)控制输入信号的幅度不变,改变频率测量。分别设置输入信号幅度峰峰值为100mA、5V、10V,改变频率进行测量。测试结果如表5.2、5.3、5.4所示。



单片机源程序如下:
  1. /**
  2.         ADC + DMA + 定时器
  3.         定时器触发ADC转换。
  4.         采样出来的点进行 FFT 分析。
  5.         
  6.   ******************************************************************************
  7. **/

  8. #include "stm32f10x.h"  
  9. #include "sys.h"
  10. #include "_SysTick.h"

  11. #include "_Usart.h"
  12. #include "lcd.h"
  13. #include "./key/bsp_key.h"
  14. #include "_Led.h"

  15. #include "_ADC.h"

  16. #include "math.h"
  17. #include "arm_math.h"  

  18. #define FFT_LENGTH                4096                 //FFT长度,默认是1024点FFT

  19. float FFT_PARAMETERS(float * pSrc,u16 numSamples);

  20. float fft_inputbuf[FFT_LENGTH*2];        //FFT输入数组
  21. float fft_outputbuf[FFT_LENGTH];        //FFT输出数组
  22. float MAX_AMP = 0;
  23. u16   base_fre = 0;
  24. float          harmonic_waves[20] = {0};//前20次谐波的幅度存储

  25.         arm_cfft_radix4_instance_f32 scfft;        //


  26. ///===============================================================================================        

  27. ///* Private variables ---------------------------------------------------------*/
  28. ///
  29. extern uint8_t _DisplayTemp[60];        //存放 需要屏幕显示的 字符串
  30. ///
  31. uint8_t dis_temp=0;        //默认0, 按键1切换1,显示频谱
  32. //float mode_temp = 2.96;//测试模式,默认,串联电流表检测,系数是2.96。 按键2切换1,并联测电压检测
  33. float mode_temp = 1;//2.965;//修正系数,默认,2.965并联测电压检测.串联电流表检测。 按键2切换1,

  34.         uint8_t k=0;
  35. //uint8_t _Flag_DMA_IT=0;

  36. extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];// ADC1转换的电压值通过DMA方式传到SRAM
  37. //float ADC_ConvertedValueLocal[NOFCHANEL];  // 局部变量,用于保存转换计算后的电压值
  38. ///

  39. /* Private function prototypes -----------------------------------------------*/

  40. void _ADC_Process1(void);//ADC处理
  41. //显示各频点的柱条
  42. void dsp_column(void);
  43. void display(void);
  44. ///===============================================================================================


  45. ///===============================================================================================
  46. int main(void)
  47. {
  48. ///====== 变量 =====================
  49.         
  50.         
  51. ///====== 初始化 ===================
  52.         SysTick_Init();/* 配置SysTick 为1us中断一次 */
  53.         USART_Config();//初始化串口1
  54.                
  55.         LED_GPIO_Config();
  56.         Key_GPIO_Config();
  57.         LCD_Init();
  58.                
  59.         ADCx_Init();                        //开了ADC1,4个通道。通道10~13对PC0~3。        
  60.         _TIM3_Config();

  61. ///===============================================================================================        
  62.         POINT_COLOR = BLACK;
  63.         //LCD_ShowString(8,8,240,300,16,"Measuring System");
  64.         
  65.         
  66.         
  67.         while(1)
  68.         {
  69.   #if 1 ///// 引脚 PC0 , ADC1, ADC_Channel_10
  70. DMA_Cmd( DMA1_Channel1 , ENABLE);
  71. TIM_Cmd( TIM3, ENABLE);
  72.                
  73.                 if( Key_Scan( KEY1_GPIO_PORT ,KEY1_GPIO_PIN) == KEY_ON )
  74.                 {
  75.                         dis_temp = !dis_temp;        //默认0, 按键1切换1,显示频谱
  76.                         LCD_Clear( WHITE);         //清屏
  77.                         LCD_Display_Dir( dis_temp);                //设置屏幕显示方向
  78.                 }
  79.         ///~~~~~~~~~~~~////
  80.                 if( Key_Scan( KEY2_GPIO_PORT ,KEY2_GPIO_PIN) == KEY_ON )
  81.                 {
  82.                         mode_temp = 2.96;        //  按键2切换1,2.96串联电流表检测。默认,2.965并联测电压检测,系数.。
  83.                         LED1_0;
  84.                 }        
  85.                
  86.                 ///////// 按下KEY4.切换到另一组模块
  87.                         /*检测是否有按键按下 */
  88.         if(GPIO_ReadInputDataBit(KEY4_GPIO_PORT,KEY4_GPIO_PIN) == 1 )  
  89.         {
  90.                 /*等待按键释放 */
  91.                 while(GPIO_ReadInputDataBit(KEY4_GPIO_PORT,KEY4_GPIO_PIN) == 1 )  ;   
  92.                         mode_temp = 1.478;        // 默认,并联测电压检测,系数。 按键2切换1,串联电流表检测
  93.                         LED1_0;LED2_0;
  94.         }
  95.         
  96.                
  97.                 if( Key_Scan( KEY3_GPIO_PORT ,KEY3_GPIO_PIN) == KEY_ON )
  98.                 {
  99.                         mode_temp = 1.414;        //按键3切换,串联电流表检测。。 默认,并联测电压检测,系数2.96.。
  100.                         LED1_1;
  101.                 }        
  102. #endif
  103. /////                        
  104.         
  105.         }
  106. }
  107.         ////////////////////////////////////////////////////////////
  108. void  DMA1_Channel1_IRQHandler (void)
  109. {
  110.     u16 i ;
  111.         
  112.         DMA_ClearITPendingBit( DMA1_IT_TC1);
  113.         TIM_Cmd( TIM3, DISABLE);        
  114.         DMA_Cmd( DMA1_Channel1 , DISABLE);

  115.         TIM_SetCounter(TIM3,0);
  116.         

  117. arm_cfft_radix4_init_f32( &scfft,FFT_LENGTH,0,1 );//初始化scfft结构体,设定FFT相关参数
  118.         
  119. for( i=0;i<FFT_LENGTH;i++)//
  120. {
  121. fft_inputbuf[2*i]=ADC_ConvertedValue[i]*3.3/4096;//
  122. fft_inputbuf[2*i+1] = 0;
  123. }   

  124. arm_cfft_radix4_f32( &scfft, fft_inputbuf);        //FFT计算(基4)        
  125. arm_cmplx_mag_f32( fft_inputbuf, fft_outputbuf, FFT_LENGTH);        //把运算结果复数求模得幅值

  126. FFT_PARAMETERS( fft_outputbuf, FFT_LENGTH);        //FFT_LENGTH                4096                 //FFT长度,默认是1024点FFT

  127. //////////////////////////

  128. ////////////
  129. if(dis_temp)//默认0, 按键1切换1,显示频谱
  130.         
  131.         dsp_column();//显示柱条。

  132. else
  133.         display        ();//显示
  134.         
  135. }
  136. ////====================================================///
  137. float FFT_PARAMETERS(float * pSrc,u16 numSamples)
  138. {
  139.         u16 i;
  140.         float temp_MAX=0;
  141.         u16   temp_FRE=0;
  142.         pSrc[0] = 0;
  143.         for(i=0;i<numSamples/2;i++)
  144.         {
  145.         //        printf("test[%d]:%f\r\n",i,pSrc[i]);
  146.                 temp_MAX = 0;
  147.                 if (pSrc[i]>pSrc[temp_FRE])
  148.                 {
  149. //                        temp_MAX = pSrc[i];
  150.                         temp_FRE = i;        
  151.                 }        
  152. //                else
  153. //                {
  154. //                        temp_MAX = temp_MAX;
  155. //                        temp_FRE = temp_FRE;
  156. //                }
  157.         }
  158.         MAX_AMP = temp_MAX;
  159.         base_fre = temp_FRE;
  160.         for(i=0;i<20;i++)
  161.         {
  162.                 if(temp_FRE*(i+1)<=1000)
  163.                 harmonic_waves[i]=pSrc[temp_FRE*(i+1)]/2048*1.02;
  164.                 else
  165.                 {        //k++;        
  166.                         harmonic_waves[i] = 10101;
  167.                 }
  168.         }
  169.         return 0 ;
  170. }/////
  171. //////////////////////////////////////////////
  172. //显示        V单位
  173. #if 0
  174. void display(void)
  175. {
  176.         uint8_t i;
  177.         
  178. //谐波振幅
  179. for(i=0;i<20;i++)
  180. {
  181.         if( harmonic_waves[i] == 10101 )        //超过题目要求的1k范围的 不显示
  182.         {
  183. //        printf("harmonic_waves[%d]:%c\r\n",i,'-');
  184.         
  185.         //sprintf((char*)_DisplayTemp," fre(%2d)_V =  --       ", i+1 );//将信息打印到_DisplayTemp地址空间里。
  186.         LCD_ShowString(56,40+13*i,240,24,12,"                     ");//显示
  187.         //        k--;
  188.         }
  189.         else
  190.         {
  191. //        printf("harmonic_waves[%d]:%f\r\n",i,harmonic_waves[i]/2.8);
  192.         
  193.         sprintf((char*)_DisplayTemp," f(%2d) I =%f mA   ", i+1 , harmonic_waves[i]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
  194.         LCD_ShowString( 56,40+13*i,240,24,12,_DisplayTemp);//显示
  195.         }
  196. }        
  197. //printf("base_fre:%d\r\n",base_fre);
  198. //printf("Ipp=%f A \r\n", 2*harmonic_waves[0]/2.8 );
  199. //频率
  200.         sprintf((char*)_DisplayTemp," Fre = %d Hz     ", base_fre );//将信息打印到_DisplayTemp地址空间里。
  201.         LCD_ShowString(26,16,240,24,12,_DisplayTemp);//显示
  202. //基波
  203.         sprintf((char*)_DisplayTemp," Ipp = %f mA   ", 2 * harmonic_waves[0]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
  204.         LCD_ShowString(116,16,240,24,12,_DisplayTemp);//显示
  205.         
  206. }
  207. #endif
  208. //显示        mV单位
  209. #if 1
  210. void display(void)
  211. {
  212.         uint8_t i;
  213.         
  214. //谐波振幅
  215. for(i=0;i<20;i++)
  216. {
  217.         if( harmonic_waves[i] == 10101 )        //超过题目要求的1k范围的 不显示
  218.         {
  219. //        printf("harmonic_waves[%d]:%c\r\n",i,'-');
  220.         
  221.         //sprintf((char*)_DisplayTemp," fre(%2d)_V =  --       ", i+1 );//将信息打印到_DisplayTemp地址空间里。
  222.         LCD_ShowString(56,40+13*i,240,24,12,"                     ");//显示
  223.         //        k--;
  224.         }
  225.         else
  226.         {
  227. //        printf("harmonic_waves[%d]:%f\r\n",i,harmonic_waves[i]/2.8);
  228.         
  229.         sprintf((char*)_DisplayTemp," f(%2d) I =%7.3f mA   ", i+1 , harmonic_waves[i]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
  230.         LCD_ShowString( 56,40+13*i,240,24,12,_DisplayTemp);//显示
  231.         }
  232. }        
  233. //printf("base_fre:%d\r\n",base_fre);
  234. //printf("Ipp=%f A \r\n", 2*harmonic_waves[0]/2.8 );
  235. //频率
  236.         sprintf((char*)_DisplayTemp," Fre = %d Hz     ", base_fre );//将信息打印到_DisplayTemp地址空间里。
  237.         LCD_ShowString(26,16,240,24,12,_DisplayTemp);//显示
  238. //基波
  239.         sprintf((char*)_DisplayTemp," Ipp = %.3f mA   ", 2 * harmonic_waves[0]*1000/ mode_temp );//将信息打印到_DisplayTemp地址空间里。
  240.         LCD_ShowString(116,16,240,24,12,_DisplayTemp);//显示
  241.         
  242. }
  243. #endif
  244. //显示各频点的柱条
  245. void dsp_column(void)
  246. {
  247.    uint16_t i,j=0,m;
  248. //        
  249.         LCD_Clear( WHITE);         //清屏
  250. //        LCD_Display_Dir(1);                //设置屏幕显示方向
  251.         
  252.         // LCD_Fill(0,228,320,240, WHITE );//填充指定颜色
  253.          for(i=0;i<20;i++)
  254.            {
  255.                 LCD_Fill(3+j, 228 - (uint16_t)(harmonic_waves[i]*90),12+j, 228 , BRRED );
  256.                 LCD_ShowxNum(2+j,228, i+1 ,2, 12,0); //显示一个数字
  257.                 if( harmonic_waves[i] != 10101 )        
  258.                 {               
  259.                 sprintf((char*)_DisplayTemp,"%d", (uint16_t)(harmonic_waves[i]*1000/ mode_temp) );//将信息打印到_DisplayTemp地址空间里。
  260.                 LCD_ShowString( 2+j, 216 - (uint16_t)(harmonic_waves[i]*90),240,24,12,_DisplayTemp);//显示
  261.                         j=j+16;
  262.                 }
  263.                 }
  264.                 LCD_ShowString( 2, 0 ,240,24,12,"Ip/mV");//显示
  265.                
  266. }


  267.         /////////////
  268. /*********************************************END OF FILE**********************/
复制代码

所有资料51hei提供下载:
2018年电赛电流信号检测装置.rar (2.39 MB, 下载次数: 233)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:593339 发表于 2019-8-1 21:07 来自手机 | 只看该作者
请问那个差分电路的两个输入和线圈接的时候有正负的区分吗?
回复

使用道具 举报

板凳
ID:623802 发表于 2019-10-15 20:00 | 只看该作者
楼主能不能留下联系方式,有问题需要了解
回复

使用道具 举报

地板
ID:635648 发表于 2020-2-6 18:25 | 只看该作者
楼主还在么,看到的话方便留个联系方式吗,有问题请教
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表