基于stm32的示波器.docx

上传人:b****5 文档编号:7505044 上传时间:2023-01-24 格式:DOCX 页数:15 大小:420.36KB
下载 相关 举报
基于stm32的示波器.docx_第1页
第1页 / 共15页
基于stm32的示波器.docx_第2页
第2页 / 共15页
基于stm32的示波器.docx_第3页
第3页 / 共15页
基于stm32的示波器.docx_第4页
第4页 / 共15页
基于stm32的示波器.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

基于stm32的示波器.docx

《基于stm32的示波器.docx》由会员分享,可在线阅读,更多相关《基于stm32的示波器.docx(15页珍藏版)》请在冰豆网上搜索。

基于stm32的示波器.docx

基于stm32的示波器

 做一个数字采样示波器一直是我长久以来的愿望,不过毕竟这个目标难度比较大,涉及的方面实在太多,模拟前端电路、高速ADC、单片机、CPLD/FPGA、通讯、上位机程序、数据处理等等,不是一下子就能成的,慢慢一步步来呗,呵呵,好歹有个目标,一直在学习各方面的知识,也有动力:

) 

   由于高速ADC涉及到采样后的数据存储问题,大量的数据涌入使得单片机无法承受,因此通常需要用外部高速RAM加CPLD配合,或者干脆用大容量的FPGA做数据存储处理等,然后通知单片机将数据发送出去。

这部分实在是难度比较大,电路非常复杂,自己是有心无力啊,还得慢慢地技术积累。

 

    正好ST新推出市场的以CORTEX-M3为核心的STM32,内部集成了2个1Msps12bit的独立ADC,并且内部高达72MHZ的主频,高达1.25DMIPS/MHZ的处理速度,高速的DMA传输功能,灵活强大的4个TIMER等等,这些真是非常有吸引力,何不用它来实现一个低频的数字示波器功能呢,我的目标是暂时只要定量定性地分析20KHZ以下的低频信号就行了,目标不高吧,用STM32可以方便地实现,等有了一定经验之后慢慢再用FPGA和高速ADC搞个100Msps采样的示波器!

 

1、ADC转换:

STM32增强型芯片内置的2个独立ADC,可以有16个通道,并且2个通道可以并行的同步采样,触发方式很灵活,可以通过TIMER以及外部电平等方式触发,并行方式下ADC2自动同步于ADC1;ADC在最高速采样的时候需要1.5+12.5个ADC周期,在14M的ADC时钟下达到1Msps的速度,因为我主频是72M所以4分频后稍微高了点,18MHZ的ADC时钟,采样速度应该高于1M了。

ADC采样2路同时采样方式,用TIM2CC2来生成时钟信号触发ADC来实现指定频率的采样。

ADC1/ADC2采样的结果是一个word 

2、采样频率控制:

由于STM32内部的4个TIMER非常强大,每个TIMER又有4个通道,再加上独立的预分配器,实际上可以实现任意分频,因此用TIM2CC2来产生指定频率的时钟,用来触发ADC1连续采样。

 

3、采样数据传输及每次采样深度控制:

ADC产生的转换数据通过高速DMA通道1来传输置指定的内部RAM中,并且将DMA通道一设置成最高优先级,以保证数据准确,并且用DMA每次传输的个数来控制采样的深度,例如我要采集100个点那么就设置DMA传输100个次,每次从32位ADC转换寄存器传输一个word到RAM中,等完成了100次传输后,DMA通道自动停止(实际上ADC是一直按照要求的采样频率连续在后台采样,只是我去取数据而已),下次采集的时候我只要再设置下采样的个数使能DMACHANNEL1就行了。

 

4、与上位机通讯:

通讯也是个难题,要达到快速地将大量数据发给上位机的目的,传输的速率肯定低不了,开始我想先用串口,不过很快就放弃了,一则即使我用外部USB转串口的芯片最高也只能达到1M的速度,并且数据会丢失;后来还是采用了网络传输的方式,用SPI接口的ENC28J60芯片,这个芯片我在MEGA32和AT91SAM7S64上都用过,接口简单挺方便的,速度还可以,在SAM7S64上DMA凡是用UDP协议单向发送的速度可以达到400KB/S以上,这次用了STM32发现速度大增,经过我用STM32的DMA传输后,同样UDP协议单向发速度竟然达到了500KB/S以上,甚至最高可以达到600KB/S,这个真是意外的收获。

 

5、上位机程序:

还是用VS2005,我还是喜欢用C#,主要是微软的C#做得是在太舒服了,编辑器智能化程度真高,缺点就是程序执行时候CPU利用率要高点,。

波形显示还是用NI的measurementStudio8来实现,一个是漂亮方便,另外最要紧的就是MeasurementStudio8里面有一大堆数据处理的库,从简单的波形有效值计算,频率计算,到各种各样的函数滤波器功能,还有FFT频域分析,时域分析等等,但凡要用到的仪器相关处理里面都有,另外本来我打算要在模拟前端里面加一个相位锁定的电路,以固定显示的波形起点,后来发现MeasurementStudio8里面有个PeakDetector的类,用这个来实现波形的锁定连这个电路都可以省了。

用MeasurementStudio8来实现实在是非常方便,并且准确。

只是我没啥资料,还在探索当中

 

 

 

 

 

ENC28J60网络子卡以及自己DIY的信号发生器照片,下面的绿板子是STM32的评估板

 

 

 

   数据采样后输出到PC上显示的图形很精确,包括MAX038产生的正弦波上部的小尖峰也很清楚,STM32的ADC精度很稳定性相当好,对于音频范围的低频信号来说,1Msps的采样也基本够用了。

只要采集足够的点送给measurementsudio提供的函数来分析,可以达到非常精确的程度,12BIT的分辨率相当于数字表的3位半的效果,用来测试信号的频率、真有效值、峰值、峰峰值等等非常方便和精确,和我用硬件实现的频率计和真有效值的读数相同(这也说明了我做的信号发生器的硬件是准确的,哈哈,之前跟数字表总对不上,看来是数字表准确度差),实现完全可以当作低频示波器来用,再加上个模拟前端电路,完全可以实用化了

 

上位机的程序还处在对于measuremenStudio的摸索当中,只是初步了解到了几个函数,用它来实现数据处理实在是方便,look 

publicvoidDataReceived_Proc()//UDP数据接收、数据处理、数据显示函数 

        { 

             

            try 

            { 

                while(bStates) 

                { 

                     

                    myudpcomm.Receive(refCommReceiveBuffer); 

                    Received_Command=Bytes2Struct(refCommReceiveBuffer); 

                    //textBox3.Text=Received_Command.SampleRate.ToString()+(acEstimate++).ToString(); 

                    dADC1_Result=newdouble[Received_Command.SampleDepth]; 

                    dADC2_Result=newdouble[Received_Command.SampleDepth]; 

                    //数据处理,将通讯接收区中的ADC数据传入绘图用数组中 

                    for(inti=0;i<(int)(Received_Command.SampleDepth);i++) 

                    { 

                        dADC1_Result[i]=(BitConverter.ToUInt16(CommReceiveBuffer,40+4*(i+0)))*(3.3/4096.0); 

                        dADC2_Result[i]=(BitConverter.ToUInt16(CommReceiveBuffer,40+4*(i+0)+2))*(3.3/4096.0); 

                    } 

                    str="通道A(绿色)\r\n"; 

                    //测试真有效值 

                    Measurements.ACDCEstimator(dADC1_Result,outacEstimate,outdcEstimate);//交流(AC方式相当于信号通过一个电容隔直后进行测量)和直流(DC直通方式进行测量)真有效值测量 

                    str+="AC方式有效值:

"+((int)(acEstimate*1000)).ToString()+"mV   "+"DC方式有效值"+((int)(dcEstimate*1000)).ToString()+"mV\r\n";  

                    //测试信号频率、振幅Vp 

                    mySingleToneInformationADC1=newSingleToneInformation(dADC1_Result,Received_Command.SampleRate); 

                    str+="频率:

"+((int)(acEstimate*1000)==0?

0:

(int)mySingleToneInformationADC1.Frequency).ToString()+"Hz   "+"振幅Vp:

"+((int)mySingleToneInformationADC1.Amplitude*1000).ToString()+"mV\r\n"; 

                    str+="\r\n通道B(红色)\r\n"; 

                    //测试真有效值 

                    Measurements.ACDCEstimator(dADC2_Result,outacEstimate,outdcEstimate);//交流(AC方式相当于信号通过一个电容隔直后进行测量)和直流(DC直通方式进行测量)真有效值测量 

                    str+="AC方式有效值:

"+((int)(acEstimate*1000)).ToString()+"mV   "+"DC方式有效值"+((int)(dcEstimate*1000)).ToString()+"mV\r\n";  

                    //测试信号频率、振幅Vp 

                    mySingleToneInformationADC2=newSingleToneInformation(dADC2_Result,Received_Command.SampleRate); 

                    str+="频率:

"+((int)(acEstimate*1000)==0?

0:

(int)mySingleToneInformationADC1.Frequency).ToString()+"Hz   "+"振幅Vp:

"+((int)mySingleToneInformationADC1.Amplitude*1000).ToString()+"mV\r\n"; 

                    textBox3.Text=str; 

                     

                    //ThresholdPeakDetector.Analyze用来找出从波谷到波峰上升沿顶点的数组序号 

                    //可以用于固定显示波形从上升沿的某固定点开始,相当与硬件的同步触发电路功能 

                    //b=ThresholdPeakDetector.Analyze(dADC2_Result,2,10); 

                    //foreach(intkinb) 

                    //{ 

                    //    textBox3.Text+=k.ToString()+""; 

                    //} 

                    //for(inti=0;i

                    { 

                        //dADC1_Result[i]=dADC2_Result[i+b[1]]; 

                    } 

                    //textBox3.Text+=b[b.Length-1].ToString(); 

                    //bIsUdpDataReceived=true;  //表示接收到了UDP数据,允许进行再次发送 

                    bIsDataReadyForPlot=true; 

                    myGraphPlotProc();   //绘图输出*/ 

                    //myD1=newmyMethodDelegate(h); 

                    //myD1

(1); 

                } 

            } 

            catch(Exceptione1) 

            { 

                timer1.Enabled=false; 

                MessageBox.Show(e1.ToString()); 

            } 

            finally 

            { 

                timer1.Enabled=false; 

            } 

        } 

        /************************************************************************************ 

         *绘图输出过程函数供,mygGraphPlotThread进程调用 

         *始终循环检测bIsDataReadyForPlot,一旦为真则进行绘图,绘图完成后置标志为false 

         ***********************************************************************************/ 

        publicvoidmyGraphPlotProc()   //绘图输出函数 

        { 

            //while(true) 

            { 

                if(bIsDataReadyForPlot) 

                { 

                    waveformPlot1.PlotY(dADC1_Result); 

                    waveformPlot2.PlotY(dADC2_Result); 

                    bIsDataReadyForPlot=false; 

                } 

            } 

        }

 

下面是下位机的程序

 

主要问题还是在传输上的,这次为了一次传输比较多的数据,要将UDP数据包分解,分成多个小于1518字节的帧发送,因此发现当数据发送快的时候很容易导致数据停止发送,以前用MEGA32和SAM7的时候没注意过,当时的处理速度也慢,没暴露出来,想来想去可能是由于连续发送的时候速度太快导致的冲突,ENC28J60出错挂起了,还是ENC28J60没有吃透,对于里面的流控、以太网冲突检测这些还需要进一步研究。

 

/********************(C)COPYRIGHT2007STMicroelectronics******************** 

*STM32F10XXX双通道ADC数据采集并通过ENC28J60实现UDP通讯传输 

*作者:

alien2006  

*环境:

keilforarmmdk3.15b  

*版本:

V0.2 

*时间:

20071202 

*说明:

V0.2 

*一、网络通讯部分 

*                        1、先采用STM32SPI轮询方式进行传输试验,ping192.168.1.100-l1400-n10 

*                                 在轮询方式下未改进SPI1_SendByte()函数(内部直接用ST提供的函数语句)需avg="9ms时间" 

*                                 轮询方式下将SPI1_SendByte()函数中的4条语句修改为直接寄存器存取后avg提高到7ms 

*                                 轮询方式下取消SPI1_SendByte()直接代之以函数中四语句avg提高到6ms 

*                                 经过上述的逐步修改,传输UDP1400个字符时双向传输(接收1400个字节再发送这1400个字节)间隔4MS可达210KB/S 

*                        2、enc28j60.c修改增加STM32SPI传输DMA和非DMA编译选项,DMA方式下网络最大传输速度测试达到350KB/S 

*     3、改进了ZYP_UDP.C实现了当要发送的UDP数据长度超过单帧所能容纳时,将UDP数据 

*                                 自动进行分组,并可在编译时自定义每个分组长度; 

*                                 改进了ENC28J60.C加入了ENC28J60DMA空闲和网络发送完毕的判断,解决了当发送速度过快时导 

*                                 致传输出错问题。

测试单向发送速度超过500KB/S; 

*二、STM32数据采集部分 

*                        1、ADC1/ADC2实现并行同时数据采集,12BIT最高可达1MSPS采样速度并通过STM32的DMA传输放入内存中 

*                        2、TIM2CC2实现对ADC采样的触发,ADC_Sample_Frequency_Set函数实现自定义TIM2OC2频率输出, 

*                        3、采样的频率和采样个数通过接收到的UDP控制命令来指定 

*                           采样的频率为20HZ~1MHZ;  

*                           采样深度为1~4000个数据(受限于STM32内存20KB容量,一个数据为2个12bitADC通道读数,需一个word) 

*                        4、定义了简单的UDP控制命令结构,用于实现与PC通讯和控制采样频率和采样深度 

*三、其他 

*     1、程序待解决问题:

UDP分组发送出错问题未完全解决,有待进一步解决 

*                        2、期待增加模拟前端电路,并实现放大倍数程控,通过上位机程序可以设置 

*V0.1:

最初程序,实现简单固定频率和深度的并行ADC采样和UDP通讯,并编制了简单的上位机程序, 

*                                可以进行采样波形的显示     

*******************************************************************************/ 

/*******************************************************************************

*FunctionName  :

DMA_ADC_Transfer_Reset

*Description    :

ADC1/ADC2DMA传输通道复位,准备下一次DMA传输

*Input          :

None                  

*Output         :

None

*Return         :

None

*******************************************************************************/

voidDMA_ADC_Transfer_Reset(void)

{

    //开始DMA传输

    //以下5句是采用函数方式共耗时多达百多个周期

    //DMA_Cmd(DMA_Channel1,DISABLE);//先要禁止DMA_ChannelX,才能修改DMA通道X传输数量寄存器DMA_CNDTRx  

  //DMA_ClearFlag(DMA_FLAG_GL1|DMA_FLAG_TC1|DMA_FLAG_HT1|DMA_FLAG_TE1);   

  //DMA_InitStructure.DMA_BufferSize=Transfer_ReceiveData_Buffer.InWord.SampleDepth;//重新设置要通过DMA传输数据量  

  //DMA_Init(DMA_Channel1,&DMA_InitStructure);      

     //DMA_Cmd(DMA_Channel1,ENABLE);//EnableDMAchannel1 

     

     //以下4句是采用直接写寄存器方式一共耗时24个周期

     DMA_Channel1->CCR&=~(1<<0);//禁用DMA_Channel,EN是CCR1寄存器的0位

     DMA->IFCR|=0x0000000F;//清除CHANNEL1的4个标志

     DMA_Channel1->CNDTR=(u16)Transfer_ReceiveData_Buffer.InWord.SampleDepth;//重新设置要设置的DMA传输数据量

     DMA_Channel1->CCR|=(1<<0);//重新使能DMA_channel1

     while(!

(DMA->ISR&DMA_FLA

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1