基于单片机正弦波有效值的测量Word格式.docx
《基于单片机正弦波有效值的测量Word格式.docx》由会员分享,可在线阅读,更多相关《基于单片机正弦波有效值的测量Word格式.docx(23页珍藏版)》请在冰豆网上搜索。
图四
6.系统整体电路图如图五所示
图五
四.软件设计
AD流程图如图六图七所示
图六
图七
1.正弦波有效值的测量方法
工频正弦电压信号
频率f和初相位角ψ已知,且ψ=0,现以t=0时可作为基准时间,并在t=0时刻开始进行等间隔采样,共得到正弦波u(t)的N个测量值(采样数据)u(0),u
(1),……,u(N-1),希望利用这N个测量值来计算正弦波的幅值Um(有效值U)。
设采样周期为TS,如果不存在噪音,且测量无偏差,则有
……
我们可以设法利用测量值求解出正弦波参数。
实际上,我们的测量存在误差,同时信号存在噪音,因此,对每一个测量信号u(k),它与对应时刻t=k·
TS的正弦波
的值
存在一个误差
,其中k=0,1,…,N-1。
定义
为了利用N个测量值来尽可能准确的计算正弦波幅值Um,我们定义指标函数为:
它是频率f,幅值Um,初相位角ψ的函数。
我们的目的就是求频率f,幅值Um,初相位角ψ使得目标函数
最小。
为此,令
可以得到正弦波的幅值
为了与正弦波的真正幅值Um表示上的区别,用UmC表示利用N个采样数据获得的正弦波幅值计算值,既
对于f≈50Hz(以前面的测量值为准,这里仅为举例),选择采样周期TS≈20/200=0.1ms=100us,既每个周期采样200点(每半个周波100次采样),
是确定的(可以预先求出,存于sin表中),sin2(2π·
f·
k·
TS)同样作为常数表,而且
本身是一个常数,因此公式
(2)变为
当采样周期很小时,数值积分系数C可以用
来替代(可以认为C是一个周期类的数值积分,当采样周期很小时,就用积分项来表示)。
就可利用N个等间隔测量值计算出正弦信号的峰值Um。
正弦波的有效值与峰值的关系
半波绝对值电路:
在待测交流信号的正半波,输出待测信号送AD变换电路,在待测信号的负半波,输出0.
正半波时,Px.y=0,单片机利用该信号识别是正半波信号,进行AD转换,获得N个采样值。
在Px.y=1时,单片机暂停AD变换,利用正半波获得的N个检测信号计算正弦波的有效值U,频率f。
2.数据测量
幅值的测量
输入幅值vpp(v)
5
4.5
4
3.5
3
2.5
2
1.5
1
单片机读数(v)
3.486
3.143
2.804
2.152
2.092
1.742
1.405
1.045
0.695
误差(%)
-1.4
-1.3
-0.8
1.3
0.6
-1.7
表1
频率的测量
被测信号(Hz)
100
200
1K
2K
5K
10K
20K
30K
40K
读值(Hz)
99
197
999
2010
5032
10040
20056
30025
40034
0.1
0.5
0.4
0.28
0.083
0.08
表2
3.数据分析
由上图可知在输入信号vpp在0.7v到5v的区域内,实验作品的误差较小能够实现有效值的测量,当频率在100Hz到40KHz时,在误差允许范围内,作品基本能完成对该信号的准确测量。
4.软件部分代码:
#include<
reg52.h>
intrins.h>
#defineFOSC12000000L
#defineBAUD9600
typedefunsignedcharBYTE;
typedefunsignedintWORD;
sbitLCM_E=P2^5;
//定义接口
sbitLCM_RW=P2^6;
sbitLCM_RS=P2^7;
sfrADC_CONTR=0xBC;
sfrADC_RES=0xBD;
sfrADC_LOW2=0xBE;
sfrP1ASF=0x9D;
sfrAUXR=0x8e;
#defineADC_POWER0x80
#defineADC_FLAG0x10
#defineADC_START0x08
#defineADC_SPEEDLL0x00
#defineADC_SPEEDL0x20
#defineADC_SPEEDH0x40
#defineADC_SPEEDHH0x60
#defineLCM_DataP0//数据接口
voidInitUart();
voidSendData(BYTEdat);
voidDelay(unsignedintn);
voidIO_ADinit();
voidADC_Power_On();
voidget_ad_result();
voidADCONVERT();
voidWriteDataLCM(BYTEWDLCM);
voidWriteCommandLCM(BYTEWCLCM,BuysC);
BYTEReadDataLCM(void);
BYTEReadStatusLCM(void);
unsignedintGetADCResult(BYTEch);
voidLCMInit(void);
voidDisplayOneChar(BYTEX,BYTEY,BYTEDData);
voidDisplayListChar(BYTEX,BYTEY,BYTEcode*DData);
voidDelay5Ms(void);
voidDelay400Ms(void);
voidDisp_number(unsignedintnum,BYTEn);
voidShowResult(BYTEch);
unsignedintGetADCResult(BYTEa);
unsignedintdata_max=0;
unsignedlongdata_max1,count=0;
unsignedintdata_change=150;
//0.7V
unsignedcharcodeVP[4]={"
Amp:
"
},Freq[5]={"
Freq:
};
unsignedintCounter=0;
unsignedintdata_last=0;
BYTEch=0;
unsignedintFrequency=0;
unsignedintnn=0,flag=0,flag1=0,nn1=0;
unsignedintPrintFre[5];
unsignedintPrint[4];
unsignedintnumber[4];
unsignedintD;
voidmain()
{
unsignedintn=0;
Delay400Ms();
//启动等待,等LCM讲入工作状态
LCMInit();
//LCM初始化
Delay5Ms();
//延时片刻(可不要)
ET1=1;
EA=1;
InitUart();
TMOD=0x15;
//均为16位计数器
TH0=0x00;
TL0=0x00;
TH1=0x3C;
TL1=0xAF;
TCON=0x50;
//T1,T0均工作,t1做定时器,t0做计数器;
while
(1)
{
ADCONVERT();
n++;
if(n>
10000){data_max=0;
n=0;
}
voidTo_interrupt(void)interrupt3using1
inti,j;
unsignedintChange1,Print[4];
unsignedlongintChange2;
TL1=0xAF;
Counter=Counter++;
if(Counter==20)
{
Frequency=(TH0<
<
8)+TL0;
//读取此时计数器0的读数
if(Frequency>
=2000)Change1=(Frequency/100)*92;
elseif(Frequency>
=200)Change1=((Frequency/10)*92)/10;
elseChange1=(Frequency*97)/100;
for(i=0;
i<
5;
i++)
{
PrintFre[i]=Change1%10;
Change1=Change1/10;
}
for(i=4;
i>
=0;
i--)
{
if(i>
0)DisplayOneChar(4-i,0,PrintFre[i]+48);
else{DisplayOneChar(4-i,0,PrintFre[i]+48);
DisplayListChar(5-i,0,"
Hz"
);
}
Change2=data_max*50;
Change2=Change2/10/1.414;
for(j=0;
j<
=3;
j++)
Print[j]=Change2%10;
Change2=Change2/10;
for(j=3;
j>
j--)
if(j>
0)DisplayOneChar(10-j,0,Print[j]+48);
else{DisplayOneChar(10-j,0,Print[j]+48);
DisplayListChar(11-j,0,"
mV"
}
}
TH1=0x3C;
TH0=0xFF;
TL0=0xFC;
Counter=0;
}
voidIO_ADinit()
{
ADC_CONTR=0xe0;
//设置P1.0为输入AD转换口
_nop_();
//ADC_CONTR需要四个指令延时
}
voidADC_Power_On()
ADC_CONTR|=0x80;
voidget_ad_result()
unsignedintq=0,ad_average_result;
ADC_RES=0;
ADC_LOW2=0;
ADC_CONTR|=0x08;
while(!
(ADC_FLAG&
ADC_CONTR));
ADC_CONTR&
=0xE7;
ad_average_result=(ADC_RES<
2)+ADC_LOW2;
if(data_max<
ad_average_result)data_max=ad_average_result;
voidADCONVERT()
ADC_Power_On();
IO_ADinit();
get_ad_result();
voidInitUART()
SCON=0x5a;
PCON|=0x80;
voidSendData(BYTEdat)
TI);
TI=0;
SBUF=dat;
voidDelay(unsignedinti)
unsignedcharj;
for(i;
i>
0;
i--)
for(j=200;
j>
j--);
voidWriteDataLCM(BYTEWDLCM)
ReadStatusLCM();
//检测忙
LCM_Data=WDLCM;
LCM_E=0;
LCM_RS=1;
LCM_RW=0;
//若晶振速度太高可以在这后加小的延时
LCM_E=1;
voidWriteCommandLCM(BYTEWCLCM,BuysC)//BuysC为0时忽略忙检测
if(BuysC)ReadStatusLCM();
//根据需要检测忙
LCM_Data=WCLCM;
LCM_RS=0;
BYTEReadDataLCM(void)
LCM_RW=1;
return(LCM_Data);
BYTEReadStatusLCM(void)
LCM_Data=0xFF;
while(LCM_Data&
0x80)//检测忙信号
{LCM_E=0;
LCM_E=1;
voidLCMInit(void)//LCM初始化
LCM_Data=0;
WriteCommandLCM(0x38,0);
//三次显示模式设置,不检测忙信号
WriteCommandLCM(0x38,1);
//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);
//关闭显示
WriteCommandLCM(0x01,1);
//显示清屏
WriteCommandLCM(0x06,1);
//显示光标移动设置
WriteCommandLCM(0x0C,1);
//显示开及光标设置
voidDisplayOneChar(BYTEX,BYTEY,BYTEDData)
Y&
=0x1;
X&
=0xF;
//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;
//当要显示第二行时地址码0x40;
X+=0x80;
//算出指令码
WriteCommandLCM(X,0);
//这里不检测忙信号,发送地址码
WriteDataLCM(DData);
voidDisplayListChar(BYTEX,BYTEY,BYTEcode*DData)
BYTEListLength;
ListLength=0;
while(DData[ListLength])//若到达字串尾则退出
if(X<
=0xF)//X坐标应小于0xF
DisplayOneChar(X,Y,DData[ListLength]);
//显示单个字符
ListLength++;
X++;
voidDisp_number(unsignedintnum,BYTEn)
BYTEa;
//个位
BYTEb;
//十位
BYTEc;
//百位
BYTEd;
//千位
//BYTEe;
//万位
switch(n)
case1:
WriteDataLCM(num);
break;
case2:
b=num/10;
a=num%10;
WriteDataLCM(number[b]);
WriteDataLCM(number[a]);
case3:
c=num/100;
b=num%100/10;
WriteDataLCM(number[c]);
case4:
d=num/1000;
c=num%1000/100;
b=num%1000%100/10;
WriteDataLCM(number[d]);
//5ms延时
voidDelay5Ms(void)
unsignedintTempCyc=5552;
while(TempCyc--);
//400ms延时
voidDelay400Ms(void)
BYTETempCycA=5;
unsignedintTempCycB;
while(TempCycA--)
TempCycB=7269;
while(TempCycB--);
五.实习总结:
匆匆的4周过去了,我们的实习也将步入结束。
4周的实习让我感受良多;
在这4周中我们从一开始的原理图方案的设计到实习实物的制作再到对作品的调试到最后的验收,经历了种种挫折与挑战。
但在同伴的不懈努力以及老师的细心指导下,我们的作品在不断的辩证下产生了,虽然它简陋而粗糙,但它却依旧是我们汗水与努力的结晶。
经过此次实习使我们学到许多,我们拥有了能够独立完成作品的能力,同时加强了我们的动手能力,增进了同学间的友谊。
当在实习中也出现了种种问题,比如由于设计方案的不合理使我们一度陷入了进退两难的境地,最终只能浪费一块板,重新做了块新板。
又例如由于焊接的粗心导致了多次数据的检测错误等等。
不管怎么说这都是一次有意义的实习。
最后感谢我们可敬的老师,感谢他们辛苦的付出。
六.参考文献
《单片微机原理及应用》清华大学主编:
方方
《模拟电子电路》北京大学出版社主编:
宋树祥
《电子系统设计创新与实践实习指导书》
《模拟电子技术基础简明教程》清华大学主编:
杨素行