基于51单片机的程控放大器设计
电气学科大类
《单片机》课程
设 计 报 告
姓 名 蔡玲珑 学号专业班号 电气提高班
指导教师 日 期 2012年3月
实验成绩 评 阅 人
摘要
本设计主要以CD4051模拟开关以及所连的电阻网络作为核心,利用SST89C51单片机控制所选A/D的电阻网络状态,同时编写峰值检测软件对输入信号进行峰值检测并以此为依据来控制正弦波的放大倍数,最后利用液晶显示器将其显示出来。经过实际测量,本系统可以实现通频为0Hz~1.5KHz,放大倍数为0.96~5的无失真的自动波形放大器。
关键词: SST89C51单片机 液晶显示器 放大器 TLC549
目录
摘要----------------------------------------------------------------------------------------------------2 一.设计要求---------------------------------------------------------------------------------------4 1.1程控放大器的作用---------------------------------------------------------------------------4 1.2程控放大器的原理----------------------------------------------4 1.3课题要求------------------------------------------------------5
二.实验方案及论证-----------------------------------------------------------------------------5
三.单元电路分析与实现--------------------------------------------------------------------- -6 3.1引脚特性说明---------------------------------------------------------------------------------6 3.2 A/D转换电路---------------------------------------------------------------------------------7 3.3控制显示电路---------------------------------------------------------------------------------8 3.4峰值检测电路设计----------------------------------------------------------------- --------11 3.5实验硬件图--------------------------------------------------------------------------- --------11
四.软件分析--------------------------------------------------------------------------------------12 4.1编程排序---------------------------------------------------------------------------------------12 4.2倍数与引脚对应-----------------------------------------------------------------------------12 4.3峰值检测---------------------------------------------------------------------------------------13 4.4液晶显示---------------------------------------------------------------------------------------13 4.5对TLC549进行操作------------------------------------------------------------------------15 4.6主程序流程分析-----------------------------------------------------------------------------15
五.实验仿真处理及结果分析---------------------------------------------------------------16
六.实验总结---------------------------------------------------------------------------- ---------21
七.参考文献-------------------------------------------------------------------------- -----------22
附录---------------------------------------------------------------------------------------------------23
一. 设计要求.
1.1程控放大器的作用
在信号调理电路中,必须将输出信号调理在适当水平。比如一个正弦交流信号,要连接到A/D转换器件进行A/D转换,当A/D转换器件的参考电压为5V时,交流信号的幅值应调节到小于并接近于2.5V的水平,以提高A/D转换器件精度的利用率。被测交流信号一般为正负交替的电压信号,需经电压提升电路,将被测电压信号中叠加一个直流分量后,输出电压在0~5V之间,如图1.1.1所示:
图1.1.1 适当的输出信号幅值
如果输出信号的幅值过大,超出A/D器件的基准电压,显然不能得到正确的A/D转换结果;如果输出信号幅值过小,则不能充分发挥A/D转换器件精度,即不能充分利用A/D转换器件的位数。因此有必要将输出信号调理到0~5V之间,并且尽可能接近边界。
当原始被测信号的幅值变化较大时,如果采用固定增益的信号调理电路,则不能自动根据原始被测信号的变化调整增益(放大倍数)。采用程控放大器,利用DSP实现增益的智能调节,则可以根据信号幅值的变化自动调整放大倍数。
1.2程控放大器的原理
程控放大器利用选通开关,控制放大器的反馈电阻阻值,实现改变放大倍数的原理工作,其基本原理如图1.2.1所示。
(a)多选一开关控制 (b)一对一开关控制
图1.2.1开关组合控制放大倍数
利用数模开关选通不同的开关通道,通过反馈电阻的搭配可以实现多种数值的放大。采用图1.2.1(a)所示的电路,只能进行较为简单的放大倍数控制。采用图1.2.1(b)所示的电路,放大器的放大倍数调整更灵活,只是编程也要复杂一些。
实验中的选通电路原理如下图1.2.2所示。
图1.2.2 程控放大器实验原理图
本实验的控制电路采用8选1模拟开关器件CD4051作为放大器反馈电阻选择开关。
1.3课题要求
a.按照图1.2.2所示,在面包板上自行搭接放大器电路,并与实验箱上的A/D转换器件及单片机连接;
b.自行编程实现程控放大的功能; c.按照图1.2.1(b)所示的电路原理,利用两片模拟开关器件CD4051,自行搭接程控放大器实验电路,并编程实现程控放大功能。
二. 实验方案设计及论证
由于本实验中已经采用8选1模拟开关器件CD4051作为放大器反馈电阻选择开关,并且也指定了相应的阻值。所以不能用步进放大的方式来对放大器进行操作。同时由于实验中要求采用两块CD4051,通过两两电阻并联一共可得32种放大倍数。由于该32种放大倍数并无太多规律可循,所以弄清所有组合并对应单片机芯片的引脚变化是很重要的。先采取合适算法先将CD4051电阻组合一一列出并与芯片引脚相对应。具体可参考附录一。
此外,利用TLC549进行峰值检测处理时需要对TLC549有一定了解:TLC549是 TI公司生产的一种低价位、高性能的8位 A/D转换器,它以8位开关电容逐次逼近的方法实现 A/D转换,其转换速度小于 17us,最大转换速率为 40000HZ,4MHZ典型内部系统时钟,电源为 3V至 6V。它能方便地采用三线串行接口方式与各种微处理器连接,构成各种廉价的测控应用系统。实验过程中,通过TLC549获取输入信号的峰值,从而可以反馈给单片机一个最合适的放大倍数,使放大后峰峰值接近5V。放大倍数通过单片机又发送给液晶屏,在液晶屏上显示放大倍数。
本次实验采用的液晶屏为字符型液晶显示模块。具体型号为SMC1602该液晶模块采用HD44780驱动芯片,可兼容性强。该液晶屏驱动程序于单片机课程学习中已经给出,可显示192种字符160个5*7点阵字符和32个5*10点阵字符,这些字符的代码均与标准ASCII码大部分兼容。所以对于字符对应和输出相当有帮助。
实验总体方案是以单片机SST89C51控制为核心,液晶模块和A/D芯片与单片
机结合参与工作,实现波形自动放大以及放大倍数的显示。系统框图如图2-1所示。该方案的优点是实现了软件与硬件相结合的控制方式,设置参数较为方便,可以实现倍数的快速自动调节,误差也较小,并且通过液晶显示器将其显示出来。利用软件部分省去了峰值检测部分的繁琐设计,大大简化了实验方案。
图2.1总体方案设计
三. 单元电路分析与实现。
3.1首先对实验中用到的一些芯片特性进行说明。 在实验中要用到单片机的部分引脚。
本实验选用P1.0,P1.1,P1.2来控制第一块CD4051;P2.0,P2.1,P2.2来控制第二块CD4051。实验接线图如下图3.1.1所示:
图3.1.1单片机与CD4051接线图
单片机与液晶显示器接线图如下图3.1.2:
图3.1.2单片机与液晶显示器接线图
3.2 A/D转换电路
本系统采用TLC549作为A/D转换芯片。下面介绍其一些基本特性。
TLC549是 TI公司生产的一种低价位、高性能的8位 A/D转换器,它以8位开关电容逐次逼近的方法实现 A/D转换,其转换速度小于 17us,最大转换速率为 40000HZ,4MHZ典型内部系统时钟,电源为 3V至 6V。它能方便地采用三线串行接口方式与各种微处理器连接,构成各种廉价的测控应用系统。 编辑本段二、TLC549 引脚图及各引脚功能 TLC549引脚图如下图3.2.1所示:
图3.2.1TLC549引脚图
其各引脚说明如下:
REF+: 正基准电压输入 2.5V≤REF+≤Vcc+0.1。
REF-: 负基准电压输入端,-0.1V≤REF-≤2.5V。且要求:(REF+)-(REF-)
≥1V。 VCC: 系统电源3V≤Vcc≤6V。 GND: 接地端。
/CS: 芯片选择输入端,要求输入高电平 VIN≥2V,输入低电平 VIN≤0.8V。
DATA OUT:转换结果数据串行输出端,与 TTL 电平兼容,输出时高位在前,低
位在后。 ANALOGIN:模拟信号输入端,0≤ANALOGIN≤Vcc,当 ANALOGIN≥REF+电压时,
转换结果为全“1”(0FFH),ANALOGIN≤REF-电压时,转换结果为全“0”(00H)。 I/O CLOCK:外接输入/输出时钟输入端,同于同步芯片的输入输出操作,无需与
芯片内部系统时钟同步
实验测试时,TLC549接线图如下图3.2.2所示:
图3.2.2TLC549接线图
3.3控制显示电路
本系统采用AT89C51单片机最小控制系统,显示部分采用LCD1602液晶显示。本节重点介绍LCD1602的基本用法。
1、LCD1602液晶简介及系统的硬件原理图
1602采用标准的16脚接口,各引脚功能图如表3.2所示。
符图形,如表3.3所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
2、1602液晶模块内部的控制器共有11条控制指令,如表3-3-3所示。 它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。 指令1:清显示,指令码01H,光标复位到地址00H位置 指令2:光标复位,光标返回到地址00H 指令3:光标和显示模式设置
1/D:光标移动方向,高电平右移,低电平左移
S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效 指令4:显示开关控制。
D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:光标或显示移位
S/C:高电平时移动显示的文字,低电平时移动光 R/L:1向右移动;0向左移动。 指令6:功能设置命令
DL高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时双行显示
F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符 指令7:字符发生器RAM地址设置 指令8:DDRAM地址设置
指令9:读忙信号和光标地址
BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。 指令10:写数据 指令11:读数据
表3-3-3 1602液晶模块的控制指令
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,表2-4是DM-162的内部显示地址。
在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。 3.4峰值检测电路设计
进行实验前,我通过查阅相关资料,进行了一个峰值检测电路的设计,电路如下图3.4所示:
图3.4峰值检测电路
该电路在低频情况下能够检测出信号的峰峰值,但进入高频后,检测结果误差很大,这可以通过后面的仿真来看出,所以经过一番取舍,我最后放弃了这种方案。 3.5实验硬件图
实验最后硬件效果图如图3.5所示:
图3.5实验硬件图
四. 软件分析
本实验中需要利用软件解决两个问题,两块CD4051选通放大倍数组合情况的分析排序以及对应单片机引脚的编码设计。 4.1编程排序
4.1.1合并所有组合
利用C++编程实现了所有放大倍数的组合。以下是该程序的示例:
通过以上程序,能够实现将所有的两两组合的放大倍数情况全部包含于数组C[64]中,当然这个数组现在是杂乱无章并且有很多重复倍数的。那么接下来就需要进行第二步——排序。
4.1.2合并及排序
通过对C[64]进行排序处理,
可以得到放大倍数从小到大有顺序的所有放大
倍数组合。程序示例如下:
上面是一个简单的排序算法,但能够很巧妙的将所有的放大倍数从小到大一一列出。仅仅获得所有的放大倍数显然是不够的,必须与单片机相应引脚对应起来并通过控制CD4051的选通来实现这些放大倍数才能达到实验自动放大的要求。
4.2倍数与引脚对应
本实验选用P1.0,P1.1,P1.2来控制第一块CD4051;P2.0,P2.1,P2.2来控制第二块CD4051。由上述硬件分析我们可以知道CD4051引脚关系图。通过对比每块CD4051的放大倍数以及两块组合的放大倍数我们可以将引脚关系也按与放
大倍数相对应的关系来一一对应。本实验采用的做法是创建两个一维数组, floatB[36]={0.5,0.6,0.6667,0.7297,0.75,0.7674,0.8361,0.8571,0.8718,0.9091,0.9643,1,1.0313,1.1489,1.1591,1.2289,1.2453,1.3044,1.35,1.4366,1.485,1.5455,1.65,1.6667,1.7654,1.9326,2.0036,2.126,2.2218,2.4812,2.55,2.9143,3.3775,3.4,4.0476,5};
intC[36]={77,76,75,74,66,73,72,65,71,70,64,55,63,54,62,61,53,60,44,52,43,51,33,50,42,41,32,40,31,30,22,21,20,11,10,0}; 对C数组进行十位以及个位的处理就可以得到相应引脚数值,具体程序如下所示:
将P1.0,P1.1,P1.2对应于d;P2.0,P2.1,P2.2对应于e就可以得到相应的放大倍数。现在的问题是如何确定最开始需要的放大倍数以及对此放大倍数做怎样的处理。
4.3峰值检测
在进行峰值检测前我曾设想过两种方案,一种是通过硬件设计,这在前面已经提过,另外一种就是软件检测了。通过对所接入信号进行不断采样并与前述信号进行比较得出峰峰值,并且在TLC549基准电压下将其转换为char型数据,这样通过与5V所对应的char型数据(255)比较可以得出放大的最大倍数。具体程序如下:
4.4液晶显示
液晶显示的目的是反映放大倍数,这样可以对原输入信号有一个清晰的了解。液晶编写需要对其驱动程序接口有比较完整的认识。液晶驱动程序流程图如下图4.4.1所示:
图4.4.1液晶驱动程序流程图
依据上述读写操作即可对液晶(LCD)进行读写。实验中对液晶操作的读写程序如下图4.4.2和4.4.3:
图4.4.2LCD读函数
图4.4.3LCD写函数
4.5对TLC549进行操作
TLC549为CMOS8位开关电容逐次逼近A/D转换器。与处理器或外围设备连接采用SPI串行总线方式,包括一个数据输出端(DO)和个控制输入端:输入/输出时钟(CLK)和芯片选择(CS)输入作为数据控制,其最高CLK输入频率为1.1MHz。
TLC549引脚接线已在硬件部分介绍。对于其读写程序应严格按时序图来进行处理。当在头文件进行完整分析后,主程序对TLC549进行操作就很简单了。
4.6主程序流程分析
首先是对头文件进行包含以及对变量和部分函数进行声明。如下图
4.6.1
图4.6.1头文件和变量声明
接下来就按照上面的分析对程序进行处理,先进行初始化:
图4.6.2LCD初始化
函数主体处理部分如下图示,与前述介绍流程图基本一致:
图4.6.3主函数处理
五. 实验仿真处理及结果分析
首先是对峰值检测电路进行仿真,仿真的频率特性如下图5.1所示:
图5.1峰值检测电路频率特性
从仿真可以看到,对于低频部分峰值 检测电路效果很好,但对于高频检测部分其效果并不佳,这也是为什么我最后舍弃这种方法的原因。
本实验采用LM324作为放大电路对实验放大电路部分进行仿真分析如图5.2:
图5.2LM324频率特性测试结果
由于LM324频率特性较好,不会对电路造成太大影响,并且LM324在电源电压为3到32V均可正常工作,而单片机开发板上最大只能提供5V电压,所以实验采用LM324作为放大芯片是非常合适的。
实验测试中需要用到示波器与信号源,所以在测试过程中,我通过protues搭建了一个模拟的单片机仿真图。具体如下图5.3所示:
图5.3实验测试开发板仿真图
通过多次测试,该开发板与实际所以单片机开发板基本吻合。对于程序调试和联合仿真起了很大作用。
下图5.4是进行仿真实时图:
图5.4a实时仿真图
图5.4b波形显示情况
通过一系列测试,我们发现该实验结果所能放大的倍数范围以及频率范围如
考虑到TLC549供电电压为5V,所以其放大最小倍数约为1倍。仿真示波器图形如下图5.5.1所示:
图5.5.1最小放大倍数检测
最大放大倍数由于收到反馈电阻的影响,故最大放大倍数为5倍,仿真显示如下图5.5.2所示:
图5.5.2最大放大倍数检测
在进行频率测试时,当输入直流电压时,仍能正常工作,故最低频率特性为0Hz。仿真结果如下图5.5.3所示:
图5.5.3最小频率特性检测
最大频率特性检测如下图5.5.4所示:
图5.5.4最大频率检测电路
造成这种结果的原因是利用软件进行峰值检测,其频率特性也收到了很大限制,如单片机处理速度,TLC549采样速度等。
六. 实验总结
通过一个多星期的课程设计,从选题到查资料,从完善原理图到写报告
文档,让我明白了课程设计是名副其实的综合性训练,不仅要运用学过的数字电路、单片机及汇编原理等知识,还要学会查阅各种图书资料和工具书,并将新知识和所学的结合起来为自己所用。进一步熟练使用Proteus仿真软件,加强了工程绘图的能力,也提高了动手能力。在设计中遇到一些困难和问题,在向老师请教和与同学的讨论中,解决了问题,觉得很有收获。这个设计过程中,我遇到过许多次失败的考验,就比如,自己对实际生活中的交通秩序的不了解给整个设计带来的困扰,连东南西北四个方向红绿灯之间的关系都没搞清楚,这是对现实生活中小细节的忽略。不仅补学了生活中的小常识,还让我明白了,生活中的点滴也蕴藏着知识,我们不仅要学习书本上的知识,也要去发现身边的学问。
值得一提的是,通过单片机课程设计,我不仅加深了对单片机理论的理
解,还学会了将理论很好地应用到实际当中去。上学期学习单片机的课时不多,对单片机的硬件设计,软件设计掌握的深度不够,但通过此次课程设计,理论水平明显地提高了了,并且对于硬件电路的工作原理有了进一步的学习,有了一定的掌握;软件方面,在程序的设计、程序的调试方面都有了很大的进步。另外在编程中出现问题时,一定要戒骄戒躁,脚踏实地,认真看书,仔细分析,仔细调试,就一定会发现错误。我在这一设计过程中,学会了坚持不懈,不轻易言弃。设计过程,也好比是我们的成长历程,常有一些不如意,也许这就是在对我们提出挑战,勇敢过,也战胜了,胜利的钟声也就一定会为我们而敲响。
七. 参考文献
1.谢自美.电子线路设计·实验·测试(第二版) .华中理工大学出版
社, 2000
2.王俊杰, 黄心汉. 程控增益放大器和自动调整增益放大器的设计
[J ] . 电子技术应用, 1998 , (5) : 50~51.
3.华中科技大学电工电子科技创新中心组.SST单片机实践教程 .华中
科技大学出版社,2010
4.何立民. MCS - 51 系列单片机应用系统设计[M] . 北京;航空航天大
学出版社,1990.
附录1.数组合并测试程序
#include
using namespace std;
int main()
{
int i,j;
float k;
float C[72];
float A[8]={1,1.5,2,2.7,3.3,5.1,6.8,10};
float B[8]={1,1.5,2,2.7,3.3,5.1,6.8,10};
for(i=0;i
{
for(j=0;j
{
C[i*8+j+1]=A[i]*B[j]/(A[i]+B[j]);
}
}
cout
for(i=0;i
{C[i+65]=A[i];}
cout
for(i=0;i
{
for(j=0;j
{
if(C[j]>C[j+1])
{
k=C[j];
C[j]=C[j+1];
C[j+1]=k;}
}
}
for(i=1;i
{
cout
}
system("pause");
}
附录2.数组排序测试源程序
#include
using namespace std;
int i,b,c,d,e;
float a;
int geti(float c[36],float a)
{
if(a
{
for(i=0;c[i]
{}
return i-1;
}
else return 35;
}
int getjk(int c[36],int b)
{
return c[b];
}
int main()
{
float
B[36]={0.5,0.6,0.6667,0.7297,0.75,0.7674,0.8361,0.8571,0.8718,0.9091,0.9643,1,1.0313,
1.1489,1.1591,1.2289,1.2453,1.3044,1.35,1.4366,1.485,1.5455,1.65,1.6667,1.7654,1.9326,2.0036,
2.126,2.2218,2.4812,2.55,2.9143,3.3775,3.4,4.0476,5};
int
C[36]={77,76,75,74,66,73,72,65,71,70,64,55,63,54,62,61,53,60,
44,52,43,51,33,50,42,41,32,40,31,30,22,21,20,11,10,0};
cin>>a;
b=geti(B,a);
c=getjk(C,b);
d=c/10;
e=c%10;
cout
system("pause");
}
附录3.实验主程序
#include"SMC162.h"
#include"TLC549.h"
sbit P1_5=P1^5;
unsigned char i,beishu,cod,p1,p2;
unsigned char volmax=0;
float Ap,f;
char display[3],screen[3];
void delay(unsigned char dly)
{
unsigned char j;
for(j=dly;j>0;j--);
}
char geti(float c[36],float a)
{
if(a
{
for(i=0;c[i]
{}
return i-1;
}
else return 35;
}
void vppfun(unsigned char vol)
{
if(vol>volmax)
volmax=vol;
}
float code Amp[36]={0.5,0.6,0.6667,0.7297,0.75,0.7674,0.8361,0.8571,0.8718,0.9091,0.9643,1,1.0313,1.1489,1.1591,1.2289,1.2453,1.3044,1.35,1.4366,1.485,1.5455,1.65,1.6667,1.7654,1.9326,2.0036,2.126,2.2218,2.4812,2.55,2.9143,3.3775,3.4,4.0476,5};
unsigned char CD[36]={77,76,75,74,66,73,72,65,71,70,64,55,63,54,62,61,53,60,44,52,43,51,33,50,42,41,32,40,31,30,22,21,20,11,10,0};
int main()
{
unsigned char volget;
int voltcal;
char display[4],screen[4];
LcdInit();
display[1]=-2;
PutStr(0,0,"Please wait!");
while(1)
{
volget=TLC549_GetAD(); //AD数据获取
vppfun(volget); //峰值获取
if(P1_5==0)
{
delay(30);
Ap=127.0/(volmax-128); //放大倍数获取
beishu=geti(Amp,Ap); //通过如已知倍数比较获取合适倍数
cod=CD[beishu]; // 将倍数与引脚关系相对应 f=Amp[beishu];
p1=cod/10; //获取P1引脚数值,CD4051选通
p2=cod%10; //获取P2引脚数值,CD4051选通 P1=p1;
P2=p2;
voltcal=f*100;
display[0]= voltcal/100;
display[2]=( voltcal%100)/10;
display[3]= voltcal%10;
for(i=0;i
{
screen[i]=display[i]+48;
PutStr(0,0,"The Ampi is:");
PutChar(i+6,1,screen[i]);
}
}
}
}