基于AT89C52单片机的函数发生器的实验总结

基于AT89C52单片机的函数发生器的实验总结

1.组成概述与框图

主控部分使用STC89C52单片机进行控制。
人机交互部分使用一个纽扣按键和一个拨码开关。
数据处理部分使用由DAC0832组成的数模转换电路。
信号预处理部分使用有LM358组成的运放电路。
在这里插入图片描述

2.软件设计流程

在这里插入图片描述

3.波形产生方案:

(1)查表法输出波形
根据波形波表产生器产生8位位宽,128个采样点的数据,存放在单片机的数据存储器中,在中断程序中直接输出相应地址的数据到DAC模块产生波形。
(2)算法输出波形
方波:循环输出0xff和0x00的数据端口
三角波:先设置一个变量,从0-255依次输出,再从255-0依次输出,以此反复。
(3)采取方案:正弦波采用查表法输出,而三角波和方波使用算法输出,可有效节约数据存储器的内存。

4.调试总结

(1)现象:程序在Protues软件上仿真时一切正常,但在实际电路上运行,产生的正弦波,三角波,方波都出现了严重失真的现象(如图)。
在这里插入图片描述
(2)分析与解决方法:最开始以为是运放电路部分的反馈电阻太大导致的失真,
经过调试发现,方波失真是因为软件的延时时间太长导致的周期时间太长引起的失真,把延时时间调小便解决了问题。正弦波失真和三角波失真是因为硬件电路引起的,按照理论值,当P0口输出0x00是DA输出电压为0V,P0口输出0xff是DA输出电压为5V,但实际电路P0口输出0xFF是电压只有2.5V左右,于是便猜想,把软件8位的输入改为7位的输入,即P0口最大输出0x7F,三角波和正弦波的最大值为127。经过实验确实解决了上述失真的问题。

5.Protues仿真原理图:

在这里插入图片描述

6.Altium原理图:

在这里插入图片描述

7.实际电路板:

在这里插入图片描述

8.实验现象

在这里插入图片描述

9.资料链接

链接:[https://pan.baidu.com/s/1MhP0C2c198hZSvxzl1vBpA]
提取码:3zx3

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于AT89C52单片机用汇编语言编写的程序,可以控制8位数码管显示时间(时间显示格式为xx(小时)-yy(分钟)-zz(秒钟)): ``` ORG 0000H MOV TMOD, 01H ;设定定时器0为16位定时器模式 MOV TH0, 3CH ;设定计数初值为3C00H(1ms) MOV TL0, 00H SETB TR0 ;启动定时器0 MOV DPTR, #TIME ;将指针指向存储时间的内存单元 MAIN: ACALL DISPLAY ;调用显示函数 SJMP MAIN ;循环 DISPLAY: MOV R0, #0AH ;设置循环次数为10 MOV A, #00H ;清零寄存器A MOV B, #00H ;清零寄存器B LOOP1: MOVX A, @DPTR ;将存储的时间读取到寄存器A中 INC DPTR ;指针自增1 MOV R1, A ;将寄存器A的值赋给寄存器R1 MOV A, R1 ;将寄存器R1的值赋给寄存器A ANL A, #0FH ;取低4位 MOV P1, A ;将寄存器A的值输出到P1口,即数码管的低4位 MOV A, R1 ;将寄存器R1的值赋给寄存器A SWAP A ;交换高低4位 ANL A, #0FH ;取低4位 MOV P2, A ;将寄存器A的值输出到P2口,即数码管的高4位 DJNZ R0, LOOP1 ;循环10次 RET ORG 0030H TIME: DB 12H ;存储小时数 DB 30H ;存储分钟数 DB 45H ;存储秒钟数 END ``` 注释: - `MOV TMOD, 01H`:设定定时器0为16位定时器模式; - `MOV TH0, 3CH`:设定计数初值为3C00H(1ms); - `MOV TL0, 00H`:设定计数初值为00H; - `SETB TR0`:启动定时器0; - `MOV DPTR, #TIME`:将指针指向存储时间的内存单元; - `MAIN`:主程序入口; - `ACALL DISPLAY`:调用显示函数; - `SJMP MAIN`:无限循环; - `DISPLAY`:显示函数; - `MOV R0, #0AH`:设置循环次数为10; - `MOV A, #00H`:清零寄存器A; - `MOV B, #00H`:清零寄存器B; - `LOOP1`:循环开始; - `MOVX A, @DPTR`:将存储的时间读取到寄存器A中; - `INC DPTR`:指针自增1; - `MOV R1, A`:将寄存器A的值赋给寄存器R1; - `MOV A, R1`:将寄存器R1的值赋给寄存器A; - `ANL A, #0FH`:取低4位; - `MOV P1, A`:将寄存器A的值输出到P1口,即数码管的低4位; - `MOV A, R1`:将寄存器R1的值赋给寄存器A; - `SWAP A`:交换高低4位; - `ANL A, #0FH`:取低4位; - `MOV P2, A`:将寄存器A的值输出到P2口,即数码管的高4位; - `DJNZ R0, LOOP1`:循环10次; - `RET`:返回主程序; - `TIME`:存储时间的内存单元; - `DB 12H`:存储小时数; - `DB 30H`:存储分钟数; - `DB 45H`:存储秒钟数。 程序的原理是利用定时器0每隔1ms中断一次,然后在中断服务程序中调用显示函数进行数码管显示。时间存储在内存中,每次显示时将时间读取到寄存器A中,然后输出到数码管上。具体实现可以根据自己的硬件平台进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值