EDAFPGADDS信号发生器课程设计实验报告.docx
《EDAFPGADDS信号发生器课程设计实验报告.docx》由会员分享,可在线阅读,更多相关《EDAFPGADDS信号发生器课程设计实验报告.docx(28页珍藏版)》请在冰豆网上搜索。
EDAFPGADDS信号发生器课程设计实验报告
《电子系统实验报告》课程设计
总结报告
题目:
DDS信号发生器
设计人员:
学号:
同组人员:
班级:
指导老师:
日期:
2010.06.12
DDS信号发生器
一主要功能要求:
本课程系统DDS信号发生器设计我们组利用FPGA生成DDS函数信号发生器内核和利用89S52单片机最小系统实现频率字输出和波形选择。
DDS模块与单片机的通信采用SPI串口协议。
系统的16位频率字输出采用单片机的SPI串口协议输出,在DDS模块内部采用16位移位寄存器和16位锁存器进行串行数据到并行数据的转换。
从而实现单片机到DDS模块的通信。
DDS模块由频率累加器、相位累加器、波形查找表、D/A模块组成。
且系统时钟频率工作于75MHZ。
频率和相位累加器采用32位累加器。
波形查找表由三个ROM表组成,分别存储正弦波、方波、三角波的量化数据。
再用一个三选一选择器作为波形输出的控制器件,控制信号由单片机输出。
二进制振幅键控的数字基带信号由VHDL语言生成M序列的二进制信号。
正弦波信号由正弦波表输出。
二者再进过一个乘法器,再到D/A模块。
由此完成2ASK模块的设计。
二进制振幅键控的数字基带信号由VHDL语言生成M序列的二进制信号。
进过二选一模块选择移位全零或者全一,查ROM表,选择移位180度或者0度,
再到D/A。
由此完成2PSK模块设计。
(注:
正弦波进行1024次量化采用公式512+511*sin(6.18/1024*k)------k值为1到1024
对方波进行1024次量化采用前512位量化数值全为1023后512位量化数值全为0
三角波进行1024次量化采用1.3.5.7…..1023.1021.1019………7.5.3.1的方式进行量化
)
二整体设计框图及整机概述
三系统实现的功能
(1)可显示信号发生器输出波形与频率。
(2)正弦波、方波、三角波输出频率范围为35HZ~1.17MHZ。
(3)具有频率设置功能。
(4)输出信号频率稳定度优于0.1。
(5)输出电压幅值:
在5K负载电阻上的电压峰峰值Vopp>=1V。
(6)输出信号能够移2种相位。
(7)用数字示波器观察时比较好。
四、DDS模块各部分原理图
单片机与DDS模块通信接口部分
锁相环模块
频率字处理模块
波形存储表及3选1选择器
2ASK
相位调制(2PSK)和2ASK和2PSK选择模块
五、系统软件流程图及流程说明
标志00
六.程序
SPI.h模块
#ifndef_spi_h_
#define_spi_h_
#defineucharunsignedchar
#defineuintunsignedint
sbitcs=P2^0;
sbitsck=P2^1;
sbitd_out=P2^2;
uintbdatadate;
sbitsend_bit=date^7;
ucharget1=0,get2=0;
voiddelayus(ucharn)
{
ucharx,y;
for(x=n;x>0;x--)
for(y=2;y>0;y--);
}
voidsend(uintsend_date)//用于发送信号的器件
{
ucharnum=0;
date=send_date;
cs=1;
sck=1;
delayus(20);
cs=0;
delayus(20);
for(;num<16;num++)
{
sck=0;
delayus(5);
d_out=send_bit;
delayus(20);
sck=1;
delayus(20);
date=date<<1;
}
cs=1;
delayus(5);
}
voidsend1(uintsend_date)//用于发送信号的器件
{
ucharnum=0;
date=send_date;
cs=1;
sck=1;
delayus(20);
cs=0;
delayus(20);
for(;num<16;num++)
{
sck=0;
delayus(5);
d_out=send_bit;
delayus(20);
sck=1;
delayus(20);
date=date<<1;
}
cs=1;
delayus(5);
}
voidget_spi()interrupt0//用于接收信号的器件
{
ucharnum=0;
EX0=0;
//EA=0;
while(sck==0);
for(;num<8;num++)
{get1=get1<<1;
while(sck==1);
while(sck==0);
//
if(d_out==1)
get1=get1|0x01;
elseget1=get1|0x00;
}
while(sck==0);
for(num=0;num<8;num++)
{get2=get2<<1;
while(sck==1);
while(sck==0);
//
if(d_out==1)
get2=get2|0x01;
elseget2=get2|0x00;
}
//EA=1;
IE0=0;
EX0=1;
}
#endif
Key44.h
#ifndef__KEY_H__
#define__KEY_H__
#defineuintunsignedint
#defineucharunsignedchar
ucharcodetable[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/********************************************************************
*名称:
Delay_1ms()
*功能:
延时子程序,延时时间为1ms*x
*输入:
x(延时一毫秒的个数)
*输出:
无
***********************************************************************/
voidDelay_1ms(uinti)
{
ucharx,j;
for(j=0;j
for(x=0;x<=148;x++);
}
/********************************************************************
*名称:
Keyscan()
*功能:
实现按键的读取。
下面这个子程序是按处理矩阵键盘的基本方法处理的。
*输入:
无
*输出:
按键值
***********************************************************************/
ucharKeyscan(void)
{
uchari,j,temp,Buffer[4]={0xfe,0xfd,0xfb,0xf7};
for(j=0;j<4;j++)
{
P1=Buffer[j];
/*以下三个_nop_();作用为让P1口的状态稳定*/
//_nop_();
//_nop_();
//_nop_();
temp=0x10;
for(i=0;i<4;i++)
{
if(!
(P1&temp))
{
return(i+j*4);//返回取得的按键值
}
temp<<=1;
}
}
}
#endif
Lcd1602.h
#ifndef__LCD1602_H__
#define__LCD1602_H__
#defineucharunsignedchar
#defineuintunsignedint
//这三个引脚参考资料
sbitE=P2^7;//1602使能引脚
sbitRW=P2^6;//1602读写引脚
sbitRS=P2^5;//1602数据/命令选择引脚
/********************************************************************
*名称:
delay()
*功能:
延时,延时时间大概为140US。
*输入:
无
*输出:
无
***********************************************************************/
voiddelay()
{
inti,j;
for(i=0;i<=10;i++)
for(j=0;j<=2;j++);
}
/********************************************************************
*名称:
Convert(ucharIn_Date)
*功能:
因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。
*输入:
1602资料上的值
*输出:
送到1602的值
***********************************************************************/
ucharConvert(ucharIn_Date)
{
uchari,Out_Date=0,temp=0;
for(i=0;i<8;i++)
{
temp=(In_Date>>i)&0x01;
Out_Date|=(temp<<(7-i));
}
returnOut_Date;
}
/********************************************************************
*名称:
enable(uchardel)
*功能:
1602命令函数
*输入:
输入的命令值
*输出:
无
***********************************************************************/
voidenable(uchardel)
{
P0=Convert(del);
RS=0;
RW=0;
E=0;
delay();
E=1;
delay();
}
/********************************************************************
*名称:
write(uchardel)
*功能:
1602写数据函数
*输入:
需要写入1602的数据
*输出:
无
***********************************************************************/
voidwrite(uchardel)
{
P0=Convert(del);
RS=1;
RW=0;
E=0;
delay();
E=1;
delay();
}
/********************************************************************
*名称:
L1602_init()
*功能:
1602初始化,请参考1602的资料
*输入:
无
*输出:
无
***********************************************************************/
voidL1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}
/********************************************************************
*名称:
L1602_char(ucharhang,ucharlie,charsign)
*功能:
改变液晶中某位的值,如果要让第一行,第五个字符显示"b",调用该函数如下
L1602_char(1,5,'b')
*输入:
行,列,需要输入1602的数据
*输出:
无
***********************************************************************/
voidL1602_char(ucharhang,ucharlie,charsign)
{
uchara;
if(hang==1)a=0x80;
if(hang==2)a=0xc0;
a=a+lie-1;
enable(a);
write(sign);
}
/********************************************************************
*名称:
L1602_string(ucharhang,ucharlie,uchar*p)
*功能:
改变液晶中某位的值,如果要让第一行,第五个字符开始显示"abcdef",调用该函数如下
L1602_string(1,5,"abcdef;")
*输入:
行,列,需要输入1602的数据
*输出:
无
***********************************************************************/
voidL1602_string(ucharhang,ucharlie,uchar*p)
{
uchara;
charq=0;
if(hang==1)a=0x80;
if(hang==2)a=0xc0;
a=a+lie-1;
enable(a);
while
(1)
{
if(*(p+q)=='\0')break;
write(*(p+q));
q++;
}
}
#endif
主程序
include
#include
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineulongunsignedlongint
sbitd1=P2^3;
sbitd0=P2^4;
ulongs_data;
ulongm,n,c;
ucharKey_Value,Key_Value1;
/***********************************************************/
voiddisplay(unsignedlongintt)
{ulongt1,t2,t3,t4,t5,t6,t7;
//t8=t%100000000;
t7=t%10000000;
t6=t%1000000;
t5=t%100000;
t4=t%10000;
t3=t%1000;
t2=t%100;
t1=t%10;
//L1602_char(1,7,t8/10000000+48);
L1602_char(1,8,t7/1000000+48);
L1602_char(1,9,t6/100000+48);
L1602_char(1,10,t5/10000+48);
L1602_char(1,11,t4/1000+48);
L1602_char(1,12,t3/100+48);
L1602_char(1,13,t2/10+48);
L1602_char(1,14,t1+48);
}
voiddisplay1(uchart)
{intt1;
t1=t%10;
L1602_char(2,4,t1+48);
}
voiddisplay2(uchart)
{intt1;
t1=t%10;
L1602_char(2,9,t1+48);
}
voidmain()
{
s_data=0x0001;
send(s_data);
L1602_init();
L1602_string(1,1,"fout=");
L1602_string(1,15,"Hz");
L1602_string(2,1,"d1=");
L1602_string(2,6,"d0=");
L1602_string(2,12,"fbo");
display(35);
display1(d1);
display2(d0);
while
(1)
{P1=0xf0;
if(P1!
=0xf0)
{
Delay_1ms(15);//按键消抖
if(P1!
=0xf0)
{
Key_Value=Keyscan()%10;
Key_Value1=Keyscan()/10;if(Key_Value==0&&Key_Value1==0)//20dejia
{
s_data=s_data+0x0001;
if(s_data==65535)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
if(Key_Value==1&&Key_Value1==0)//100dejia
{
s_data=s_data+0x0006;
if(s_data==65535)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
if(Key_Value==2&&Key_Value1==0)//1kdejia
{
s_data=s_data+0x0040;
if(s_data==65535)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
if(Key_Value==3&&Key_Value1==0)//10kdejia
{
s_data=s_data+0x0280;
if(s_data==65535)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
if(Key_Value==4&&Key_Value1==0)//100kdejia
{
s_data=s_data+0x1900;
if(s_data==65535)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
/****************************************************************************************/
if(Key_Value==5&&Key_Value1==0)//20dejian
{
s_data=s_data-0x0001;
if(s_data==0)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
if(Key_Value==6&&Key_Value1==0)//100dejian
{
s_data=s_data-0x0006;
if(s_data==0)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}
if(Key_Value==7&&Key_Value1==0)//1kdejian
{
s_data=s_data-0x0040;
if(s_data==0)
{
s_data=0x0001;
}
send(s_data);
n=(s_data+1)*18;
display(n);
Delay_1ms(100);
}