基于STC单片机虚拟示波器的设计Word文档下载推荐.docx
《基于STC单片机虚拟示波器的设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于STC单片机虚拟示波器的设计Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
故需将单片机的两个口(P0、P2)分别与AD7862的DB0-DB11相连,即可完成数据的采集。
本设计利用MAX232芯片实现RS-232电平与TTL电平转换,利用串行通信方式1将数据发给PC机,波特率为9600bit/s、无校验位;
用VC++6.0编写相应的界面进行数据处理,控制和显示。
在实验的初级阶段采用的是每采集一次模拟电压值,就直接把12位的并行数据,利用串行通信方式1直接发给上位机。
这时发现A/D7862每采样一个数据只需要4μs,单片机采用11.0592MHz的晶振,即单片机采集一次数据真正需要的时间只有十几μs,以正弦波每个周期至少20个点来表示计算,对于采集4KHz以下的正弦波是没有问题的。
而如果从串口通信的波特率来说,如采用19200bit/s来计算,则只有44Hz以下的波形能采集了。
对比之下可以看出,影响这种方案采集波形的主要瓶颈是波特率,如果在不变硬件的基础上采用其最高波特率57600bit/s的波特率传输数据,理论计的测量范围也只是0~130Hz。
在此基础上为了提高采样波形的频率范围,最后采用先采集保存再群组发送的方式,首先采集100个点,并将数字量存储在单片机的RAM中,然后群组发给上位机,这样可以大大的提高采样率,根据AD7862的时序图,还有单片机的一个机器周期大约1微秒,这样可以得出采理论上采样率大约40KHZ,要使得波形比较平滑的话,每个信号周期内至少应该采集20个点,这样算起来能采样到2KHZ的波形。
经实验采样率最大只能达到20KHZ左右,同样换算最大能采样到1KHZ左右的波形。
在下位机里采用定时器0的方式2对采样率进行设定,设定不同的采样率,就可以采样到低于1KHZ的不同频率段的波形。
由于定时的时间比较短,采用方式2比较精确,但是最大只能定时255微秒,经换算最大能采样到196HZ,经调试最小频率能采集到10HZ左右。
故采样的波形频率范围在10HZ-1000HZ。
最终利用上位机对采集的数据进行处理,画出模拟信号的波形,并显示模拟信号的电压值、最大值、最小值和峰峰值等。
三、系统工作原理
系统由电源模块、AD采样模块、STC单片机控制模块、串口通信模块、计算机处理与显示模块组成。
电源模块提供总个系统工作的电压,保证系统正常工作。
STC单片机控制AD采样电压值,并将电压值通过串口传送给上位机,上位机通过VC程序对数据进行处理和显示。
上位机通过串口发送不同的标志位给下位机,控制下位机在不同的采样率下对模拟电压值进行采样。
四、硬件电路
1、AD硬件电路设计如下。
为了使得单片机能够更有效地控制AD7852工作,在连线的时候尽可能多地把AD7862的控制端与单片机的I/O相连接,以便供以后升级使用。
DB0-DB11是A/D转换后的数字量输出端口,它们分别与单片机的P2和P0口P1.1-P1.4相连接,以便单片机把数字量读走。
CONVST是AD7862转换开始触发端口,与单片机的P0.0连接,是为了利用单片机的外部中断0来提高模拟电压信号的采样率,使得AD7862更有效的工作起来。
VA1和A2,VB1和VB2分别是模拟电压信号的四个输入通道。
当A0为低电平的时候选择VA0或VA1,当A0为高电平的时候选择VB1或VB2,此电路图中将A0接地,选择VA0或VA1.
2、PC机通过串口进行通信,电路如图所示。
单片机串口为TTL电平,PC机串口为232电平,通过MAX232与单片机和DB9连接,DB9通过USB转串口线与PC机相连,实现电平转换和下位机和上位机的通信。
3.单片机控制模块电路图如图所示,单片机的控制AD采样,要保证电容和晶振振荡器给单片机提供合适的工作频率。
4.电源模块
电源模块电路图如图所示,电源模块给系统提供5V的恒定电压,保证系统正常工作。
五、系统软件设计
1、下位机设计
下位机处理三方面的工作,一是控制AD7862采集VA1端得模拟电压信号,得到数字量,并保存到单片机内部的RAM单元;
二是是通过定时器0的方式2定不同的采样率,得出所采波形的采样周期;
三是负责与PC通信,将保存的数据发送到PC,让上位机做处理。
控制数据采集主要依据AD7862工作时序来完成。
下图即使AD7862的工作时序图
如图所示,CONVST、CS、RD、A0由单片机来控制,让AD采哪个通道、何时采集等;
BUSY与单片机的INT0管脚相连从而通过外部中断0来提高AD7862的工作效率,当CONVST下降沿一来,AD转换开始,这时两个锁存器同时锁存两个通道的模拟量,在大约3.6us之后,转换完成同时BUSY的下降沿向单片机申请外部中断0,这个时候AD7862的输出寄存器的数据是有效的,可以读取数据。
A0为0可以读A通道。
当/CS和/RD有效时,数据可以从12位的并行数据总线上读出。
下位机流程图:
yes
no
下位机程序代码如下:
#include<
reg52.h>
#include<
intrins.h>
math.h>
typedefunsignedintuint;
typedefunsignedcharuchar;
sbitconvst=P0^0;
sbitBUSY=P3^2;
sbitAD_RD1=P3^3;
sbitAD_CS=P3^4;
ucharsamplingCounter=0;
//采样计数器
ucharsamplingFlag=0;
//采样率标志位
ucharsendFlag=0;
//串口发送标志位
ucharAD_H=0,AD_L=0;
ucharidataAD_result[100][2];
voidsentda(void);
voidAD_unit(void);
voidMicfo_unit(void);
voiddelayms(uintz)
{
uinty;
for(y=z;
y>
0;
y--);
}
//==================主函数============================================
voidmain(void)
{
AD_unit();
Micfo_unit();
while
(1)
{
if(sendFlag)
{
sentda();
sendFlag=0;
}
convst=0;
//开始AD转换
while(BUSY==1);
//检测ADC忙信号线,等待AD转换完成,若完成则执行下一步
//取VA1的数值
convst=1;
AD_CS=0;
AD_RD1=0;
AD_result[samplingCounter][0]=(P0>
>
1)|0xf0;
AD_result[samplingCounter][1]=P2;
AD_RD1=1;
//记录采样次数,带采样100次后,将这100次的采样结果一次性发送给上位机。
switch(samplingFlag)//
{
//case0x06:
delayms(107);
break;
//1000us间隔采样
case0x02:
delayms(51);
//500us间隔采样307
case0x03:
delayms(15);
_nop_();
//200us间隔采样109
case0x04:
delayms(5);
break;
//100us间隔采样55
case0x05:
//52us间隔采样23
//case0x07:
//52us间隔采样
samplingCounter++;
if(samplingCounter==100)
sendFlag=1;
samplingCounter=0;
}
//===================子函数===========================================
//ADC初始化函数
voidAD_unit(void)
AD_CS=1;
voidMicfo_unit(void)//初始化串口和定时器0
SCON=0x50;
//SCON:
工作模式1,8-bitUART,允许接收
TMOD=0x20;
//TMOD:
定时器T1,工作模式2,8位自动重载方式
PCON=0x80;
TH1=0xFF;
//当波特率为57600时,定时器初值
//TL1=0xFD;
TR1=1;
//开定时器1
ES=1;
//开串行中断
EA=1;
//开总中断
//串口发送子函数,将读取到的串口数据发送给上位机
voidsentda(void)
chari,j;
for(j=0;
j<
100;
j++)
for(i=0;
i<
2;
i++)
SBUF=AD_result[j][i];
while(!
TI);
TI=0;
//===================中断服务函数===========================================
//串口接收中断服务程序,根据接收到得采样标志位,配置不同的采样率
voidser()interrupt4
{
if(RI)
RI=0;
samplingFlag=SBUF;
2.上位机设计
下位机给上位机发送数据的时候先发送12位数据的高4位,后发送12位数据的低8位,这个时候上位机要对接收到数据进行数据处理。
在编写上位机程序的时候参考了串口调试助手的源程序,此源程序完成的功能是把接收到的数字量进行转换得到模拟电压的瞬时值,以及如何利用计算机串口向STC单片机发送命令,从而控制AD7862的采样率。
PC对接收到的数据进行处理,PC读回的数据是十六进制数,要经过一系列的处理,才能得到最后的显示值。
首先要判断得到的数据对应的电压是正或是负的。
若电压是正的,即数据小于2048,则处理公式如下:
OUT=a*LSB
式中a为得到的数字量,out为显示的电压,LSB为AD最小分辨电压。
若电压为负的,即得到的数据大于等于2048,则处理公式如下:
OUT=(a-4096)*LSB
AD7862的转换结果输出是以二进制的补码表示的,当其输入电压为负时,数据处理的方法采用上面的方法,而不必还原成原码。
上位机的数据处理核心程序为:
for(CONT=0;
CONT<
Num;
CONT++)
{if((rxdata[2*CONT]&
0XF0)==0XF0)
{rxdata[2*CONT]=rxdata[2*CONT]&
0X0F;
ReceiveData[2*CONT]=rxdata[2*CONT];
ReceiveData[2*CONT+1]=rxdata[2*CONT+1];
ResultData[CONT]=ReceiveData[2*CONT]*256+
ReceiveData[2*CONT+1];
if(ResultData[CONT]>
=0x0800)
{
ResultData[CONT]=ResultData[CONT]-4096;
}
data[CONT]=float(ResultData[CONT])*20/4096;
m_result=data[CONT];
if(CONT==0||CONT==1)
{
m_max=(float)m_result;
m_min=(float)m_result;
}
if(CONT>
1)
{
if(m_max<
(float)m_result)
{
m_max=(float)m_result;
}
elseif(m_min>
(float)m_result)
m_min=(float)m_result;
m_Vpp=m_max-m_min;
此时就可以对采集的信号进行处理和分析,得到采集的电压值、最大最小值和峰峰值,并画出信号的波形图。
上位机向下位机发送命令,控制AD7862的采样率的命令为:
CStringfre1;
fre1=0x03;
m_MSCOMM1.SetOutput(COleVariant(fre1));
六、系统调试
根据方案设计的要求,调试过程共分三大部分:
硬件调试、软件调试和软硬件联调。
电路按模块调试,各模块逐个调试通过后再联调。
1、硬件调试
通过制作原理图、PCB板到做成板子将原件焊接完毕,这一过程都要保持一种认真的态度。
为了方便调试,我在硬件电路中加了液晶和开关,采用分块调试的方法。
电路由多个模块组成,AD转换电路、串口通信电路、单片机控制电路、调试电压电路。
经调试,当采集低于10v电压时,液晶上能准确显示电压值,说明硬件电路总体工作。
2、软件调试
在确定编程思路以后将各模块的程序及各子程序编好,使用Keil进行调试,根据Keil提示的错误对程序进行修改。
除了语法差错和逻辑差错外,当确认程序没问题时,用“伟福”开始调试,看其中值的变化,有错误时直接在上面修改,直到能全部通过,并用串口调试助手看结果是否正确。
最后下载到单片机进行调试,看是否能达到预期的目的。
当下位机基本设计好后,就要设计上位机的内容了,由于VC++没有接触过,所以从最简单的开始搞,主要是进行数据处理和控制并显示出来,选择好串口号,点击“打开串口”和开始采集”按钮,画出波形并显示电压“当前值”、“最大值”、“最小值”和“峰峰值”。
表示的值跟测量值基本符合。
3、软硬联调
下载程序到单片机后,利用串口调试助手首先查看是否输出空载电压和直流电压正确。
在本次设计中,通过观察发现硬件电路输出正常,但输出数据不正确,所以问题锁定在程序的问题,经过多次进行程序的修改及调试,最终系统工作正常。
七、实验结果与误差分析
将时间连续、幅值也连续的模拟量转换为时间离散、幅值也离散的数字信
号,A/D转换一般要经过取样、保持、量化及编码4个过程。
在实际电路中,这些过程有的是合并进行的,例如,取样和保持,量化和编码往往都是在转换过程中同时实现的。
将取样电路每次取得的模拟信号转换为数字信号都需要一定的时间,为了给后续的量化编码过程提供一个稳定值,每次取得的模拟信号必须通过保持电路保持一段时间。
在量化过程中,由于取样电压不一定能被量化单位整除,所以量化前后不可
避免地存在误差,此误差称之为量化误差。
量化误差属原理误差,它是无法消除
的。
A/D转换器的位数越多,各离散电平之间的差值越小,量化误差越小,分辨率也就越高。
对AD7862来说,输出位为12位,输入信号范围为-10到+10V,那AD7862能区分的输入信号的最小电压为:
20V/4096=4.883mV。
所以其最大的转换误差
为2.4415mV。
故实验中得到的测量绝对误差应低于这个值。
然而在实际的实验过程中,检测到的误差要远大于这个值,一般为10-30mV的样子。
USB电源的纹波比较大,幅值不稳定。
在芯片的电源接口部分应加上相应的滤波电容,以减小电源波动对芯片的干扰。
加入的测试信号幅度不宜过大,正常范围为-10V到+10V,最大范围为-17V到+17V,否则超过最大范围的话会烧坏AD7862芯片;
另外所加交流信号的频率由于受采集速率的限制也要控制在一定的范围之内,最好小于1KHZ,这样在上位机上显示的波形就比较好。
第一步思想是采一点发一点数据,发现采样率不高,为了提高采样率,又采用先采集100点存入数组,再往上位机发送,这样节省了每两点之间发送的时间,提高了采样率。
为了定时准确,采用了定时器0的方式2,最多只能定256微秒,又加上我的上位机界面上的画图区域不过大,导致最小只能采集10HZ的波形。
按理论值采样率可以定到20us,但实际上最大只能定到78us。
导致最大只能采到700HZ左右的波形。
定出采样率后,能采到最大频率的波是按照每一个周期至少采集20个点来计算的,实际调试过程中发现,能采到比计算值大一点点的波形。
下面各图是分别对不同频率的信号进行数据采集结果。
当选择好串口,确定好采样范围,上位机就会发相应的指令给下位机,上位机就会给下位机发送命令。
同时上位机上显示出各种参数值。
点击开始采集按钮,界面上会画出相应的波形。
对10HZ的正弦波进行采样
对50HZ的正弦波进行采样
对100HZ的正弦波进行采样
对300HZ的正弦波进行采样
对300HZ的方波进行采样
对550HZ的正弦波进行采样
对700HZ的正弦波进行采样
对700HZ的方波进行采样
八、实验心得
通过本次接口试验,我学到了很多知识,首先是A/D芯片,以前接触到的都是8位的A/D转换芯片,这次是第一次接触12位的A/D芯片。
从它的管脚到时序一点点的学,再看懂单片机是怎样对它控制控制的。
先写下位机程序,从实现简单的采集功能,再实现波特率的设置。
在做实验之前没接触过VisualC++,从通过看孙鑫老师的视频,掌握了一些基本的知识,在参考关于VC编程和串口通信编程的书籍,最终编出了上位机的界面程序,完成了一个虚拟示波器的设计和制作。
但是也还存在一些不足,比如由于定时器选用的原因和画图区域不够大,导致最小只能采集到10HZ。
为了采集更高频率的波,一方面由于单片机内部只有256字节的RAM,为增加一次采集的点数,可以接一个外部RAM芯片。
另一方面因为用11.0596MHZ的晶振,单片机的一个机器周期大约为1微秒,单片机采样一次大约要耗十几微秒,可以将晶振提高到24MHZ。
九.鸣谢
在这次试验中,在下位机和上位机的编程实现中遇到许多问题,感谢老师的指导,感谢王明飞、李清清,秦昌明等同学对我的帮助和指导。
通过与他们的交流,思路更加的清晰,让我又一次意识到交流的重要性。
同时感谢我的家人和朋友对我的经济和精神的支持!
参考文献:
[1]郭天祥.51单片机C语言教程-入门、提高、开发、拓展全攻略.北京:
电子工业出版社,2009
[2]孙鑫等.VC++深入详解.北京:
电子工业出版社,2007
[3]张筠莉等.VisualC++实践与提高--串口通信与工程应用篇.北京:
中国铁道出版社,2006
[4]龚建伟,熊光明.VisualC++/TurboC串口通信编程实践.北京:
电子工业出版社,2007
[5]李现勇.VisualC++串口通信技术与工程实践(第二版).北京:
人民邮电出版社,2004.