片单机课程设计报告简易波形发生器大学论文.doc
题目:简易波形发生器 单片机课程设计报告 学院:信息工程学院 班级:通信13-2班 指导教师: 小组成员:目录1.1 简易波形发生器的背景介绍1.2 简易波形发生器的设计思路1.2.1 简易波形发生器的工作流程1.2.2 简易波形发生器的需求分析与设计1.2.3 D/A芯片的工作原理1.2.4 I2C接口总线工作原理1.3 简易波形发生器的硬件设计1.3.1简易波形发生器的硬件模块划分1.3.2 简易波形发生器硬件电路图1.3.3 硬件模块基础单刀单掷开关1.3.4 硬件模块基础MAX5171.4 简易波形发生器的软件设计1.4.1 简易波形发生器的软件模块划分和流程设计1.4.2 MAX517的驱动函数设计1.4.3 简易波形发生器的软件综合和程序清单1.4.4 简易波形发生器的应用系统仿真1.5 课程设计的体会1.6 参考文献1.7 课程设计源程序代码1.1 简易波形发生器的背景介绍 信号发生器是最常用的测试仪器之一,主要用于产生被测电路所需特定参数的电测试信号。在测试,研究或调整电子电路及设备时,为测定电路的一些电参量,如测量频率响应,噪声系数及电压表定度等,都要求提供符合所定技术条件的电信号,以模拟在实际工作中使用的待测设备的激励信号。当要求进行系统的稳态特性测量时,需使用振幅,频率已知的正弦信号源;当测试系统的瞬态特性时,又需要使用前沿时间,脉冲宽度和重复周期已知的矩形脉冲源。并且要求信号源输出的参数,如频率,波形,输出电压或功率等,能在一定范围内进行精确调整,有好的稳定性,有输出指示。 信号发生器可以根据输出波形的不同,划分为正弦信号发生器,矩形脉冲信号发生器,函数信号发生器和随机信号发生器4类。此设计的简易波形发生器就是一个产生频率固定,最大幅度为5V的正弦波,锯齿波和三角波的仪器。1.2 简易波形发生器的设计思路1.2.1 简易波形发生器的工作流程简易波形发生器的工作流程如图所示。51单片机系统 初始化检查用户 输入 三角波按键被按下 锯齿波按键被按下 正弦波按键被按下 输出三角波 输出锯齿波 输出正弦波1.2.2 简易波形发生器的需求分析与设计设计简易波形发生器系统,需要考虑如下几个方面:1) 如何产生相应的波形;2) 如何给用户提供相应的选择通道;3) 需要设计合适的单片机软件。1.2.3 D/A芯片的工作原理 在51单片机应用系统中,通常使用D/A芯片来产生对应得模拟量,包括各种波形。D/A芯片的组成如图所示,其输入包括数字信号,基准参考电压,供电电源;而输出为模拟电流信号或电压信号。 供电电源 D/A通道+ -数字输入正电压信号 负电压信号 模拟输出 基准电压参考 图1.2D/A芯片的组成D/A通道的数模拟转换原理可以分为有权电阻D/A转换和T型网络转换两种,大多数D/A通道芯片是由电阻阵列和多个电流,电压开关组成,其根据输入数字信号来切换多路开关,以产生对应的输出电流和电压。为了保证D/A通道芯片输入引脚上的数字信号的稳定,一般来说,D/A芯片内部常常带有数据锁存器和地址译码电路,以便于51单片机的接口连接。D/A通道芯片按照数字输入位数可以分为8位,10位,12位,16位等,按照和51 单片机的接口方式可分为并行D/A通道芯片和串行D/A通道芯片;按照转换后输出的模拟量类型来分可分为电压输入型D/A通道芯片和电流输出型D/A通道芯片。D/A通道芯片的主要性能指标如下:1 分辨率。2 转换时间。3 输出模拟量的类型与范围。4 满刻度误差。5 接口方式。1.2.4 I2C接口总线工作原理I2C是一种串行总线的外设接口,它采用同步方式串行接收或发送信息,两个设备在同一个时钟下工作。I2C总线只用两根线:串行数据SDA(Serial Data)、串行时钟SCL(Serial Clock)。 由于I2C只有一根数据线,因此其发送信息和接收信息不能同时进行。信息的发送和接收只能分时进行。I2C串行总线工作时传输速率最高可达400K bit/s。I2C总线上的所有器件的SDA线并接在一起,所有器件的SCL线并接在一起,且SDA线和SCL线必须通过上拉电阻连接到正电源。I2C总线的数据传输协议要比SPI总线复杂一些,因为I2C总线器件没有片选控制线,所以I2C总线数据传输的开始必须由主器件产生通信的开始条件(SCL高电平时,SDA产生负跳变);通信结束时,由主器件产生通信的结束条件(SCL高电平时,SDA产生正跳变)。SDA线上的数据在SCL高电平期间必须保持稳定,否则会被误认为开始条件或结束条件,只有在SCL低电平期间才能改变SDA线上的数据。I2C总线的数据传输波形图如下图所示。1.3 简易波形发生器的硬件设计1.3.1简易波形发生器的硬件模块划分简易波形发生器的硬件模块划分如图所示,由51单片机,波形选择通道模块和D/A通道芯片模块组成,其各个部分详细说明如下: 51单片机:简易波形发生器系统的核心控制器; 波形选择通道模块:提供用户选择通道,用以选择产生的波形; D/A通道芯片模块:用于将相应的数字量转化为模拟量。 波形选择通道模块 51单片机 D/A通道芯片模块1.3.2 简易波形发生器硬件电路图 简易波形发生器的硬件电路图,三个单刀单掷开关分别连接到P1.0,P1.2和P1.4引脚上,作为用户的选择输入模块;使用P2.0和P2.1引脚扩展了一个I2C总线接口的串行D/A芯片(MAX517)作为波形发生模块通道。 简易波形发生器的硬件电路表:简易波形发生器电路中涉及的典型器件说明器件名称器件编号说明晶体振荡器X151单片机的振荡源51单片机U152单片机,系统的核心控制器件电容C1 C2 C3滤波,储能器件电阻R1上拉单刀单掷开关用户选择波形输出MAX517U2D/A通道1.3.3 硬件模块基础单刀单掷开关 单刀单掷开关属于同轴开关的一种,按照接口数量定义,代号为#P#T,另外还有单刀双掷(SPDT)、双刀双掷(DPDT)、单刀六掷(SP6T)等,在实际使用中,其完全等同于一个不会自动弹起的独立按键。1.3.4 硬件模块基础MAX517MAX517是美信公司出品的8位电压输出型D/A芯片,其采用I2C总线接口,内部提供精密输出缓冲源,支持双极性工作方式,其主要特点如下:1 单5V电源供电;2 提供8位精度的电压输出;3 输出缓冲放大可以为双极性;4 基准输入可以为双极性。MAX517的引脚封装结构,其详细说明如下。1) OUT0:D/A转换输出引脚。2) GND:电源地信号引脚。3) SCL:I2C接口总线时钟信号引脚。4) SDA:I2C接口总线时钟数据引脚。5) AD1、AD0:I2C接口总线地址选择引脚,可以设定I2C总线上的多个MAX517的I2C地址。6) VDD:电源正信号输入引脚。7) REF0:基准电压输入引脚。MAX517是个I2C总线接口器件,其有唯一的I2C地址,AD1和AD0引脚可用于在同一条I2C总线上挂接多个MAX517时选择地址。MAX517的I2C地址结构参见表1,从表中能看到在同一条I2C总线上最多可以挂接4片MAX517。表1,MAX517的I2C地址BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT001011AD1AD00MAX517的控制寄存器的格式参见表2,在I2C的总线操作中,使用“地址+命令字节”的格式把MAX517的命令字写入内部控制寄存器。表2,MAX517控制寄存器的格式BIT7BIT6BIT5BIT4BIT3BIT2BIT1BIT0R2R1R0RSTPD保留保留A01) R2R0:保留为,永远为0。2) RST:复位位,在该位被置“1”时,MAX517的所有寄存器被复位。3) PD:电源工作状态位,当该位为“1”时,MAX517进入休眠状态,当该位为“0”时,进入正常工作状态。4) A0:用于判断将数据写入哪一个寄存器中,在MAX517中,此位永远为“0”。 1.4 简易波形发生器的软件设计 简易波形发生器的软件设计重点是使用51单片机的普通I/O引脚模拟I2C总线时序,对MAX517进行读/写操作。1.4.1 简易波形发生器的软件模块划分和流程设计简易波形发生器的软件可划分为I2C总线时序读/写MAX517驱动库函数和波形产生函数两个部分,其流程如图所示。 初始化51单片机 初始化I2C总线检查单刀单掷开关状态断开 断开断开三角波开关=1锯齿波开关=1正弦开关=1 闭合 闭合 闭合控制MAX517送出锯齿波控制MAX517送出正弦波控制MAX517送出三角波 简易波形发生器的软件流程1.4.2 MAX517的驱动函数设计 MAX517的驱动函数模块主要用于对MAX517的相关控制,其包括了如下函数。1. Viod I2C_Start():启动I2C总线。2. Viod I2C_Init():初始化I2C总线。3. I2C_Delay(unsigned int I2C_VALUE):I2C总线的延时程序,其延时值为参数I2C_VALUE控制。4. Viod I2C_write(char dat):通过I2C总线写一个字节数据。5. Bit I2C_GetAck():I2C总线应答函数。6. Viod I2C_stop():停止I2C总线。7. Bit write_addr(unsigned char addr,bit mod):向MAX517写入一个地址数据,addr为地址数据,如果写入成功则返回1,否则返回0。8. Bit write_data(unsigned char dat):向MAX517写入一个数据,dat为数据。1.4.3 简易波形发生器的软件综合和程序清单表1 Proteus电路器件列表 器件名称 库 子库 说明AT89C52Microprocessor ICs8051Family51单片机RESResistorsGeneric通用电阻CAPCapacitorsGeneric电容CAP-ELECCapacitorsGeneric极性电容CRYSTALMiscellaneous 晶体震荡器MAX517Data ConvertersD/AConverterMAX517芯片SWITCHSwitches&RelaysSwitches开关1.4.4 简易波形发生器的应用系统仿真单击运行,合上对应的单刀单掷开关,可以看到对应的波形输出,如图所示。三角波输出正弦波输出锯齿波输出1.5 课程设计的体会 在这次课程设计中,我们运用到了以前所学的专业课知识,如:cad制图、汇编语言、模拟和数字电路知识等。虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。后,要做好一个课程设计,就必须做到:在设计程序之前,对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在设计课程过程中遇到问题是很正常德,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题的课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。设计过程,好比是我们人类成长的历程,常有一些不如意,但毕竟这是第一次做,难免会遇到各种各样的问题。在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。我们通过查阅大量有关资料,并在小组中互相讨论,交流经验和自学,若遇到实在搞不明白的问题就会及时请教老师,使自己学到了不少知识,也经历了不少艰辛,但收获同样巨大。通过这次课程设计我也发现了自身存在的不足之处,虽然感觉理论上已经掌握,但在运用到实践的过程中仍有意想不到的困惑,经过一番努力才得以解决。这也激发了我今后努力学习的兴趣,我想这将对我以后的学习产生积极的影响。通过这次设计,我懂得了学习的重要性,了解到理论知识与实践相结合的重要意义,学会了坚持、耐心和努力,这将为自己今后的学习和工作做出了最好的榜样。我觉得单片机的课程设计是很有意义的。更重要的是如何把自己平时所学的东西应用到实际中。虽然自己对于这门课懂的并不多,很多基础的东西都还没有很好的掌握,觉得很难,也没有很有效的办法通过自身去理解,但是靠着这一个多礼拜的“学习”,在小组同学的帮助和讲解下,渐渐对这门课逐渐产生了些许的兴趣,自己开始主动学习并逐步从基础慢慢开始弄懂它。我认为这个收获应该说是相当大的。觉得课程设计反映的是一个从理论到实际应用的过程,但是更远一点可以联系到以后毕业之后从学校转到踏上社会的一个过程。小组人员的配合相处,以及自身的动脑和努力,都是以后工作中需要的。1.6 参考文献1. 51单片机应用开发25例张新 陈跃琴 编著2. 单片机课程设计蔡明文 冯先成 主编3. 单片机原理及应用张毅刚 主编1.7 课程设计源程序代码MAX517驱动函数的应用代码#include<AT89X52.h>#include<math.h>sbit SCL=P20;sbit SDA=P21;void Delay(unsigned int I2C_Delay_t)while(-I2C_Delay_t!=0);void I2C_Delay(unsigned int I2C_VALUE) while(-I2C_VALUE!=0); /停止I2C总线void I2C_Init() SCL=1; I2C_Delay(5); SDA=1; I2C_Delay(5); /启动I2C总线void I2C_Start() SDA=1; I2C_Delay(5); SCL=1; I2C_Delay(5); SDA=0; I2C_Delay(5); SCL=0; I2C_Delay(5); /I2C总线延时void I2C_Write(char dat) unsigned char t=8; do SDA=(bit)(dat & 0x80); dat<<=1; SCL=1; I2C_Delay(5); SCL=0; I2C_Delay(5); while(-t!=0);/取得总线应答bit I2C_GetAck() bit ack; SDA=1; I2C_Delay(5); SCL=1; I2C_Delay(5); ack=SDA; SCL=0; I2C_Delay(5); return ack;/停止I2C总线void I2C_Stop() unsigned int t=10; SDA=0; I2C_Delay(5); SCL=1; I2C_Delay(5); SDA=1; I2C_Delay(5);while(-t!=0); /在下一次产生start之前,要加一定的延时/写MAX517地址bit write_addr(unsigned char addr,bit mod) unsigned char address; address=addr<<1; if(mod) address+; I2C_Start(); I2C_Write(address); Delay(10); if(I2C_GetAck() return 1; return 0;/MAX517写数据bit write_data(unsigned char dat) I2C_Write(dat); if(I2C_GetAck() return 1; return 0;/停止void stop() I2C_Stop(); I2C_Init();简易波形发生器的软件综合代码#include<AT89X52.h>#include<math.h>#define ADDR1 0x2csbit key_sin=P10;sbit key_tran=P12;sbit key_tooth=P14;sbit SCL=P20;sbit SDA=P21;unsigned char code sinabc256= /正弦表0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xee,0xee,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6f,0x72,0x76,0x79,0x7c,0x80;bit write_addr(unsigned char,bit);/第一个参数表示地址,第二个参数表示读(1)/写(0)bit write_data(unsigned char);/第一个参数表示数据,第二个参数表示命令字void stop();void Delay(unsigned int);void I2C_Init();void main(void) unsigned char i; loop:I2C_Init();while(1) if(key_sin=0) /产生正弦波 while(1) for(i=192;i<255;i+) write_addr(ADDR1,0); write_data(0); write_data(sinabci);stop();if(!(key_tran!=0&&key_tooth!=0)goto loop;for(i=0;i<192;i+) write_addr(ADDR1,0); write_data(0); write_data(sinabci);stop();if(!(key_tran!=0&&key_tooth!=0)goto loop; if(key_tran=0)/产生三角波 while(1) for(i=0;i<255;i+) write_addr(ADDR1,0); write_data(0); write_data(i); stop(); if(!(key_sin!=0&&key_tooth!=0) goto loop; for(;i>0;i-) write_addr(ADDR1,0); write_data(0); write_data(i); stop(); if(!(key_sin!=0&&key_tooth!=0) goto loop; if(key_tooth=0)/产生锯齿波 while(1) for(i=0;i<255;i+) write_addr(ADDR1,0); write_data(0); write_data(i); stop(); if(!(key_tran!=0&&key_sin!=0) goto loop;