两路相位可调方波信号发生器.docx
- 文档编号:2007319
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:21
- 大小:502.84KB
两路相位可调方波信号发生器.docx
《两路相位可调方波信号发生器.docx》由会员分享,可在线阅读,更多相关《两路相位可调方波信号发生器.docx(21页珍藏版)》请在冰点文库上搜索。
两路相位可调方波信号发生器
1.设计原理
单片机集成度高、功能强、可靠性高、体积小、功耗地、使用方便、价格低廉等一系列优点,目前已经渗入到人们工作和生活的方方面面,几乎“无处不在,无所不为”。
单片机的应用领域已从面向工业控制、通讯、交通、智能仪表等迅速发展到家用消费产品、办公自动化、汽车电子、PC机外围以及网络通讯等广大领域。
单片机有两种基本结构形式:
一种是在通用微型计算机中广泛采用的,将程序存储器和数据存储器合用一个存储器空间的结构,称为普林斯顿结构。
另一种是将程序存储器和数据存储器截然分开,分别寻址的结构,一般需要较大的程序存储器,目前的单片机以采用程序存储器和数据存储器截然分开的结构为多。
本课题讨论的方波发生器的核心是目前应用极为广泛的51系列单片机。
本课程设计是设计一个方波发生器,用1602显示方波的频率和相位差。
系统的整体图如下:
图1系统整体图
系统默认的频率为10HZ,默认的相位差为0。
1.1复位电路设计
如果RST持续为高电平,单片机就处于循环复位状态,而无法执行程序。
由C1,R1,开关构成开关复位电路,如图2。
上电后,由于电容充电,使RST持续一段高电平。
当单片机在运行状态下,按下复位键也能使RST持续一段时间的高电平,从而实现上电复位和手动复位。
图2复位电路
1.2振荡电路设计
如图3所示,外接石英晶体或者陶瓷谐振器以及电容C2,C3接在放大器的反馈电路中构成并联谐振电路。
谐振器本身对外接电容C2、C3虽然没有十分严格的要求,但电容容量的大小会轻微影响振荡频率的高低、振荡器工作的稳定性、起振的难易程度以及温度的稳定性,如果使用石英晶体,推荐使用30pF,而使用陶瓷谐振器建议选择40pF。
本次设计使用的是石英晶体谐振器,因此采用30pF的电容,晶振频率为12MHZ。
图3振荡电路
1.3矩阵键盘设计
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。
由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,下图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。
这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。
行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
图4矩阵键盘
1.4液晶显示
液晶如图:
图5液晶
1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线
VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,其中:
引脚
符号
功能说明
1
VSS
一般接地
2
VDD
接电源(+5V)
3
V0
液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
4
RS
RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
5
R/W
R/W为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作。
6
E
E(或EN)端为使能(enable)端,
写操作时,下降沿使能。
读操作时,E高电平有效
7
DB0
低4位三态、双向数据总线0位(最低位)
8
DB1
低4位三态、双向数据总线1位
9
DB2
低4位三态、双向数据总线2位
10
DB3
低4位三态、双向数据总线3位
11
DB4
高4位三态、双向数据总线4位
12
DB5
高4位三态、双向数据总线5位
13
DB6
高4位三态、双向数据总线6位
14
DB7
高4位三态、双向数据总线7位(最高位)(也是busyflag)
15
BLA
背光电源正极
16
BLK
背光电源负极
寄存器选择控制表
RS
R/W
操作说明
0
0
写入指令寄存器(清除屏等)
0
1
读busyflag(DB7),以及读取位址计数器(DB0~DB6)值
1
0
写入数据寄存器(显示各字型等)
1
1
从数据寄存器读取数据
注:
关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0.
busyflag(DB7):
在此位为1时,LCD忙,将无法再处理其他的指令要求。
2.程序流程图
图6流程图
3.源程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbittest=P3^7;
sbitLCDEN=P2^2;
sbitLCDRS=P2^0;
sbitLCDRW=P2^1;
sbitWaveA=P3^0;
sbitWaveB=P3^1;
ucharFrequency,Key_Value,Flag,a[6];
uintdataPhase_Difference;
doubleControl_Phase=0.000001;
intdataCounter_T0,Number_T0,Counter_T1,Number_T1;
//**********************
voidInitial_System();
ucharScan_Keyboard();
uintGet_Number_T0(ucharFrequency);
uintGet_Number_T1(ucharFrequency);
voidIncrease_Frequency();
voidDecrease_Frequency();
voidIncrease_Phase_Difference(uintdataStep_Phase_Difference);
//voidDecrease_Phase_Difference(uintdataStep_Phase_Difference);
voidCalculate_Frequency_Phase(void);
voidDisplay_Frequency_Phase();
voidDelay(uint);
voidWrite_Cmd(ucharcmd);
voidWrite_Data(ucharData);
voidLCD_Init();
//**********************************
voidmain()
{
Initial_System();
while
(1)
{
Key_Value=Scan_Keyboard();
Calculate_Frequency_Phase();
Display_Frequency_Phase();
}
}
//************************
voidInitial_System()
{
WaveA=0;
WaveB=0;
Control_Phase=0.000001;
Frequency=10;
Phase_Difference=0;
Counter_T0=0;
Counter_T1=0;
Number_T1=Get_Number_T1(Frequency);
TMOD=0x22;
TH1=0x38;//256-200
TL1=0x38;//256-200
TH0=0xc9;//256-201
TL0=0xc9;
EA=1;
ET1=1;
TR0=1;
TR1=1;
LCD_Init();
}
//****************************
voidWrite_Cmd(ucharcmd)
{
LCDEN=1;
LCDRS=0;
P0=cmd;
Delay(5);
LCDEN=0;
}
//***************************
voidWrite_Data(ucharData)
{
LCDEN=1;
LCDRS=1;
P0=Data;
Delay(5);
LCDEN=0;
}
//***************************
voidLCD_Init()
{
LCDRW=0;
LCDRS=0;
Write_Cmd(0x01);
Write_Cmd(0x38);
Write_Cmd(0x0C);
Write_Cmd(0x06);
Write_Cmd(0x80);
Write_Data('F');
Write_Data('R');
Write_Data('E');
Write_Data(':
');
Write_Cmd(0x80+0x40);
Write_Data('P');
Write_Data('H');
Write_Data('A');
Write_Data(':
');
}
//*************************
ucharScan_Keyboard()
{
ucharkey;
uchartemp1,temp2;
P1=0x0f;
if(P1!
=0x0f)
{
temp1=P1;
P1=0xf0;
temp2=P1;
}
P1=0x0f;
while(P1!
=0x0f)
{
Delay(10);
key=temp1|temp2;
}
switch(key)
{
case0xee:
return0;break;
case0xde:
return1;break;
case0xbe:
return2;break;
case0x7e:
return3;break;
case0xed:
return4;break;
case0xdd:
return5;break;
case0xbd:
return6;break;
case0x7d:
return7;break;
case0xeb:
return8;break;
case0xdb:
return9;break;
case0xbb:
return10;break;
case0x7b:
return11;break;
case0xe7:
return12;break;
case0xd7:
return13;break;
case0xb7:
return14;break;
case0x77:
return15;break;
default:
return16;
}
}
//*********************************
uintGet_Number_T0(ucharFrequency)
{
uinth;
doublel;
l=(double)Frequency;
l=Control_Phase*0.5/l;
l=l/0.000055;
h=l;
if(l-h>+0.5)
h=h+1;
returnh;
}
//*********************************
uintGet_Number_T1(ucharFrequency)
{
uinth;
doublef;
f=(double)Frequency;
f=0.5/f;
f=f/0.0002;
h=f;
if(f-h>=0.5)
h=h+1;
returnh;
}
//********************************T0
voidTimer0_Interrupt()interrupt1
{
Counter_T0++;
if(Counter_T0>Number_T0)
{
Counter_T0=0;
if(Flag==0)
WaveB=WaveA;
else
WaveB=~WaveA;
ET0=0;
TR0=0;
}
}
//********************************T1
voidTimer1_Interrupt()interrupt3
{
Counter_T1++;
if(Counter_T1>Number_T1)
{
Counter_T1=0;
WaveA=~WaveA;
ET0=1;
TR0=1;
}
}
//********************************
voidIncrease_Frequency()
{
if(Frequency<=256-10)
Frequency=Frequency+10;
else
Frequency=255;
Number_T1=Get_Number_T1(Frequency);
}
//********************************
voidDecrease_Frequency()
{
if(Frequency>10)
Frequency=Frequency-10;
else
Frequency=1;
Number_T1=Get_Number_T1(Frequency);
}
//********************************
voidIncrease_Phase_Difference(uintdataStep_Phase_Difference)
{
Control_Phase=Control_Phase+0.00555556*Step_Phase_Difference;
if(Control_Phase>=1&&Flag==1)
{
Flag=0;
Control_Phase=0.000001;
}
elseif(Control_Phase>1)
{
Flag=1;
Control_Phase=Control_Phase-1;
}
Phase_Difference+=Step_Phase_Difference;
if(Phase_Difference>=360)
Phase_Difference=0;
}
voidCalculate_Frequency_Phase(void)
{
switch(Key_Value)
{
case0:
Increase_Frequency();break;
case1:
Decrease_Frequency();break;
case2:
Increase_Phase_Difference(10);break;
case3:
Initial_System();break;
default:
break;
}
Number_T0=Get_Number_T0(Frequency);
}
voidDisplay_Frequency_Phase()
{
uchari,j;
a[0]=Frequency/100;
a[1]=(Frequency%100)/10;
a[2]=Frequency%10;
a[3]=Phase_Difference/100;
a[4]=(Phase_Difference%100)/10;
a[5]=Phase_Difference%10;
Write_Cmd(0x80+5);
for(i=0;i<=2;i++)
{
Write_Data(a[i]+48);
Delay(5);
}
Write_Cmd(0x80+0x40+5);
for(j=3;j<=5;j++)
{
Write_Data(a[j]+48);
Delay(5);
}
test=0;
}
voidDelay(uinti)
{
uintj,k;
for(k=i;k>0;k--)
for(j=110;j>0;j--);
}
4.仿真结果分析
4.1系统初始化
系统默认频率为10HZ,相位差为0.液晶显示,示波器测量如图:
图7系统初始图
4.2频率100HZ,相位差0
图8频率100HZ,相位差0
4.3频率10HZ,相位差90
图9频率10HZ,相位差90
4.4频率100HZ,相位差90
图10频率100HZ,相位差90
5.心得体会
通过本次课程设计,我对单片机和C语言的相关知识得到了进一步的,刚开始看到这个题目的时候,感觉倒计时不是很难,有对应的输入,在控制芯片的作用下,进行递减的控制,就可以达到效果。
所以刚开始的时候,做的还不是很认真,当设计进行到具体环节的时候,问题就体现出来了,并不是像刚开始的那样简单。
首先要想到芯片的对应P口的功能,于是要对所学的单片机的知识进行复习,查找相关资料对那些知识进行扩充,于是就大量的查找相关资料和阅读,了解清楚了相应的功能后,开始了设计。
接着就是具体的模块部分的设计。
我把整体模块分为三个部分进行,输入部分,用4*4的矩阵键盘作为输入模块。
显示部分,采用1602,。
控制部分则有AT89S52芯片来完成其功能。
再就是进行相对应的仿真设计。
由于再仿真用到的是Proteus软件,所以要对这个软件的应用进行学习。
也是开始查找一些资料书和上网找一些应用方面的技巧,在做了充分的准备后,开始了仿真绘图。
在绘图的过程中,有时候也是弄错了,导致仿真的结果出不来,在同学的帮助下,仔细查找和修改,还是完成了本设计,感觉集体的智慧还是很强大的。
在看到LCD上的显示和示波器一致的时候,心里感觉还是蛮高兴的。
虽然在这次设计的过程中,困难不少,但是正是在自己的努力,同学们的帮助下,自己能够顺利的完成,确实还是蛮欣慰的。
感谢这次课程设计给了自己锻炼的机会,自己在今后的学习和生活中,会更加的努力,争取更大的进步!
6.参考文献
[1]何立民.MCS51单片机应用系统设计[M].北京:
北京航空航天大学出版社,2003.
[2]徐君毅.单片微型机原理与应用[M].上海:
上海科技出版社,1995.
[3]公茂法.单片机人机接口实例集[M].北京:
航空航天大学出版社,1998.
[4]沈红卫.基于单片机的智能系统设计与实现[M].北京:
电子工业出版社,2005.
[5]李广弟,朱月秀等.单片机基础[M].北京:
北京航空航天大学出版社,2003.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 相位 可调 方波 信号发生器