《单片机正文函数信号发生器.doc》由会员分享,可在线阅读,更多相关《单片机正文函数信号发生器.doc(22页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、. . . . 编号:单片机综合实训 (论文)说明书题 目: 函数信号发生器 院 (系): 信息与通信学院 专 业: 电子信息工程 学生:学 号:指导教师:2012年 12月 24 日4 / 22摘 要本文介绍一种用AT89C51单片机构成的波形发生器,可产生方波、三角波、正弦波、锯齿波等多种波形,波形的周期可用程序改变,并可根据需要选择单极性输出或双极性输出,具有线路简单、结构紧凑、性能优越等特点。文章给出了源代码,通过仿真测试,其性能指标达到了设计要求。关键词:单片机;DAC;信号发生器AbstractThis paper introduces a AT89C51 single chip
2、waveform generator, can produce square wave, triangle wave, sine wave, sawtooth wave and other wave, waveform cycle can be used to change procedures, and in accordance with the need to select the output unipolar or bipolar output, has simple circuit, compact structure, superior performance character
3、istics. The article gives the source code, through simulation test, the performance indexes have reached the design requirements.Key words: single chip microcomputer; DAC; signal generator。目录目录31 绪论41.1单片机与TLC5615概述41.2信号发生器的分类41.3 研究容42 方案的设计与选择52.1 方案的比较52.2 设计原理52.3 设计功能63 硬件设计73.1 硬件原理框图73.2 系统P
4、CB板的设计73.3 主控电路73.4数/模转换电路83.5 按键接口电路103.6 时钟电路103.7 显示电路104 软件设计124.1 程序流程图124.2 软件与联机调试134.3 主控程序调试145 实训心得体会1参考文献1附录12电路原理图与PCB图2附录2 源程序31 绪论1.1单片机与TLC5615概述随着大规模集成电路技术的发展,中央处理器(CPU)、随机存取存储器(RAM)、只读存储器(ROM)、(I/O)接口、定时器/计数器和串行通信接口,以与其他一些计算机外围电路等均可集成在一块芯片上构成单片微型计算机,简称为单片机。单片机具有体积小、成本低,性能稳定、使用寿命长等特点
5、。其最明显的优势就是可以嵌入到各种仪器、设备中,这是其他计算机和网络都无法做到的。TLC5615为美国仪器1999年推出的产品,是具有串行接口的数模转换器,其输出为电压型,最大输出电压是基准电压值的两倍。带有上电复位功能,即把DAC寄存器复位至全零。TLC5615性价比高,目前在国市场很方便购买。1.2信号发生器的分类信号发生器应用广泛,种类繁多,性能各异,分类也不尽一致。按照频率围分类可以分为:超低频信号发生器、低频信号发生器、视频信号发生器、高频波形发生器、甚高频波形发生器和超高频信号发生器。按照输出波形分类可以分为:正弦信号发生器和非正弦信号发生器,非正弦信号发生器又包括:脉冲信号发生器
6、,函数信号发生器、扫频信号发生器、数字序列波形发生器、图形信号发生器、噪声信号发生器等。按照信号发生器性能指标可以分为一般信号发生器和标准信号发生器。前者指对输出信号的频率、幅度的准确度和稳定度以与波形失真等要求不高的一类信号发生器。后者是指其输出信号的频率、幅度、调制系数等在一定围连续可调,并且读数准确、稳定、屏蔽良好的中、高档信号发生器。1.3 研究容本文是做基于单片机的信号发生器的设计,将采用编程的方法来实现三角波、锯齿波、矩形波、正弦波的发生。根据设计的要求,对各种波形的频率和幅度进行程序的编写,并将所写程序装入单片机的程序存储器中。在程序运行中,当接收到来自外界的命令,需要输出某种波
7、形时再调用相应的中断服务子程序和波形发生程序,经电路的数/模转换器和运算放大器处理后,从信号发生器的输出端口输出。2 方案的设计与选择2.1 方案的比较方案一:采用单片函数发生器(如8038),8038可同时产生正弦波、方波等,而且方法简单易行,用D/A转换器的输出来改变调制电压,也可以实现数控调整频率,但产生信号的频率稳定度不高。方案二:采用锁相式频率合成器,利用锁相环,将压控振荡器(VCO)的输出频率锁定在所需频率上,该方案性能良好,但难以达到输出频率覆盖系数的要求,且电路复杂。方案三:采用单片机编程的方法来实现。该方法可以通过编程的方法来控制信号波形的频率和幅度,而且在硬件电路不变的情况
8、下,通过改变程序来实现频率的变换。此外,由于通过编程方法产生的是数字信号,所以信号的精度可以做的很高。鉴于方案一的信号频率不够稳定和方案二的电路复杂,频率覆盖系数难以达标等缺点,所以决定采用方案三的设计方法。它不仅采用软硬件结合,软件控制硬件的方法来实现,使得信号频率的稳定性和精度的准确性得以保证,而且它使用的几种元器件都是常用的元器件,容易得到,且价格便宜,使得硬件的开销达到最省。2.2 设计原理数字信号可以通过数/模转换器转换成模拟信号,因此可通过产生数字信号再转换成模拟信号的方法来获得所需要的波形。89C51单片机本身就是一个完整的微型计算机,具有组成微型计算机的各部分部件:中央处理器C
9、PU、随机存取存储器RAM、只读存储器ROM、I/O接口电路、定时器/计数器以与串行通讯接口等,只要将89C51再配置键盘与其接口、显示器与其接口、数模转换与波形输出、指示灯与其接口等四部分,即可构成所需的波形发生器,其信号发生器构成原理框图如图2.1所示。 输出AT89C51单片机滤波放大D/A转换器接口电路图2.1 信号发生器原理框图AT89C51是整个波形发生器的核心部分,通过程序的编写和执行,产生各种各样的信号,并从键盘接收数据,进行各种功能的转换和信号幅度的调节。当数字信号经过接口电路到达转换电路,将其转换成模拟信号也就是所需要的输出波形。2.3 设计功能(1)本方案利用8155扩展
10、8个独立式按键,6个LED显示器。其中“S0”号键代表方波输出,“S1”号键代表正弦波输出,“S2”号键代表三角波输出,“S3” 号键代表锯齿波输出。(2)“S4”号键为10Hz的频率信号,“S5”号键为100Hz的频率信号,“S6”号键为500Hz的频率信号,“S7”号键为1KHz的频率信号,6个LED显示器输出信号的频率值,选用共阳极LED。(3)利用两片DAC0832实现幅度可调的信号源,(其中一片用来调节幅度,另外一片用来实现信号源的输出)。(4)频率围:101000Hz。(5)输出波形幅度为05V。3 硬件设计3.1 硬件原理框图硬件原理方框图如图3.1所示。波形输出放大电路复位电路
11、显示电路数/模转换电路键盘电路单片机图3.1 硬件原理框图3.2 系统PCB板的设计PCB即印刷电路板,是电子电路的承载体。在现代电子产品中,几乎都要使用PCB。PCB板的设计是电路设计的最后一个环节,也是对原理电路的再设计。因此PCB板的设计是理论设计到实际应用一个十分重要的容。印制电路板(PCB)是电子产品中电路元件和器件的支撑件它提供电路元件和器件之间的电气连接。PCB设计的好坏对抗干扰能力影响很大因此,在进行PCB设计时必须遵守印制电路板设计原则和抗干扰措施的一般原则,并应符合抗干扰设计的要求。本次设计采用Altium公司PROTEL系列设计完成SCH到PCB的设计,并且手工完成电路焊
12、接以与整机的装配。3.3 主控电路AT89C51单处机部设置两个16位可编程的定时器/计数器T0和T1,它们具有计数器方式和定时器方式两种工作方式与4种工作模式。在波形发生器中,将其作定时器使用,用它来精确地确定波形的两个采样点输出之间的延迟时间。模式1采用的是16位计数器,当T0或T1被允许计数后,从初值开始加计数,最高位产生溢出时向CPU请求中断。中断系统是使处理器具有对外界异步事件的处理能力而设置的。当中央处理器CPU正在处理某件事的时候外界发生了紧急事件,要求CPU暂停当前的工作,转而去处理这个紧急事件。在波形发生器中,只用到片定时器计数器溢出时产生的中断请求,即是在AT89C51输出
13、一个波形采样点信号后,接着启动定时器,在定时器未产生中断之前,AT89C51等待,直到定时器计时结束,产生中断请求,AT89C51响应中断,接着输出下一个采样点信号,如此循环产生所需要的信号波形6。如图3.2所示,AT89C51从P0口接收来自键盘的信号,并通过P2口输出一些控制信号,将其输入到8155的信号控制端,用于控制其信号的输入、输出。如果有键按下,则在读控制端会产生一个读信号,使单片机读入信号。如果有信号输出,则在写控制端产生一个写信号,并将所要输出的信号通过8155的PB口输出,并在数码管上显示出来。图3.2 主控电路图3.4数/模转换电路由于单片机产生的是数字信号,要想得到所需要
14、的波形,就要把数字信号转换成模拟信号,所以该文选用价格低廉、接口简单、转换控制容易TLC5615。TLC5615由10 位 DAC 电路;一个 16 位移位寄存器, 接受串行移入的二进制数,并且有一个级联的数据输出端DOUT;并行输入输出的 10 位 DAC 寄存器, 为 10 位 DAC 电路提供待转换的二进制数据;电压跟随器为参考电压端REFIN提供很高的输入阻抗,大约10M;2 电路提供最大值为 2 倍于 REFIN 的输出;上电复位电路和控制电路组成。由于TLC5615电压型输出,所以不用外接运放,使之在使用时更为方便TLC5615各引脚与其功能如下:DIN: 串行数据输入端; SCL
15、K: 串行时钟输入端; /CS: 芯片选用通端,低电平有效; DOUT: 用于级联时的串行数据输出端; AGND: 模拟地; REFIN:基准电压输入端, 2V (VDD - 2); OUT: DAC 模拟电压输出端; VDD: 正电源端,4.55.5V ,通常取 5V。图3.3.1TLC引脚图TLC5615的工作方式有两种: 第一种方式由图3.3可以看出16 位移位寄存器分为高 4 位虚拟位、低两位填充位以与 10位有效位。在单片 TLC5615 工作时,只需要向 16 位移位寄存器按先后输入 10位有效位和低 2 位填充位, 2 位填充位数据任意,这是第一种方式,即 12 位数据序列。第二
16、种方式为级联方式, 即 16 位数据列,可以将本片的 DOU T 接到下一片的 DIN , 需要向 16 位移位寄存器按先后输入高 4 位虚拟位、10 位有效位和低 2 位填充位, 由于增加了高 4 位虚拟位, 所以需要 16 个时钟脉冲。图3.3.2TLC5615功能框图3.5 按键接口电路图3.4为键盘接口电路的原理图,图中键盘和8155的PA口相连,AT89C51的P0口和8155的D0口相连,AT89C51不断的扫描键盘,看是否有键按下,如有,则根据相应按键作出反应。其中“S0”号键代表方波输出,“S1”号键代表正弦波输出,“S2”号键代表三角波输出。 “S3”号键代表锯齿波输出,“S
17、4”号键为10Hz的频率信号,“S5”号键为100Hz的频率信号,“S6”号键为500Hz的频率信号,“S7”号键为1KHz的频率信号3。 图3.4 按键接口3.6 时钟电路8051单片机有两个引脚(XTAL1,XTAL2)用于外接石英晶体和微调电容,从而构成时钟电路,其电路图如图3.5所示。电容C1、C2对振荡频率有稳定作用,其容量的选择为30pf,振荡器选择频率为12MHz的石英晶体。由于频率较大时,三角波、正弦波、锯齿波中每一点的延时时间为几微秒,故延时时间还要加上指令时间才能获得较大的频率波形9。 图3.5 时钟电路3.7 显示电路显示电路是用来显示波形信号的频率,使得整个系统更加合理
18、,从经济的角度出发,所以显示器件采用LED数码管显示器。而且LED数码管是采用共阳极接法,当主控端口输出一个低电平后,与其相对应的数码管即变亮,显示所需数据。其器件模型如图3.6所示。图3.6LED显示电路4 软件设计4.1 程序流程图本文中子程序的调用是通过按键的选择来实现,在取得按键相应的键值后,启动计时器和相应的中断服务程序,再直接查询程序中预先设置的数据值,通过转换输出相应的电压,从而形成所需的各种波形。主程序的流程图如图4.1所示,在程序开始运行之后,首先是对8155进行初始化,之后判断信号频率值,如符合所需的频率,则重置时间常数,并通过显示器显示出来,不符则返回。在中断结束后,还要
19、来判断波形是否符合,如符合,则显示其频率,不符则返回,重新判断。图4.1 主程序流程图图4.2为各波形子程序的流程图。如图所示,在中断服务子程序开始后,通过判断来确定各种波形的输出,当判断选择的不是方波后,则转向对正弦波的判断,如此反复。如果选择的是方波,则用查表的方法求出相应的数据,并通过D/A转换器将数据转换成模拟信号,形成所需波形信号。图4.2 子程序流程图4.2 软件与联机调试Keil 4是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。用过汇编语言后再使用C来开发,体会更加
20、深刻。Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。Keil 4件是一个基于32位Windows环境的应用程序,支持C语言和汇编语言编程,其6.0以上的版本将编译和仿真软件统一为Vision(通常称为V2)。Keil提供包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在的完整开发方案, 4.3 主控程序调试应用Keil进行软件仿真开发的主要步骤为:编写源程序
21、并保存建立工程并添加源文件设置工程编译/汇编、连接,产生目标文件程序调试。成功编译/汇编、连接后,选择菜单Debug-Start/Stop Debug Session(或按Ctrl+F5键)进入程序调试状态,Keil提供对程序的模拟调试功能,建一个功能强大的仿真CPU以模拟执行程序。Keil能以单步执行(按F11或选择Debug-Step)、过程单步执行(按F10或选择Debug-Step Over)、全速执行等多种运行方式进行程序调试。如果发现程序有错,可采用在线汇编功能对程序进行在线修改(Debug-Inline Assambly),不必执行先退出调试环境、修改源程序、对工程重新进行编译/
22、汇编和连接、然后再次进入调试状态的步骤。对于一些必须满足一定条件(如按键被按下等)才能被执行的、难以用单步执行方式进行调试的程序行,可采用断点设置的方法处理(Debug-Insert/Remove Breakpoint或Debug-Breakpoints等)。在模拟调试程序后,还须通过编程器将.hex目标文件烧写入单片机中才能观察目标样机真实的运行状况。5 实训心得体会课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域, 在生活中可以说得是
23、无处不在。因此作为二十一世纪的大学来说掌握单片机的开发技术是十分重要的。回顾起此次单片机课程设计,我仍感慨颇多,的确,从选题到定稿,从理论到实践,在好几个星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过
24、程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说不懂一些元器件的使用方法,对单片机汇编语言掌握得不好通过这次课程设计之后,一定把以前所学过的知识重新温故。这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在宋阳老师的辛勤指导下,终于游逆而解。同时,在宋阳老师那里我学得到很多实用的知识,在次我表示感!同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感!参考文献1 程全.基于AT89C52实现的多种波形发生器的设计J.师学院学报,2005.22(5):5758.2 周明德.微型计算机系统原理与应用M.:清华大学,2002.341364.3 乐善.
25、微型计算机接口技术与应用M.:航空航天大学,2001.258264.4 童诗白.模拟电路技术基础M.:高等教育,2000.171202.5 杜华.任意波形发生器与应用J.国外电子测量技术,2005.1:3840.6 友德.单片微型机原理、应用与实践M.:复旦大学,2004.4044. 7 程朗.基于8051单片机的双通道波形发生器的设计与实现J.计算机工程与应用,2004.8:100103.8 永瑞.电子测量技术基础M.:电子科技大学,2006.61101.9 叶紫. MCS-51单片机应用教程M.:清华大学,2004.232238.附录1电路原理图与PCB图附录2 源程序 #include
26、#include #define count 1000 sbit SCLK =P21 ; /定义端口sbit DIN =P22; sbit CS =P20 ;unsigned int temp;/中间变量 unsigned int f1,f2,f3,f4; const seven_seg_point10=0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10;/有小数点的数码管显示 unsigned char counter4=0xef,0xdf,0xbf,0x7f;/定义位选 /*定义按键*/ sbit K1 =P30;/方波 sbit K2 =P
27、31;/三角波 sbit K3 =P32;/正弦波 sbit K4 =P33; /锯齿波 sbit K5 =P34; /频率加 sbit K6 =P35; /频率减 /sbit K5 =P16; /步进 /sbit K6 =P17; /确认输出unsigned int num,wave=1;/中间变量unsigned char j=0; /j_片选,vout_电压输出char scan1,scan2,scan3,scan4;unsigned char seven_seg= 0xC0, /0 0xF9, /1 0xA4, /2 0xB0, /3 0x99, /4 0x92, /5 0x82, /
28、6 0xF8, /7 0x80, /8 0x90, /9 0x88, /A 0x83, /B 0xC6, /C 0xA1, /D 0x86, /E 0x8E, /F 0x89, /H 0xC7, /L 0xC8, /n 0xC1, /u 0x8C, /P 0xA3, /o0xBF, /- 0xFF, /熄灭 0xFF /自定义 ;/*TI 10位DA TLC5615的驱动程序 -调用方式: void da5615(unsigned int da)函数说明: TI 10位DA TLC5615的驱动程序-*/void da5615(unsigned int da) /DA子函数unsigned c
29、har i;da=6; CS=0;SCLK=0;for (i=0;i12;i+)DIN=(bit)(da&0x8000);SCLK=1;da=1;SCLK=0;CS=1;SCLK=0;for (i=0;i12;i+); /12位数值转换成串行输给DA芯片 void delay(int x)/延时int i,j;for(i=0;ix;i+);void vout_sin() /输出正弦波 float x,vout; /用于正弦波发生器 for(x=-3.1415;x3.1415;x+=0.05)/正弦波发生器 vout=512*(1+sin(x)/2; /输出值Vout必须大于0 temp=(un
30、signed int)vout;da5615(temp);/delay(2);delay(2); P1=0xfe;/*三角波*/void sanjiao() unsigned int i; for(i=0;i0;i-) temp=i; da5615(temp); P1=0xfb;/*锯齿波*/void juchi() temp+; if(temp=512) temp=0; da5615(temp); delay(f1); P1=0xfd;/*方波*/void fangbo() da5615(512); delay(f1); da5615(0); delay(f1);P1=0xf7;void T
31、imer1_ISR(void) interrupt 3 using 1unsigned char j;EA = 0; /禁止全局中断TR1 = 0; P2=counterj&0xf0;/delay(2);switch(j) case 0:P0=0xff;delay(2);P0=seven_segscan1;break; case 1:P0=0xff;delay(2);P0=seven_segscan2;break; case 2:P0=0xff;delay(2);P0=seven_segscan3;break; case 3:P0=0xff;delay(2);P0=seven_segscan4
32、;break; default:break;/j为其他情况是跳出循环 j+;if(j=4) j=0; TH1 = 0xEC; /定时5msTL1 = 0x78;EA = 1;TR1 = 1;void Init_Timer0(void) TMOD |= 0x01; TH0=(65536-25000)/256; / Init value/ TL0=(65536-25000)%256; TH1 = 0xEC; /定时5ms TL1 = 0x78; EA=1; ET1=1; TR1=1; / interupt enable /ET0=1; / enable timer0 interrupt / TR0
33、=1;EX0=1;/外部中断0开 IT0=1;/边沿触发 main() f1=f2=f3=f4=0; Init_Timer0();while(1) / da5615(temp); /此时接入LED灯能看到灯的亮度逐渐变化 /delay(500); /vout_sin(); /DA值增加1 满后(1023)自动溢出 / sanjiao(); /juchi(); /fangbo(); /delay(1); / key(); switch(wave)case 1: vout_sin();break;case 2: juchi();break;case 3: sanjiao();break;case
34、4: fangbo();break; void Timer0_isr(void) interrupt 1 using 1 if(K1=0) scan3+; if(scan3=10) scan3=9; f1=scan3*10+scan2; if(K2=0) scan3-; if(scan30) scan3=0; f1=scan3*10+scan2; if(K5=0) scan2+; if(scan2=10) scan2=9; f1=scan3*10+scan2; if(K6=0) scan2-; if(scan20) scan2=0; f1=scan3*10+scan2; void ISR_Key(void) interrupt 0 using 1 /EX0=0; if(K3=0)wave+;if(wave=5) wave=1;