⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shiboqi.c

📁 单片机DDS驱动程序
💻 C
字号:
//-----------------------------------------
//
//2007年全国电子设计大赛培训专用	
//		基于DDS的信号发生器
//						Design By BoBo&ShuiJian
//------------------------------------------
#include<reg51.h>
#include<absacc.h>
#include<stdio.h>
#include"LCD.h"
//----------每位的控制字-----------------
#define FF7 357913941//858993459	//50M															//2147483648  20M			//357913941		 120M															//385136686 		111MHz晶振
#define FF6 35791394//85899346																	//214748365					//35791394																	//38513669
#define FF5 3579139//8589935																		//21474836					//3579139																		//3851367
#define FF4 357914//858993																		//2147484					//357914																		//385137
#define FF3 35791//85899																		//214748					//35791																		//38514
#define FF2 3579//8590																		//21475						//3579																		//3851
#define FF1 358//859																			//2148						//358																			//385
#define FF0 36//86																			//215						//36		
//--------------8279端口定义--------------
#define com XBYTE[0X0001]   															//命令字地址
#define dat XBYTE[0X0000]   															//数据口地址
//--------------DDS控制--------------------
#define  data_OUT  XBYTE[0x1C00]														//采用总线方式CE7
#define	 data_OUT1	XBYTE[0x1400]														//采用总线方式CE5
//--------------AD7524端口定义-------------
#define	AD7524	XBYTE[0x0C00]															//程控衰减地址

unsigned long data temp_r ;																//频率值预存
sfr AUXR = 0x8e;
bit int_flag=0; 																		/*中断标志位*/
sbit clflag=ACC^7;
unsigned char LCD_string[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,'\0'};				//LCD显示字符串变量
unsigned char LCD_step[]={0x00,'\0'};
unsigned char step_i=0;																	//ma步进值下标	
unsigned char step[]={0x00,0x19,0x32,0x4B,0x64,0x7D,0x96,0xAF,0xC8,0xE1,0xFA};			//ma步进控制值
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 		//数码管段码
unsigned char freq[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};							//8位数码管频率值
unsigned char con_word[5]; 																//频率控制字
unsigned char i,temp;																	//temp用于存放临时命令状态字
unsigned char key_value;																//按键值
//-----------------------主要函数--------------------------
void IntToStr(void);																	//LCD显示字符转换
void longtoword(unsigned long num);														//长整型转频率控制字
void write_ad9850(void);																//控制字写入ad9850
void write_ad98501(void);
unsigned long jisuan(unsigned char data *fno);											//频率值产生
unsigned char keyin(void);																//按键函数
void setup_8279(void);																	//8279初始化
void display_led(void);																	//数码管显示
void delay(unsigned char i);															//延时
//------------------频率步进设置----------------------
void f10Mhz(void);																		//S1
void f1Mhz(void);																		//S2
void f100Khz(void);																		//S3
void f10Khz(void);																		//S4
void f1Khz(void);																		//S5
void f100Hz(void);																		//S6	
void f10Hz(void);																		//S7
void f1Hz(void);																		//S8
//-----------------------------------------------------
void carry_sin(void);																	//载波正弦波发生	S9
void mod_sin(void);																		//调制信号正弦波发生S10
void ma_step(void);																		//调制度10%步进
void mode(void);
unsigned char a,b,k;
//-------------------------主函数--------------------------------
void main(void)
{
  	 
     Init_LCD();
	 Clear_Screen();
     Write_Nopara_Command(0x98); 
     AUXR = 0x02;																		/*STC单片机关内部RAM和开ALE*/
  	 EA=1;
  	 EX0=1;																				//开外部中断
  	 IT0=1;
  	//-----------延时(必须加)-------------
  	for(a=0;a<5;a++)
 	{
		for(b=0;b<50;b++)
  		{
			for(k=0;k<50;k++);
		}
	}
  	//------------------------------------
  	setup_8279(); 	 																	//初始化8279
  	delay(1000);
	Display_hz(2,0,"信号发生器");
	Display_String(12,0,"(Hz)");
	Display_hz(0,1,"载波");
	Display_String(4,1,":");
	Display_hz(0,2,"调制波");
	Display_String(6,2,":");
	Display_hz(0,3,"调制度");
	Display_String(6,3,":");
	while(1)
  	{
  		mode();
  	}
}
//------数码管显示----------------
void display_led(void)
{
	for(i=0;i<8;i++)
    {	com=0x80+i;																		//写显示RAM
   		dat=dispcode[freq[7-i]];														//显示段码
   		delay(120);
  	}
}
//-----8279初始化-----------------
void setup_8279(void)
{
	com=0x00;																			//键盘,显示方式
	com=0x34;																			//20分频  
	com=0xd1;																			//1101 0001b 清除所有显示
	temp=com;																			//读状态字
	do{ACC=com;}
	while(clflag==1);   																//清除起来比较慢,所以一条指令执行的时间不足以完成所有清除,故需等待
}

//---------频率值转换控制字----------
void longtoword(unsigned long num)
{
	con_word[0]=0x00;  																	//置工作方式选择位为00
	con_word[4]=num&(0xff);
	num=num>>8;
	con_word[3]=num&(0xff);
	num=num>>8;
	con_word[2]=num&(0xff);
	num=num>>8;
	con_word[1]=num&(0xff);
}
/***计算控制字************/
/***入口:频率数组指针***出口,控制字*****/
unsigned long jisuan(unsigned char data *fno)
{
    unsigned long dds_no ;
    dds_no=
    (*(fno+7))*FF7+
    (*(fno+6))*FF6+
    (*(fno+5))*FF5+
    (*(fno+4))*FF4+
    (*(fno+3))*FF3+
    (*(fno+2))*FF2+
    (*(fno+1))*FF1+
    (*fno)*FF0 ;
    return(dds_no);		
}
//---------------------进位判断-------------------
unsigned char judge(unsigned char a)		
{
	unsigned char b=0;
	if(a>=10)
	{
		b=0;
	}
	else
	{
		b=a;	
	}
	return b;

}
//-------------------步进按键or模式选择---------------
void mode(void)								
{
	if(int_flag==1)
	{
		int_flag=0;
		switch(key_value)
		{
			case 0x40:f10Mhz();break;
			case 0x41:f1Mhz();break;
		 	case 0x42:f100Khz();break;
		 	case 0x43:f10Khz();break;
		 	case 0x48:f1Khz();break;
			case 0x49:f100Hz();break;
		 	case 0x4a:f10Hz();break;
			case 0x4b:f1Hz();break;
		 	case 0x50:carry_sin();break;
			case 0x51:mod_sin();break;
			case 0x52:ma_step();break;
		 	default:break;
		}
 	}

}
/*步进按键函数*/
void f10Mhz(void)																		//10Mhz步进
{
	freq[7]=freq[7]+1;
	freq[7]=judge(freq[7]);
	display_led();
}

void f1Mhz(void)																		//1Mhz步进
{
 	freq[6]=freq[6]+1;
	freq[6]=judge(freq[6]);
	display_led();	
}

void f100Khz(void)																		//100Khz步进
{	
	freq[5]=freq[5]+1;
	freq[5]=judge(freq[5]);
	display_led();
}

void f10Khz(void)																		//10Khz步进
{
	freq[4]=freq[4]+1;
	freq[4]=judge(freq[4]);
	display_led();
}

void f1Khz(void)																		//1Khz步进
{
	freq[3]=freq[3]+1;
	freq[3]=judge(freq[3]);
	display_led();
}

void f100Hz(void)																		//100hz步进
{
	freq[2]=freq[2]+1;
	if(freq[2]>=10)
	{
		freq[2]=0;
		freq[3]=freq[3]+1;	
	}
	display_led();

}

void f10Hz(void)																		//10hz步进
{
	freq[1]=freq[1]+1;
	freq[1]=judge(freq[1]);
	display_led();

}

void f1Hz(void)																			//1hz步进
{
	freq[0]=freq[0]+1;
	freq[0]=judge(freq[0]);
	display_led();

}
//-----------功能模式---------------------------
void carry_sin(void)																	//产生载波正弦波
{
    temp_r=jisuan(freq);
	longtoword(temp_r);
	write_ad9850();																		//发送频率控制字
	IntToStr();
	Display_String(5,1,LCD_string);
}
void mod_sin(void)																		//产生调制信号正弦波
{
	temp_r=jisuan(freq);
	longtoword(temp_r);
	write_ad98501();
	IntToStr();
	Display_String(7,2,LCD_string);
}
void ma_step(void)
{
	step_i++;
	if(step_i==10)
	{
		step_i=0;
	}
	AD7524=step[step_i];
	LCD_step[0]=step_i+'0';
	Display_String(7,3,LCD_step);
	Display_String(8,3,"0");
	Display_String(9,3,"%");
}
//--------------------------------------------------------------------------------------------------
// 函数名称: WRITE_AD9850
// 函数功能: 将控制字写入AD9850
//--------------------------------------------------------------------------------------------------
void write_ad98501(void)
{
     unsigned char no,temp;
	 delay(0);
     for(no=0;no<5;no++)
     {
     	data_OUT1=con_word[no];      													//送控制字 
     	delay(0);
     }
     temp=data_OUT1;                 													//读指令产生上升延,要求AD9850改变输出
}
void write_ad9850(void)
{  
     unsigned char no,temp;
	 delay(0);
     for(no=0;no<5;no++)
     {
     	data_OUT=con_word[no];      													//送控制字 
     	delay(0);
     }
     temp=data_OUT;                 													//读指令产生上升延,要求AD9850改变输出
} 
void IntToStr(void) 
{
	char i,flag_top;   
    flag_top=1;
	for(i=0; i<8; i++)         															//转成ASCII码              	
	{	
		if((freq[7-i]==0)&(flag_top==1))
		{
			LCD_string[i]=' ';
		}
		else
		{
			LCD_string[i]=freq[7-i]+'0';
			flag_top=0;
		}
    }
}
//-----------按键读取------------------------------------------
unsigned char keyin(void)
{
 	unsigned char value;
 	com=0x40;
	value=dat;value=value&0x7f; 														//取键盘数据低7位
 	return(value);
}
void int_int0() interrupt 0 using 0
{
  	int_flag=1;
	key_value=keyin();
}
//-------------------------延时---------------------------------
void delay(unsigned char i)
{
	while(--i);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -