基于单片机的多功能信号发生器的源程序及电路图.docx
- 文档编号:9641290
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:20
- 大小:1,021.31KB
基于单片机的多功能信号发生器的源程序及电路图.docx
《基于单片机的多功能信号发生器的源程序及电路图.docx》由会员分享,可在线阅读,更多相关《基于单片机的多功能信号发生器的源程序及电路图.docx(20页珍藏版)》请在冰豆网上搜索。
基于单片机的多功能信号发生器的源程序及电路图
程序源代码
#include
#include
#include
voidDelay1ms(WORDcount);//软件延时函数
voiddisplay_freq(void);//更新频率函数
BYTEcodeCursor[]={0xC3,0XC4,0XC6,0XC7,0XC8,0XCA,0XCB,0XCC,0x85};//换算光标位置
unsignedinta;//控制长时间不操作隐藏光标
unsignedcharstep=4;//移动光标
bitflag=0;//控制光标闪烁
unsignedlongintcodeData[]={10000000,1000000,100000,10000,1000,100,10,1};//换算加减值
unsignedlongintFreqency_Out=1000;//初始化频率输出值
unsignedcharWave_Out=1;
unsignedchardataDY[3]={0x00,0x00,0x00};
unsignedcharDA;
unsignedlongintXS;
sbitKEY1=P1^0;
sbitKEY2=P1^1;
sbitKEY3=P1^2;
sbitKEY4=P1^3;
sbitKEY5=P1^4;
sbitKEY6=P1^5;
sbitBEEP=P3^7;
sbitdin=P3^4;
sbitclk=P3^5;
sbitcs=P3^6;
/*us级延时函数*/
/*******************************************************************/
voidDelayuS(unsignedintnum)
{
while(--num);
}
/*软件延时1*m毫秒*/
voidDelay1ms(WORDcount)
{
BYTEi,j;
for(;count>0;count--)
for(i=2;i>0;i--)
for(j=248;j>0;j--);
}
voiddisplay_freq(void)//显示频率
{unsignedcharj;
unsignedlonginttemp;
temp=Freqency_Out;
tab2[3]=temp/10000000+0x30;//
tab2[4]=temp%10000000/1000000+0x30;
tab2[6]=temp%10000000%1000000/100000+0x30;
tab2[7]=temp%10000000%1000000%100000/10000+0x30;
tab2[8]=temp%10000000%1000000%100000%10000/1000+0x30;
tab2[10]=temp%10000000%1000000%100000%10000%1000/100+0x30;
tab2[11]=temp%10000000%1000000%100000%10000%1000%100/10+0x30;
tab2[12]=temp%10000000%1000000%100000%10000%1000%100%10+0x30;
WriteLCD(0,0xC0);//设置显示位置为第二行第一个字
for(j=0;j<15;j++)
{WriteLCD(1,tab2[j]);}
switch(Wave_Out)
{case1:
Load_wave(0x2000,Freqency_Out,0xD000);break;
case2:
Load_wave(0x2002,Freqency_Out,0xD000);break;
case3:
Load_wave(0x2028,Freqency_Out,0xD000);break;
}
}
voiddisplay_Wave(void)//变换波形
{unsignedcharj;
switch(Wave_Out)
{case1:
WriteLCD(0,0x80);Load_wave(0x2000,Freqency_Out,0xD000);
for(j=0;j<10;j++)
{WriteLCD(1,tab1_1[j]);}break;
case2:
WriteLCD(0,0x80);Load_wave(0x2002,Freqency_Out,0xD000);
for(j=0;j<10;j++)
{WriteLCD(1,tab1_2[j]);}break;
case3:
WriteLCD(0,0x80);Load_wave(0x2028,Freqency_Out,0xD000);
for(j=0;j<10;j++)
{WriteLCD(1,tab1_3[j]);}break;
}
//设置显示位置为第二行第一个字
}
voidinitTimer(void)//定时器初始化初值
{
TMOD=0x2;//方式二
TH0=0x49;//200us
TL0=0x49;
}
/*******************************************************************/
/*蜂鸣器响一声*/
/*******************************************************************/
voidbeep()
{
unsignedchary;
for(y=0;y<100;y++)
{
DelayuS(60);
BEEP=!
BEEP;//BEEP取反
}
BEEP=1;//关闭蜂鸣器
DelayuS(40000);
}
voidTLC5615(DA)
{
unsignedchary;
DA<<=6;//舍弃前6位
for(y=0;y<12;y++)//从高到低发送
{
if((DA&0x8000)==0)
din=0;
elsedin=1;
//din=x&0x8000;//此处不能用din=x&0x8000;
cs=0;
clk=1;
;;;
clk=0;
DA=DA<<1;
}
cs=1;
}
/*电压转换与显示*/
/*******************************************************************/
Disp_dianya()
{
DY[2]=XS/100+0x30;
DY[0]=XS%100;
DY[1]=DY[0]/10+0x30;
DY[0]=DY[0]%10+0x30;
WriteLCD(0,0x8B);
WriteLCD(1,DY[2]);//十位数显示
WriteLCD(0,0x8D);
WriteLCD(1,DY[1]);//个位数显示
WriteLCD(0,0x8E);
WriteLCD(1,DY[0]);//小数显示
}
voidmain(void)//主函数
{unsignedchari;
initTimer();//定时器初始化
TR0=1;
ET0=1;
DA=175;//DA初始电压
XS=5;//显示初始电压
TLC5615(DA);
LCD_Initial();//液晶初始化
WriteLCD(0,0x80);//设置显示位置为第一行第一个字
for(i=0;i<16;i++)
{WriteLCD(1,tab1_1[i]);}//每行16个字,且光标自动右移
WriteLCD(0,0xC0);//设置显示位置为第二行第一个字
for(i=0;i<16;i++)
{WriteLCD(1,tab2[i]);}//每行16个字,且光标自动右移
Disp_dianya();
DDSIni();//初始化AD9833
Load_wave(0x2000,Freqency_Out,0xD000);//1KHz正弦信号
display_freq();
EA=1;//开启总中断
WriteLCD(0,Cursor[step]);//设置显示位置为第二行第一个字
while
(1)
{
if(KEY2==0)//Right光标右移
{Delay1ms(50);
if(KEY2==0)
{if(a!
=0)//在没有光标时,第一次按下向左,向右按键时,光标不移动,只是显示出光标,并闪烁
{step++;if(step==9)step=0;}
WriteLCD(0,0x0F);//开显示,开光标,闪烁
WriteLCD(0,Cursor[step]);//显示出当前光标的位置
EA=1;a=0;//当有按键按下时,开启定时器,计时开始。
beep();
while(KEY2==0);
}
}
if(KEY1==0)//Left光标左移
{Delay1ms(50);
if(KEY1==0)
{if(a!
=0)//在没有光标时,第一次按下向左,向右按键时,光标不移动,只是显示出光标,并闪烁
{if(step==0)step=9;
step--;
}
WriteLCD(0,0x0F);//开显示,开光标,闪烁
WriteLCD(0,Cursor[step]);//显示出当前光标的位置
EA=1;a=0;//当有按键按下时,开启定时器,计时开始。
beep();
while(KEY1==0);
}
}
if(KEY3==0)//Up加
{Delay1ms(50);
if(KEY3==0)
{if(a!
=0)//在没有光标时,不能调整频率
{if(step<8)
{if(Freqency_Out+Data[step]<=12500000)//判断频率是否大于12.5MHZ
{Freqency_Out=Freqency_Out+Data[step];
//Load_wave(0x2000,Freqency_Out,0xD000);
display_freq();//液晶刷新显示,且更新频率、相位
WriteLCD(0,Cursor[step]);//显示出当前光标的位置
}
}
if(step>=8)
{Wave_Out++;
if(Wave_Out==4)Wave_Out=1;
display_Wave();
WriteLCD(0,Cursor[step]);//显示出当前光标的位置
}
}
a=0;//定时器重新开始计算开始时间,防止在按的时候隐藏光标
beep();
while(KEY3==0);
}
}
if(KEY4==0)//Down减
{Delay1ms(50);
if(KEY4==0)
{if(a!
=0)//在没有光标时,不能调整频率
{if(step<8)
{if(Freqency_Out>=Data[step])//判断频率是否大于0HZ
{Freqency_Out=Freqency_Out-Data[step];
//Load_wave(0x2000,Freqency_Out,0xD000);
display_freq();//液晶刷新显示,且更新频率、相位
WriteLCD(0,Cursor[step]);//显示出当前光标的位置
}
}
if(step>=8)
{if(Wave_Out==1)Wave_Out=4;
Wave_Out--;
display_Wave();
WriteLCD(0,Cursor[step]);//显示出当前光标的位置
}
}
a=0;//定时器重新开始计算开始时间,防止在按的时候隐藏光标
beep();
while(KEY4==0);
}
}
if(KEY5==0)//幅度加
{Delay1ms(50);
if(KEY5==0)
{
DA++;
XS++;
TLC5615(DA);
Disp_dianya();
beep();
Delay1ms(50);
}
}
if(KEY6==0)//幅度减
{Delay1ms(50);
if(KEY6==0)
{
DA--;
XS--;
TLC5615(DA);
Disp_dianya();
beep();
Delay1ms(50);
}
}
if(flag==1)//当按键超过4S不操作时光光标
{flag=0;
WriteLCD(0,0x0C);//关光标,关闪烁
a=0;EA=0;//关掉定时器,清除计数
}
}
}
voidtimer0(void)interrupt1//中断服务程序,用于隐藏光标
{
a++;
if(a==30000)
{a=0;
flag=1;
}
}
#include
#defineBYTEunsignedchar//宏定义
#defineWORDunsignedint
voidWriteLCD(BYTEstyle,BYTEinput);//向LCD写入命令或数据函数
BYTEWait(void);//等待写操作结束函数
voidLCD_Initial(void);//初始化液晶函数
/*液晶管脚连线*/
sbitLCDRS=P2^5;//寄存器选择1:
数据;0:
指令
sbitLCDRW=P2^6;//读写操作选择1:
读;0:
写
sbitLCDE=P2^7;//使能信号
sbitBUSY=ACC^7;//忙标志位(非管脚)
BYTEcodetab1_1[]={"Wave=1Sin0.00V"};//初始化液晶显示值正弦波
BYTEcodetab1_2[]={"Wave=2Tri"};//初始化液晶显示值三角波
BYTEcodetab1_3[]={"Wave=3Squ"};//初始化液晶显示值方波
BYTEtab2[]={"F=00,000,000Hz"};
voidDelay(WORDcount)
{
BYTEi,j;
for(;count>0;count--)
for(i=2;i>0;i--)
for(j=248;j>0;j--);
}
/*等待写操作结束函数*/
BYTEWait(void)
{
LCDRS=0;
LCDRW=1;_nop_();
LCDE=1;_nop_();//读忙标志和AC码时,LCDE高电平
do
{
ACC=P0;//判断忙信号为P0_7
}while(BUSY==1);//写操作忙,等待
LCDE=0;
Delay
(1);
returnACC;
}
voidWriteLCD(BYTEstyle,BYTEinput)//向LCD写入命令或数据
{
LCDRS=style;
LCDRW=0;_nop_();
LCDE=1;_nop_();//LCDE下降沿写入
P0=input;_nop_();//P0口为数据输入口
LCDE=0;_nop_();
Wait();//等待写入完成
}
voidLCD_Initial(void)//液晶初始化函数
{
LCDE=0;
Delay(10);
WriteLCD(0,0x38);//8位数据口,两行显示,5*7点阵,//功能设置
WriteLCD(0,0x0f);//开显示,光标,闪烁
WriteLCD(0,0x06);//AC自动增一,画面不动
WriteLCD(0,0x02);//光标返回到00HAC=0
WriteLCD(0,0x01);//清屏
}
/*AD9833串行控制模式,采用25MHZ有源晶振,*/
voidDDSIni(void);
voidAD9833_reset(void);
voidSDelay(unsignedcharDelayNum);
voidAD9833_writedata(unsignedintDDSdata);
voidLoad_wave(unsignedintContr_Reg_data,unsignedlongintFreq_data,unsignedintPhs_data);
//voidLoad_wave(unsignedintContr_Reg_data,unsignedintFre_MSBdata,unsignedintFre_LSBdata,unsignedintPhs_data);
//Load_wave(0x2000,0x4020,0x7020,0xD000);//50KHz正弦信号VPP=600MV
//Load_wave(0x2002,0x4020,0x7020,0xD000);//50KHz三角波信号VPP=600MV
//Load_wave(0x2028,0x4020,0x7020,0xD000);//50KHz方波信号0-5V50%占空比
//Load_wave(0x2020,0x4020,0x7020,0xD000);//25KHz方波信号0-5V50%占空比
sbitFSYNC=P2^2;//AD9833控制脚
sbitSCLK=P2^1;
sbitSDATA=P2^0;
voidDDSIni(void)
{
FSYNC=1;//FSYNCdisable
SCLK=1;//Clockhigh
SDATA=0;
AD9833_reset();
}
voidAD9833_reset(void)
{
//addcodehere
AD9833_writedata(0x0100);//寄存器复位
AD9833_writedata(0x2000);//准备清空频率寄存器0
AD9833_writedata(0x4000);//Filledwith0
AD9833_writedata(0x4000);//Filledwith0
AD9833_writedata(0x2000);//PrepareforclearFre1
AD9833_writedata(0x8000);//Filledwith0
AD9833_writedata(0x8000);//Filledwith0
AD9833_writedata(0xD000);//clearPHS0
AD9833_writedata(0xF000);//clearPHS1
}
voidSDelay(unsignedcharDelayNum)
{
while(DelayNum--);
}
/////////////////////////////////////
/*函数描述:
AD9833写数据操作
/*写入参数:
AD9833控制字,16bit
/*返回参数:
无
/*描述:
标准时序
*////////////////////////////////////
voidAD9833_writedata(unsignedintDDSdata)
{
unsignedchardata_num=0;
unsignedintDDSdata_temp;
DDSdata_temp=DDSdata;
SCLK=1;
SDelay(4);
FSYNC=0;//DDSable
SDelay(4);
for(data_num=0;data_num<16;data_num++)
{
if(DDSdata_temp&0X8000)
{
SDATA=1;
}
else
{
SDATA=0;
}
SDelay(5);
SCLK=0;
SDelay(5);
SDATA=0;
SDelay(5);
SCLK=1;
DDSdata_temp=DDSdata_temp<<1;
if(data_num<15)
{
SDelay(50);
}
}
FSYNC=1;
}
/////////////////////////////////////
/*函数描述:
AD9833加载波新
/*写入参数:
控制字、32bit(28bit有效)的频率数据,16bit(12bit有效)的相位数据
/*返回参数:
无
*////////////////////////////////////
voidLoad_wave(unsignedintContr_Reg_data,unsignedlongintFreq_data,unsignedintPhs_data)
{unsignedlongintFreq_temp=0;
unsignedintFre_MSBdata,Fre_LSBdata;
Freq_temp=(unsignedlongint)(10.738*Freq_data);//SYSCLK=25MHz2^28/25000000=10.7374
Fre_LSBdata=Freq_temp&0x3fff;
Fre_LSBdata=Fre_LSBdata|0x4000;
Fre_MSBdata=(Freq_temp>>14)&0x3fff;
Fre_MSBdata=Fre_MSBdata|0x4000;
AD9833_writedata(Contr_Reg_data);
AD9833_writedata(Fre_LSBdata);
AD9833_writedata(Fre_MSBdata);
AD9833_writedata(Phs_data);
}
/*
voidLoad_wave(unsi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 多功能 信号发生器 源程序 电路图