找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 38403|回复: 12
收起左侧

基于51单片机信号发生器的设计论文

  [复制链接]
ID:311212 发表于 2018-4-18 20:54 | 显示全部楼层 |阅读模式

目  录

摘  要
Abstract
引  言
第1章  绪  论
1.1  选题背景、意义
1.2基本功能简介
第二章  硬件设计与原理
2.1 总设计框图
2.2 硬件设计分析
2.2.1 电源的设计的选择
2.2.2  核心控制的选择            
2.2.3  键盘的选择
2.3 单片机最小系统
2.4按键输入电路
2.5 D/A转换电路
第三章  软件设计与分析
3.1 软件设计的组成
3.2定时程序设计            
3.3  各部分软件分析
3.3.1  调节部分——频率子函数
3.3.2  调节部分——方波的占空比子函数
3.3.3  波形发生子函数
3.3.4  定时器0中断子函数
3.3.5  定时器1中断处理子函数
3.3.6  主函数
3.4  总源程序
第四章 软件介绍
4.1 PROTEUS简介
4.2 PROTEL 99 SE简介
4.2.1 电路工程设计部分
4.2.2 电路仿真与PLD部分
4.3 Protel 99 SE的功能特性
4.4 Protel99SE快捷键大全
第五章 系统调试与软件仿真
5.1 硬件调试
5.2  Keil uVision2软件调试
总结
致  谢
附录
参考文献



摘  要

本文介绍一种用STC89C51RC单片机构成的波形发生器,可产生方波、三角波、正弦波、锯齿波四种波形,波形的频率可由按键改变,并可根据需要选择单极性输出或双极性输出,具有线路简单、结构紧凑、性能优越等特点。文章给出了源代码,通过仿真测试,其性能指标达到了设计要求。


引  言

21世纪,单片机的发展非常的迅速。单片机是把主要计算机功能部件都集成在一块芯片上的微型计算机。它是一种集计数和多种接口于一体的微控制器,被广泛应用在智能产品和工业自动化上,而51单片机是个单片机中最为典型和最有代表性的一种。

最近几年来,随着科技的飞速发展,单片机领域正在不断的走向社会各个角落,还带动传统控制检测日新月异更新。在实时运作和自动控制的单片机应用到系统中,单片机如今是作为一个核心部件来使用,仅掌握单片机方面知识是不够的,还应根据其具体硬件结构,以及针对具体应用对象特点的软件结合,加以完善。“单片机原理及应用课程设计”是电子类专业的学科基础科,它是继“汇编语言程序设计”,“接口技术”等课程之后开出的实践环节课程。


第1章  绪  论
1.1  选题背景、意义

当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未有的速度被单片机智能化控制所取代。单片机具有体积小、功能强、成本低、应用面广等优点,可以说智能化控制与自动控制的核心就是单片机。本设计是以AT89C52芯片的电路为基础,外部加上输入设备和显示设备,以此来实现信号发生器的硬件电路,通过软件程序来控制单片机实现波形的输出。对于不同型号的单片机只需要相应的改变一下地址即可。该软、硬件系统具有很好的通用性,很高的实际使用价值,为广大的单片机爱好者提供了很好的借鉴。

1.2基本功能简介
  • 方波
  • 三角波
  • 正弦波
  • 锯齿波
  • 频率可改变

第二章  硬件设计与原理

以AT89C52单片机为核心,起着控制作用。系统包括D/A转换电路、复位电路、时钟电路、按键电路。设计思路分为五个模块:复位电路、晶振电路模块、AT89C52、D/A转换电路、按键电路这五个模块。

2.1 总设计框图

图2-1 总设计框图

2.2 硬件设计分析
2.2.1
电源的设计的选择

   方案一:采用电池供电,但是耗费电源而且不节能环保顾不采用。

方案二:采用系统电源使用外接直流5伏。即就是usb数据线供电,才方案具有简单方便节能高效等特点。

基于以上分析,本次设计我采用方案二。

2.2.2  核心控制的选择

核心控制器主要用于对输入,D/A转换,信号输出等模块进行控制。相当于人的大脑故非常重要和复杂,控制器的选择有以下两种方案。

方案一:采用FPGA(现场可编程门列阵)作为系统的控制器。FPGA可以实现各种复杂的逻辑功能,规模大,密度高,它将所有器件集成在一块芯片上,减小了体积,提高了稳定性。但由于本设计对数据处理的速度要求不高,FPGA的高速处理的优势得不到充分体现,并且由于其集成度高,使其成本偏高,同时由于芯片的引脚较多,实物硬件电路板布线复杂,加重了电路设计和实际焊接的工作。

方案二:采用单片机作为系统控制器的作为其核心的方案。单片机算术运算功能强、软件编程灵活、自由度大,可以用软件编程实现各种算法和逻辑控制,并且由于其功耗低、体积小、技术成熟和成本低等优点,使其在各个领域应用广泛。

基于以上分析,本次设计我采用方案二。

2.2.3  键盘的选择

键盘是单片机不可缺少的输入设备,是实现人机对话的纽带。键盘按结构形式可以分为非编码键盘和编码键盘,前者用软件方法产生键码,而后者则用硬件方法来产生键码。在单片机中使用的都是非编码键盘,因为非编码键盘结构简单,成本低廉,非编码键盘的类型很多,常用的有独立式键盘,行列式键盘等。

方案一:独立式键盘            

独立式键盘接口中使用几根I/O线,就有几个按键,这种类型的键盘,其按键比较少,且键盘中各按键的工作互不干扰。因此可以根据实际需要对键盘中的按键灵活编码。独立式键盘的缺点是需要占用比较多的I/O口线,当单片机应用系统键盘中需要的按键比较少或I/O口线比较富余时,可以采用这样类型的键盘。

方案二:行列式键盘

行列式键盘是用N条I/O线作为行线,M条I/O线作为列线组成的键盘,按键在行线和列线的每个交叉点上。这种形式的键盘结构,能够有效地提高单片机系统中I/O的利用率。

CPU对键盘的扫描可以采用取程序控制的随机方式,即只有在CPU空闲是时才去扫描键盘,响应操作人员的键盘输入,即利用单片机内部定时器每隔一定时间对键盘扫描一次,这样控制方式,不管键盘上有无键闭合,CPU总是定时的关心键盘状态。在大多数情况下,CPU对键盘可能进行空扫描。

根据以上的论述,我们采用方案一。

2.3 单片机最小系统

51单片机是对目前所有兼容intel 8031指令系统的单片机的统称。该系列单片机的始祖是intel的8031单片机,后来随着技术的发展,成为目前广泛应用的8为单片机之一。单片机是在一块芯片内集成了CPU、RAM、ROM、定时器/计数器和多功能I/O口等计算机所需要的基本功能部件的大规模集成电路,又称为MCU。51系列单片机内包含以下几个部件:

一个8位CPU;一个片内振荡器及时钟电路;

8KB的ROM程序存储器;

一个256B的RAM数据存储器;

寻址64KB外部数据存储器和64KB外部程序存储空间的控制电路;

32条可编程的I/O口线;

两个16位定时/计数器;

一个可编程全双工串行口;

5个中断源、两个优先级嵌套中断结构。

如图2-2-1所示为单片机基本构造,其基本性能介绍如下:

图2-2-1单片机

该单片机本身内含40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中端口,3个16位可编程定时计数器,2个全双工串行通信口,AT89C52可以按照常规方法进行编程,但不可以在线编程。其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。

主要特性如下表所示:

兼容MCS—51指令系统

32个可编程I/O线

8k字节可编程闪烁存储器

可编程UARL通道

三个16位可编程定时/计数器中断

时钟频率0-24MHz

2个外部中断源,共8个中断源

128×8bit内部RAM

2个读写中断口线

可直接驱动LED

软件设置睡眠和唤醒功能

低功耗空闲和掉电模式

表2-2-1  单片机主要功能描述

该单片机为40脚双列直插封装的8位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。主要管脚有:XTAL1(19脚)和XTAL2(18脚)为振荡器输入输出端口,外接12MHz 晶振。RST/Vpd(9脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40脚)和VSS(20脚)为供电端口,分别接+5V电源的正负端。P0~P3 为可编程通用I/O脚,其功能用途由软件定义,在本设计中,P0端口(32~39脚)被定义为N1功能控制端口,分别与N1的相应功能管脚相连接,13脚定义为IR输入端,10脚和11脚定义为I2C总线控制端口,分别连接N1的SDAS(18脚)和SCLS(19脚)端口,12脚、27脚及28脚定义为握手信号功能端口,连接主板CPU的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。

P0口:P0口是一组8位漏极开路型双向I/O 口,也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口P0写“1”时,可作为高阻抗输入端用。在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。在Flash 编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。

P1口:P1是一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。与AT89C51不同之处是,P1.0和P1.1还可分别作为定时/计数器2 的外部计数输入(P1.0/T2)和输入(P1.1/T2EX)。Flash编程和程序校验期间,P1接收低8位地址。

P2口:P2是一个带有内部上拉电阻的8 位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对端口P2写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX @DPTR指令)时,P2口送出高8位地址数据。在访问8位地址的外部数据存储器(如执行MOVX @RI指令)时,P2口输出P2锁存器的内容。Flash编程或校验时,P2亦接收高位地址和一些控制信号。

P3口:P3口是一组带有内部上拉电阻的8位双向I/O口。P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。此时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能P3口还接收一些用于Flash 闪速存储器编程和程序校验的控制信号。

RST:复位输入。当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。

ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个AL脉冲。对Flash存储器编程期间,该引脚还用于输入编程脉冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。该位置位后,只有一条 MOVX 和MOVC指令才能将ALE激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。

PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当单片机由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。在此期间,当访问外部数据存储器,将跳过两次PSEN信号。

EA/VPP:外部访问允许。欲使CPU仅访问外部程序存储器(地址为0000H—FFFFH),EA端必须保持低电平(接地)。需注意的是:如果加密位LB1被编程,复位时内部会锁存EA端状态。如EA端为高电平(接Vcc端),CPU则执行内部程序存储器中的指令。Flash存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。

XTAL1:振荡器反相放大器的及内部时钟发生器的输入端。

XTAL2:振荡器反相放大器的输出端。

单片机最小原理图如图2-2-2所示。

图2-2-2 单片机最小系统

单片机最小系统说明:

时钟信号的产生:在MCS-51芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,其输出端为引脚XTAL2。而在芯片的外部,XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器,这就是单片机的时钟振荡电路。

时钟电路产生的振荡脉冲经过触发器进行二分频之后,才成为单片机的时钟脉冲信号。

一般地一般选用石英晶体振荡器。此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。电路中两个电容 C3,C2的作用有两个:一是帮助振荡器起振;二是对振荡器的频率进行微调。C3,C2的典型值为30PF。

图2-2-2 晶振电路

单片机复位使CPU和系统中的其他功能部件都处在一个确定的初始状态下,并从这个状态开始工作。单片机复位条件:必须使9脚加上持续两个机器周期(即24个振荡周期)的高电平。

图2-2-2 复位电路

    利用单片机的ISP功能通过与电脑串口连接,在电脑端运行ISP下载控制软件STC-ISP.EXE(可到mcu-memory网站下载)即可对芯片进行烧录。需要注意的是单片机要上电复位即冷启动才会运行其内部已固化的系统ISP程序与电脑端ISP下载控制软件通讯。另外由于是串口通讯,有读者会认为用户系统目标板上要用通讯标准晶振如11.0592M等与电脑端通讯。其实并非这样,用户系统目标板上的晶振频率选择并没有多大限制,只要不超过33M,理论上可选择任一频率的晶振。电脑端ISP下载控制软件会自动检测出用户系统目标板上所使用晶振的频率,并计算出合适的波特率,但不会超过用户在ISP下载控制软件中设定的最高波特率与之通信并开始烧录。

由于该系列单片机EA管脚内部已上拉到VCC,所以用户程序如不在外部的存储器中可悬空不接,晶振旁的电容C1最好去掉不接利于起振,C1可能造成用户下载程序不成功。在编程方面,任何老的编译器/汇编器均可使用,如果使用KEILC51编译器,器件需选择标准的Intel8052,头文件包含标准的<reg52.h>,如果头文件中未声明新增的特殊功能寄存器可用“sfr”及“sbit”在头文件中添加声明地址,如果是汇编程序则用“DATA”或“EQU”在程序中声明地址即可。

C51单片机与C52单片机比较:C52单片机有3个定时器,8KB的ROM程序存储器,。

2.4按键输入电路

按键是由一组按压式或触摸式开关构成的阵列,是一种常用的输入设备。键盘可分为编码式键盘和非编码式键盘两种。

1.编码键盘通过硬件电路产生被按按键的键码,这种键盘所需程序简单,但硬件电路复杂、价格昂贵通常不被单片机系统采用。

2.非编码键盘常用一些按键排列成行列矩阵,其硬件逻辑与按键编码不存在严格的对应关系,而要由所用的程序来决定。非编码键盘的硬件接口简单,但是要占用较多的CPU时间,通常采用可编程键盘管理芯片来克服这个缺点。

在接线时由于有四个引脚,连接时需要用万用表进行测量,然后接通两个引脚,原理图如下。

要进行数据的计算就必须先进行数据的输入,也就必须确定按键输入的数值是什么,这就需要对键盘进行扫描,从而确定究竟是哪个键按下。

图2-2-3 按键电路

这些常开开关组成了调节按键,硬件电路简单,在程序设计上也不复杂,只要在程序中消除在按键过程中产生的“毛刺”现象就可以了。这里采用最常用的方法即延时法,其的原理为:因为“毛刺”脉冲一般持续时间短,约为几ms,而按键的时间一般远远大于这个时间,所以当单片机检测到有按键动静后再延时一段时间(这里取10ms)后再判断此电平是否保持原状态,如果是则为有效按键,否则无效。

2.5 D/A转换电路

DAC0832是8分辨率的D/A转换集成芯片。与微处理器完全兼容。这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。

主要参数

* 分辨率为8位;

* 电流稳定时间1us;

* 可单缓冲、双缓冲或直接数字输入;

* 只需在满量程下调整其线性度;

* 单一电源供电(+5V~+15V);

* 低功耗,20mW。

* D0~D7:8位数据输入线,TTL电平,有效时间应大于90ns(否则锁存器的数据会出错);

* ILE:数据锁存允许控制信号输入线,高电平有效;

* CS:片选信号输入线(选通数据锁存器),低电平有效;

* WR1:数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。由ILE、CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据线变换,LE1的负跳变时将输入数据锁存;

* XFER:数据传输控制信号输入线,低电平有效,负脉冲(脉宽应大于500ns)有效;

* WR2:DAC寄存器选通输入线,负脉冲(脉宽应大于500ns)有效。由WR2、XFER的逻辑组合产生LE2,当LE2为高电平时,DAC寄存器的输出随寄存器的输入而变化,LE2的负跳变时将数据锁存器的内容打入DAC寄存器并开始D/A转换。

* IOUT1:电流输出端1,其值随DAC寄存器的内容线性变化;

* IOUT2:电流输出端2,其值与IOUT1值之和为一常数;

* Rfb:反馈信号输入线,改变Rfb端外接电阻值可调整转换满量程精度;

* Vcc:电源输入端,Vcc的范围为+5V~+15V;

* VREF:基准电压输入线,VREF的范围为-10V~+10V;

* AGND:模拟信号地;

* DGND:数字信号地。

工作方式

根据对DAC0832的数据锁存器和DAC寄存器的不同的控制方式,DAC0832有三种工作方式:直通方式、单缓冲方式和双缓冲方式。

DAC0832引脚功能电路应用原理图DAC0832是采样频率为八位的D/A转换芯片,集成电路内有两级输入寄存器,使DAC0832芯片具备双缓冲、单缓冲和直通三种输入方式,以便适于各种电路的需要(如要求多路D/A异步输入、同步转换等)。所以这个芯片的应用很广泛,关于DAC0832应用的一些重要资料见下图: D/A转换结果采用电流形式输出。若需要相应的模拟电压信号,可通过一个高输入阻抗的线性运算放大器实现。运放的反馈电阻可通过RFB端引用片内固有电阻,也可外接。DAC0832逻辑输入满足TTL电平,可直接与TTL电路或微机电路连接。

DAC0832引脚功能说明:

DI0~DI7:数据输入线,TLL电平。

ILE:数据锁存允许控制信号输入线,高电平有效。

CS:片选信号输入线,低电平有效。

WR1:为输入寄存器的写选通信号。

XFER:数据传送控制信号输入线,低电平有效。

WR2:为DAC寄存器写选通输入线。

Iout1:电流输出线。当输入全为1时Iout1最大。

Iout2: 电流输出线。其值与Iout1之和为一常数。

Rfb:反馈信号输入线,芯片内部有反馈电阻.

Vcc:电源输入线 (+5v~+15v)

Vref:基准电压输入线 (-10v~+10v)

AGND:模拟地,摸拟信号和基准电源的参考地.

DGND:数字地,两种地线在基准电源处共地比较好.

图2-2-4 转换电路

第三章  软件设计与分析3.1 软件设计的组成

该系统由调节部分——频率子函数、调节部分——方波的占空比子函数、波形发生子函数、定时器0中断子函数、定时器1中断子函数、主函数和数据定义这几部分组成。

在程序开始运行之后,首先是对单片机进行初始化,之后判断信号频率值,如符合所需的频率,则重置时间常数,不符则返回。在中断结束后,还要来判断波形是否符合,如符合,则显示其频率,不符则返回,重新判断。

在中断服务子程序开始后,通过判断来确定各种波形的输出,当判断选择的不是方波后,则转向对正弦波的判断,如此反复。如果选择的是方波,则用查表的方法求出相应的数据,并通过D/A转换器将数据转换成模拟信号,形成所需波形信号。

3.2定时程序设计
定时器T1用于倒计时,每次中断为50ms,当计数标志为20时即为一秒,显示数字减一。其流程图如下






图3-3-2  倒计时中断流程图




第五章 系统调试与软件仿真

\系统调试包括硬件调试和软件调试,二者密不可分。我们设计好的硬件电路和软件程序必须经过联合调试才能验证其正确性。因为大家都清楚两者相互结合才能发挥最佳功效。

5.1 硬件调试

硬件调试分为单元电路调试和联机调试,单元电路调试在硬件电路设计中已经进行对电路进行检验。

线路检查:根据硬件逻辑设计图,仔细检查电路是否正确,并且核对元器件的型号、规格和安装是否符合要求,必要时可用万用表检测线路通断情况。先用万用表检查各管脚之间是否有短路、虚焊、漏焊现象。检查无误后,测试各个芯片是否有损,待检查完毕后,将各个芯片插入各自的槽位。

电源调试:电路的第一次通电测试很重要,调试方法有两种:一种是断开电路稳压电源的输出端,检查空载时电源的工作情况;另一种是拔下电路上的主要继承芯片,检查电源的负载能力。确保电源无故障并符合性能要求。

5.2  Keil uVision2软件调试

软件调试是通过对用户程序的汇编、连接、执行来发现程序中存在的语法错误与逻辑错误并加以排除纠正的过程。

本设计用到了Keil uVision2软件,首先打开Keil uVision2,将程序输入;然后进行调试,将程序中的语法错误和逻辑错误纠正,调试完毕后,创建HEX文件,HEX文件用于烧写芯片,将制定程序写入已设计好的电路板中,使其能根据我们的要求实现相应的功能;最后将HEX文件烧写入芯片,运行电路,让其实现信号发生器的功能         


总结

经过近一个月的努力,终于顺利完成了毕业设计。刚开始,我们头绪不是很清楚,不知道从哪里入手,但通过老师的耐心指导并和同学认真研究设计课题,跑图书馆查资料、确定基本设计方案、对所用芯片功能进行查找、调试、上机仿真等,经历了一次次的困难,却积累了很多宝贵的经验。在整个设计的过程中遇到的问题主要有以下三点,第一:基础知识掌握的不牢固,主要表现在一些常用的电路的形式和功能不清楚,对书本上的内容理解不够透彻。第二:对一些常用的应用软件缺少应用,体现在画电路图和系统的仿真的时候,对这些软件的操作不熟练,浪费了很多时间。第三:相关知识掌握的不够全面,缺少系统设计的经验。

这次设计进一步端了我的学习态度,学会了实事求是,严谨的作风,对自己要严格要求,不能够一知半解,要力求明明白白。急于求成是不好的,我有所感受。如果省略了那些必要的步骤,急于求成,不仅会浪费时间,还会适得其反。我觉得动手之前,头脑里必须清楚该怎么做,这一点是很重要的。就目前来说,我的动手能力虽然差一点,但我想,通过我的不懈努力,在这方面,我总会得到提高。这一点,我坚信。因为别人能做到的,我也一定能做到。

在此次的毕业设计中我最大的体会就是进一步认识到了理论联系实践的重要性。一份耕耘,一份收获。通过这段时间的设计,让我明白科学的思维方法和学习方法是多么重要,只有这样才能够有很高的效率,才能够让自己的工作更完美。总而言之,此次毕业设计让我学到了好多平时在课堂上学不到的东西,增加了我的知识运用能力,增强我的实际操作能力。谢谢老师给我们提供这么好的机会,为我们之后走向社会奠定了一个好的基础。

本次毕业设计让我学到了很多,也学会到了要怎么样去面对困难,不要对知识一知半截,要有的求实的能力,通过老师的帮助我学到了很多在平时的没有注意到的动东西及知识,更美没有深入的的去理解,通过这次我要更加的明确自己。更要注重自己在各方面的锻炼能力,把握机会。这次的设计非常的感谢老师们。


致谢

三年的大学生活接近尾声,我的毕业设计也顺利的完成了,这里首先向我的指导老师陈东凤表示最诚挚的感谢,同时也感谢那些帮助过我的同学们。

在本次的毕业设计中陈老师给我提供了极大的帮助,首先在一开始的选题中我便遇到了难题,由于当时选题的时候过于疏忽大意,没有认真的加以分析,所选择的题目并不是自己爱好的方向,陈老师便告诉我,最重要的就是找对方向找准目标,选择一个自己擅长和喜欢的方向不仅能够促使我们积极的完成设计,而且对于自己来说也是充满着兴趣,这样做出来的东西会更加完美和轻松,所以我毅然的改题,选择了一个自己喜欢的方向,其次,在毕业设计的过程中,陈老师不厌其烦的为我们讲解了毕业设计中可能出现的问题,并为我们提供了完整的毕业设计模板无论我遇到什么样的问题,她总能很耐心的为我们讲解,同时她每个周一要求见面一次,督促我们抓紧时间完成毕业设计,每次见面她都要求我详解上周所做的东西以及自己下周要做的东西,有问题或者不合理的地方她便为我指出来,加以指导。陈老师认真负责的态度让我倍受感激。同时在此也感谢胡银飞同学,他解决了许多我在毕业设计中遇到的问题,特别是刚开始软件的学习中,他给了我很大的帮助。

在此向所有毕业设计的过程中给予我帮助的老师和同学最诚挚的谢意。

附录

原理图



元件清单



3.3  各部分软件分析
3.3.1
  调节部分——频率子函数


单片机源程序如下:
  1. //调节部分——频率子函数
  2. void freq_ud()
  3. {
  4.               uint temp;
  5.                  if(k3==0)
  6.                             FREQ--;            
  7.                  else if(k2==0)
  8.                             FREQ++;
  9.                  if(cho==1|cho==3) //锯齿波256次中断一周期,特殊处理下。否则他的频率是100(+\-)n*2Hz.
  10.               {
  11.                             temp=0xffff-3906/FREQ;  //方波,三角波默认为100hz,切换后频率也为50HZ 65336-10^6/(256*FREQ)
  12.                             TIME0_H=temp/256;
  13.                             TIME0_L=temp%256;
  14.               }
  15.                  else if(cho==0|cho==3)
  16.               {            
  17.                             //正弦波 三角波默认周期50hz  65536-10^6//(512*FREQ)
  18.                                temp=0xffff-1953/FREQ;
  19.                                TIME0_H=temp/256;
  20.                                TIME0_L=temp%256;
  21.                  }
  22. }
  23. 3.3.2  调节部分——方波的占空比子函数

  24. //调节部分——方波的占空比子函数
  25. void duty_ud()  //方波也采用512次中断构成一个周期。
  26. {
  27.               if(k5==0&sqar_num>0)
  28.                             sqar_num--;
  29.                  else if(k4==0&sqar_num<255)
  30.                               sqar_num++;
  31. }
  32. 3.3.3  波形发生子函数

  33. //波形发生子函数
  34. void sint()
  35. {
  36.               if(!flag)
  37.               {
  38.                             CS=0;
  39.                             P2=sin_num[num++];
  40.                             CS=1;
  41.                             if(num==0)
  42.                             {
  43.                                           num=255;
  44.                                           flag=1;
  45.                             }
  46.               }
  47.               else if(flag)
  48.               {
  49.                             CS=0;
  50.                             P2=sin_num[num--];
  51.                             CS=1;
  52.                             if(num==255)
  53.                             {
  54.                                           num=0;
  55.                                           flag=0;
  56.                             }            
  57.               }
  58. }
  59. void square()
  60. {
  61.               if(i++<sqar_num)
  62.               {
  63.                             CS=0;
  64.                             P2=0xff;
  65.                             CS=1;
  66.               }
  67.               else
  68.               {
  69.                             CS=0;
  70.                             P2=0x00;
  71.                             CS=1;
  72.               }
  73. }
  74. void triangle()
  75. {
  76.                 CS=0;
  77.               P2=num++;
  78.               CS=1;
  79. }
  80. void stw()
  81. {
  82.                  if(~flag)
  83.                  {
  84.                   CS=0;
  85.                             P2=num++;
  86.                             CS=1;
  87.                             if(num==0)
  88.                             {
  89.                                           num=255;
  90.                                           flag=1;
  91.                             }
  92.               }
  93.                  else if(flag)
  94.                  {
  95.                                CS=0;
  96.                             P2=num--;
  97.                             CS=1;
  98.                             if(num==255)
  99.                             {
  100.                                           num=1;
  101.                                           flag=0;
  102.                             }
  103.               }
  104. }
  105. 3.3.4  定时器0中断子函数

  106. //定时器0中断子函数
  107. void t0() interrupt 1
  108. {
  109.               TH0=0;
  110.               TL0=0;
  111.               if(k1==0)
  112.               {
  113.                             if(++cho==4)
  114.                             {
  115.                                           cho=0;
  116.                                           num=0;
  117.                             }            
  118.               }              //num=0;所有数据从新开始,保证波形的完整性
  119.                  else if(k2==0|k3==0)
  120.     {
  121.                             freq_ud();
  122.               }
  123.                  else if(cho==1&(k5==0|k4==0))
  124.     {
  125.                             duty_ud();
  126.               }
  127.                  else ;
  128. }
  129. 3.3.5  定时器1中断处理子函数

  130. //定时器1中断处理子函数
  131. void t1() interrupt 3
  132. {
  133.                 switch(cho)
  134.                 {
  135.                               case 0:              {
  136.                                                                       TH1=TIME0_H;
  137.                                                                       TL1=TIME0_L;
  138.                                                                       sint();
  139.                                                                       break;
  140.                                                         }  //正弦波//每半周期256取样。
  141.                             case 1:              {
  142.                                                                       TH1=TIME0_H;
  143.                                                                       TL1=TIME0_L;
  144.                                                                       square();
  145.                                                                       break;
  146.                                                         }              //方波   //为了提高方波的最高频率,只有牺牲占空比的最小可调值。分100份 每次1%。
  147.                             case 2:              {
  148.                                                                       TH1=TIME0_H;
  149.                                                                       TL1=TIME0_L;
  150.                                                                       triangle();
  151.                                                                       break;
  152.                                                         }              //三角波
  153.                               case 3:              {
  154.                                                                       TH1=TIME0_H;
  155.                                                                       TL1=TIME0_L;
  156.                                                                       stw();   
  157.                                                                       break;
  158.                                                         }              //锯齿波
  159.                             default: ;
  160.                 }
  161. }
  162. 3.3.6  主函数

  163. //主函数
  164. void main()
  165. {
  166.               TMOD=0x11;
  167.               TH1=0xff;
  168.               TL1=0xd9;
  169.               TH0=0;
  170.               TL0=0;
  171.               EA=1;
  172.               ET1=1;
  173.               TR1=1;
  174.               ET0=1;
  175.               TR0=1;
  176.               while(1)
  177.               {
  178.                               ;
  179.               }
  180. }

  181. 3.4  总源程序

  182. #include<reg51.h>
  183. #include<001.h>
  184. #include<DAC0832.h>
  185. //主函数
  186. void main()
  187. {
  188.               TMOD=0x01;
  189.               TH0=0xff;
  190.               TL0=0xd9;
  191.               IT0=1;    //设置中断触发方式,下降沿
  192.               EA=1;
  193.               EX0=1;
  194.               ET0=1;
  195.               IP=0X01;  //键盘中断级别高
  196.               TR0=1;
  197.               while(1)
  198.               {
  199.                               ;
  200.               }
  201. }
  202. #ifndef __DAC0832_h__
  203. #define __DAC0832_h__
  204. typedef unsigned char uchar;
  205. typedef unsigned int  uint;
  206. uchar i,sqar_num=128; //最大值100,默认值50
  207. uchar cho=0;         //0:正弦波。1:方波。2:三角波。3:锯齿波。
  208. uchar num=0;
  209. uchar TIME0_H=0xff,TIME0_L=0xd9;      //定时器0的初值设置;全局变量.对应正弦波,锯齿波50HZ
  210. sbit k1=P1^0;                                                                                                     //三角波100Hz.
  211. sbit k2=P1^1;
  212. sbit k3=P1^2;
  213. sbit k4=P1^3;
  214. sbit k5=P1^4;
  215. sbit CS=P3^7;
  216. bit flag=0;
  217. uint FREQ=50;//初始化频率,50HZ
  218. //调节部分——频率子函数
  219. void freq_ud()
  220. {
  221.               uint temp;
  222.                  if(k3==0)
  223.                             FREQ--;            
  224.                  else if(k2==0)
  225.                             FREQ++;
  226.                  if(cho==1|cho==3) //锯齿波256次中断一周期,特殊处理下。否则他的频率是100(+\-)n*2Hz.
  227.               {
  228.                             temp=0xffff-3906/FREQ;  //方波,三角波默认为100hz,切换后频率也为50HZ 65336-10^6/(256*FREQ)
  229.                             TIME0_H=temp/256;
  230.                             TIME0_L=temp%256;
  231.               }
  232.                  else if(cho==0|cho==3)
  233.               {            
  234.                             //正弦波 三角波默认周期50hz  65536-10^6//(512*FREQ)
  235.                                temp=0xffff-1953/FREQ;
  236.                                TIME0_H=temp/256;
  237.                                TIME0_L=temp%256;
  238.                  }
  239. }
  240. //调节部分——方波的占空比子函数
  241. void duty_ud()  //方波也采用512次中断构成一个周期。
  242. {
  243.               if(k5==0&sqar_num>0)
  244.                             sqar_num--;
  245.                  else if(k4==0&sqar_num<255)
  246.                               sqar_num++;
  247. }
  248. //波形发生子函数
  249. void sint()
  250. {
  251.               if(!flag)
  252.               {
  253.                             CS=0;
  254.                             P2=sin_num[num++];
  255.                             CS=1;
  256.                             if(num==0)
  257.                             {
  258.                                           num=255;
  259.                                           flag=1;
  260.                             }
  261.               }
  262.               else if(flag)
  263.               {
  264.                             CS=0;
  265.                             P2=sin_num[num--];
  266.                             CS=1;
  267.                             if(num==255)
  268.                             {
  269.                                           num=0;
  270.                                           flag=0;
  271.                             }            
  272.               }
  273. }
  274. void square()
  275. {
  276.               if(i++<sqar_num)
  277.               {
  278.                             CS=0;
  279.                             P2=0xff;
  280.                             CS=1;
  281.               }
  282.               else
  283.               {
  284.                             CS=0;
  285.                             P2=0x00;
  286.                             CS=1;
  287.               }
  288. }
  289. void triangle()
  290. {
  291.                 CS=0;
  292.               P2=num++;
  293.               CS=1;
  294. }
  295. void stw()
  296. {
  297.                  if(~flag)
  298.                  {
  299.                   CS=0;
  300.                             P2=num++;
  301.                             CS=1;
  302.                             if(num==0)
  303.                             {
  304.                                           num=255;
  305.                                           flag=1;
  306.                             }
  307.               }
  308.                  else if(flag)
  309.                  {
  310.                                CS=0;
  311.                             P2=num--;
  312.                             CS=1;
  313.                             if(num==255)
  314.                             {
  315.                                           num=1;
  316.                                           flag=0;
  317.                             }
  318.               }
  319. }
  320. //外部中断0处理子函数
  321. void wb0() interrupt 0
  322. {
  323.                  if(k1==0)
  324.               {
  325.                             if(++cho==4)
  326.                             {
  327.                                           cho=0;
  328.                                           num=0;
  329.                             }            
  330. ……………………

  331. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整的Word格式文档51黑下载地址:
基于51单片机信号发生器的设计.doc (1001.5 KB, 下载次数: 266)
回复

使用道具 举报

ID:327447 发表于 2019-6-4 16:50 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:570500 发表于 2019-6-24 10:17 | 显示全部楼层

感谢分享
回复

使用道具 举报

ID:570631 发表于 2019-6-24 11:05 | 显示全部楼层
朋友前面的定义没得啊
回复

使用道具 举报

ID:580896 发表于 2019-7-15 10:21 | 显示全部楼层
同问,能不能把前面的定义也发一下。
回复

使用道具 举报

ID:627964 发表于 2019-10-21 23:15 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:662569 发表于 2019-12-13 15:04 来自手机 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:671476 发表于 2019-12-29 15:12 | 显示全部楼层
对于一个菜鸟来说,这个真的很有帮助!!!感谢大佬!!!
回复

使用道具 举报

ID:671476 发表于 2020-1-3 10:30 | 显示全部楼层
有两个库函数莫得呀?可以发一下或者解释一下吗?
回复

使用道具 举报

ID:688139 发表于 2020-2-8 13:01 来自手机 | 显示全部楼层
Lily-lemon 发表于 2020-1-3 10:30
有两个库函数莫得呀?可以发一下或者解释一下吗?

你好,你有没有把库函数弄好,可以给我发一下吗?还有我这边程序有两个错误
回复

使用道具 举报

ID:688139 发表于 2020-2-8 13:02 来自手机 | 显示全部楼层
SpringMean 发表于 2019-7-15 10:21
同问,能不能把前面的定义也发一下。

你好,不知道你现在弄好没?可以给我发一下吗??而且我这边有错误,能帮忙解释一下吗
回复

使用道具 举报

ID:688139 发表于 2020-2-8 13:37 来自手机 | 显示全部楼层
可以回复一下吗?很着急
回复

使用道具 举报

ID:255945 发表于 2021-1-10 18:26 | 显示全部楼层
厉害啊,不用网上查资料了,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表