基于单片机DA转换设计函数信号发生器.docx
《基于单片机DA转换设计函数信号发生器.docx》由会员分享,可在线阅读,更多相关《基于单片机DA转换设计函数信号发生器.docx(20页珍藏版)》请在冰豆网上搜索。
基于单片机DA转换设计函数信号发生器
电路综合实习报告
课程题目:
基于单片机D/A转换设计函数信号发生器
摘要:
以51单片机为核心设计函数信号发生器,采用程序设计方法产生正弦波,方波,三角波,方波,锯齿波,波形的频率在一定频率范围内可任意改变。
通过键盘来控制四种波形的类型选择与频率变化,并通过液晶屏1602显示其各自的类型及数值。
主要包括信号发生部分、D/A转换部分以及液晶显示部分。
关键词:
D/A转换,液晶显示
主要内容:
1.实习原理
2.实习内容
1)系统设计
●设计要求
●方案设计(各模块设计)
●软件设计流程
2)通过示波器对波形种类及频率进行测试
●测试说明
●测试过程
●测试结果
3.实习的心得体会
4.附录:
源程序
1.实习原理:
●系统总体框图
●主控芯片AT89S52
●DAC0832的内部结构:
●D/A转换原理图
DAC0832是双列直插式8位D/A转换器。
能完成数字量输入到模拟量(电流)
输出的转换。
其主要参数如下:
分辨率为8位,转换时间为1μs,满量程
误差为±1LSB,参考电压为-10V~+10V,供电电源为+5V~+15V,逻辑电平
输入与TTL兼容。
DAC0832中有两级锁存器,第一级锁存器称为输入寄存
器,它的允许锁存信号为ILE,第二级锁存器称为DAC寄存器,它的锁存
信号也称为通道控制信号/XFER。
●液晶屏的显示
●矩阵键盘
2.实习内容:
1)系统设计
利用AT89S52单片机采用程序设计方法产生锯齿波、正弦波、方波、三角波四种波形,再通过D/A转换器DAC0832将数字信号转换成模拟信号,滤波放大,最终由示波器显示出来,通过键盘来控制四种波形的类型选择、频率变化,最终输出显示其各自的类型以及数值。
●设计要求
1)基于单片机的D/A转换用软件编程产生四种波形,分别为:
锯齿波,正弦波,方波,三角波;
2)通过键盘选择四种波形类型;
3)波形频率可调;
●方案设计论证
显示方案论证:
方案一:
采用LED数码管。
LED数码管由8个发光二极管组成,每只数码管轮流显示各自的字符。
由于人眼具有视觉暂留特性,当每只数码管显示的时间间隔小于1/16s时人眼感觉不到闪动,看到的是每只数码管常亮。
使用数码管显示编程较易,但要显示内容多,而且数码管不能显示字母。
方案二:
采用LCD液晶显示器1602。
其功率小,效果明显,显示编程容易控制,可以显示字母。
以上两种方案综合考虑,选择方案二。
键盘方案论证:
方案一:
矩阵式键盘。
矩阵式键盘的按键触点接于由行、列母线构成的矩阵电路的交叉处。
当键盘上没有键闭合时,所有的行和列线都断开,行线都呈高电平。
当某一个键闭合时,该键所对应的行线和列线被短路。
方案二:
编码式键盘。
编码式键盘的按键触点接于74LS148芯片。
当键盘上没有闭合时,所有键都断开,当某一键闭合时,该键对应的编码由74LS148输出。
以上两种方案综合考虑,选择方案一。
●软件设计流程
N
Y
2)通过示波器对波形种类及频率进行测试
●测试说明:
正弦波、矩形波、三角波和方波信号的输出,通过对独立键盘来实现其不同波形的输出以及改变其频率。
●测试过程:
当程序下进去时经过初始化,液晶屏的上只显示“Starting,XinHaoFaSheng”,然后显示“ClearAll,NothingHappened”,当键盘4按下时开始显示频率,当键盘7按下时,此时输出波形为三角波,当键盘8按下时,此时输出波形为方波,当键盘9按下时,此时输出波形为正弦波,当键盘C按下时,此时输出波形为锯齿波。
每按一次键盘4,再按键盘A,波形频率增加,每按一次键盘4,再按键盘B,波形频率减小。
●测试结果
各种波形:
输出波形为三角波
输出波形为方波时
输出为正弦波时
输出为锯齿波时
存在问题:
得到的波形纹波比较明显,波形相当不稳定,而且有时候出现了失真
解决方法:
修改程序中波形的幅值,使幅值减小,最后纹波变小,波形也比较稳定。
至于出现失真这个问题,经过检查,发现连接线路有所松动,处理完后,波形正常。
3.实习心得体会
通过这次实习,我学习了函数发生器设计的原理,用keil软件编程及调试,protues软件仿真,示波器的使用,加深了我对单片机的理解,也让我了解到专业知识的重要性。
在实习过程中也碰到了很多困难,比如说对于写程序可以说是掌握得不是很好,用c语言写程序会出现很多错误;在用protues软件仿真时,由于第一次接触,所以一开始都不知道何从下手;在用示波器测试时纹波太大,而且波形不稳定等等,最后通过一些书籍,XX查看相关资料,询问同学,再修改程序,解决了困难。
这次实习是对我们过去所学知识的系统提高和扩充的过程,很好的锻炼了我们解决问题的能力,同时也让我们了解到自己的不足,从而不断完善自己。
4.附录
源程序:
#include"regX51.h"
#include"intrins.h"
#include
#include"1602.h"
#include"DAC0832.h"
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharKey,keytemp,flag=20,i;
ucharfreq,baiwei,shiwei,gewei;
uintcodepinlv[]={400,227,214,200,190,178,170,160,153,147,140,134,130,125,121,117,112,108,105,101,
99,96,92,90,88,86,83,81,80,78,76,74,72,70,78,76,74,72};
ucharcodevalue[16]=//矩阵键盘中每个键对应的P0口值
{
0x0e7,0x0d7,0x0b7,0x077,
0x0eb,0x0db,0x0bb,0x07b,
0x0ed,0x0dd,0x0bd,0x07d,
0x0ee,0x0de,0x0be,0x07e
};
ucharcodetable[]=
{
0x30,//0在1602中的十六进制码
0x31,//1在1602中的十六进制码
0x32,//2在1602中的十六进制码
0x33,//3在1602中的十六进制码
0x34,//4在1602中的十六进制码
0x35,//5在1602中的十六进制码
0x36,//6在1602中的十六进制码
0x37,//7在1602中的十六进制码
0x38,//8在1602中的十六进制码
0x39,//9在1602中的十六进制码
0x41,//A在1602中的十六进制码
0x42,//B在1602中的十六进制码
0x43,//C在1602中的十六进制码
0x44,//D在1602中的十六进制码
0x45,//E在1602中的十六进制码
0x46//F在1602中的十六进制码
};
ucharcodesanjiaobo[128]={
0x00,0x04,0x08,0x0c,
0x10,0x14,0x18,0x1c,
0x20,0x24,0x28,0x2c,
0x30,0x34,0x38,0x3c,
0x40,0x44,0x48,0x4c,
0x50,0x54,0x58,0x5c,
0x60,0x64,0x68,0x6c,
0x70,0x74,0x78,0x7c,
0x80,0x84,0x88,0x8c,
0x90,0x94,0x98,0x9c,
0xa0,0xa4,0xa8,0xac,
0xb0,0xb4,0xb8,0xbc,
0xc0,0xc4,0xc8,0xcc,
0xd0,0xd4,0xd8,0xdc,
0xe0,0xe4,0xe8,0xec,
0xf0,0xf4,0xf8,0xfc,
0xfe,0xfa,0xf6,0xf2,
0xee,0xea,0xe6,0xe2,
0xde,0xda,0xd6,0xd2,
0xce,0xca,0xc6,0xc2,
0xbe,0xba,0xb6,0xb2,
0xae,0xaa,0xa6,0xa2,
0x9e,0x9a,0x96,0x92,
0x8e,0x8a,0x86,0x82,
0x7e,0x7a,0x76,0x72,
0x6e,0x6a,0x66,0x62,
0x5e,0x5a,0x56,0x52,
0x4e,0x4a,0x46,0x42,
0x3e,0x3a,0x36,0x32,
0x2e,0x2a,0x26,0x22,
0x1e,0x1a,0x16,0x12,
0x0e,0x0a,0x06,0x02,
};
ucharcodefangbo[256]={
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,
};
ucharcodezhengxianbo[128]={
0x80,0x86,0x8c,0x92,
0x98,0x9f,0xa5,0xab,
0xb0,0xb6,0xbc,0xc1,
0xc7,0xcc,0xd1,0xd5,
0xDA,0xde,0xe2,0xe6,
0xea,0xed,0xf0,0xf3,
0xf6,0xf8,0xfa,0xfc,
0xfd,0xfe,0xff,0xff,
0xff,0xff,0xff,0xfe,
0xfd,0xfc,0xfa,0xf8,
0xf6,0xf3,0xf0,0xed,
0xea,0xe6,0xe3,0xde,
0xDA,0xd6,0xd1,0xcc,
0xc7,0xc1,0xbc,0xb6,
0xb1,0xab,0xa5,0x9f,
0x99,0x92,0x8c,0x86,
0x80,0x79,0x73,0x6d,
0x67,0x61,0x5b,0x55,
0x4f,0x49,0x43,0x3e,
0x39,0x33,0x2e,0x2a,
0x25,0x21,0x1d,0x19,
0x15,0x12,0x0f,0x0c,
0x09,0x07,0x05,0x03,
0x02,0x01,0x00,0x00,
0x00,0x00,0x00,0x01,
0x02,0x03,0x05,0x07,
0x09,0x0c,0x0e,0x12,
0x15,0x18,0x1c,0x20,
0x25,0x29,0x2e,0x33,
0x38,0x3d,0x43,0x48,
0x4e,0x54,0x5a,0x60,
0x66,0x6c,0x73,0x79,
};
ucharcodejc[128]=
{
0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,
0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,
0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,
0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,
0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,
0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,
0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,
0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,
0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,
0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,
0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,
0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,
0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,
0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,
0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,
0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe
};
voidScanKey();
voidDly_mS(unsignedintms)//延时函数
{
unsignedinti;
while(ms--)
for(i=0;i<75;i++);
}
voidIniSys()
{
Dly_mS(200);
EA=0;
TCON=0x00;/*中断标志清0*/
IT1=0;/*中断1边缘触发*/
EX1=0;/*中断1暂时关闭*/
ET0=0;/*定时器0中断关闭*/
TMOD=0x01;/*定时器0方式1*/
TH0=0x0FC;
TL0=0x18;//定时1ms
EA=1;/*开中断*/
ET0=1;/*开定时器0中断*/
}
voidCT0Server()interrupt1//定时器中每1MS扫描一次键盘
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;//定时10ms
TR0=1;
keytemp=Key;
ScanKey();
}
voiddelay_nus(ucharn)
{
while(--n)
{;}
}
voidScanKey()
{
ucharP0Buf,scan,j;
P0=0x0f;
P0Buf=P0;
if(P0Buf!
=0x0f)
{
P0=0xf0;
scan=P0Buf;
P0Buf=P0;
scan=scan+P0Buf;
for(j=0;j<16;j++)
{
if(value[j]==scan)
{
Key=j;
break;
}
}
}
}
voidfunction0()
{
Display(0,0,"ClearAll");
Display(0,1,"NothingHappened");
DAC0832=0x00;
}
voidfunction4()
{
for(i=0;i<128;i++)//循环送255个三角波数据
{
DAC0832=sanjiaobo[i];
delay_nus(freq);
}
}
voidfunction5()
{
for(i=0;i<128;i++)//循环送255个方波数据
{
DAC0832=fangbo[i];
delay_nus(freq);
}
}
voidfunction6()
{
for(i=0;i<128;i++)//循环送255个正弦波数据
{
DAC0832=zhengxianbo[i];
delay_nus(freq);
}
}
voidfunction7()
{
for(i=0;i<128;i++)//循环送255个锯齿波数据
{
DAC0832=jc[i];
delay_nus(freq);
}
}
voidfunction8()
{
Display(0,0,"PinLvSheZhi");
if(Key==11)flag++;
if(Key==15)flag--;
freq=flag;
Display(0,1,"freq=Hz");
baiwei=(pinlv[freq]/100);
shiwei=(pinlv[freq]%100)/10;
gewei=(pinlv[freq]%10);
DispOneChar(8,1,table[baiwei]);
DispOneChar(9,1,table[shiwei]);
DispOneChar(10,1,table[gewei]);
}
voidmain()
{
IniSys();
LcdInit();
Display(0,0,"Starting...");
Dly_mS(1000);
WrtLcdCmd(Clear);//清显示
Display(0,0,"XinHaoFaSheng");
Dly_mS(1000);
WrtLcdCmd(Clear);//清显示
TR0=1;/*开定时器0*/
while
(1)
{
switch(Key)
{
case0:
function0();break;
case4:
function4();break;
case5:
function5();break;
case6:
function6();break;
case7:
function7();break;
case8:
function8();break;
default:
break;
}
}
}