标题:
单片机怎么调节AD9850产生10MHZ方波信号?(目前程序显示成矩形波)
[打印本页]
作者:
光打雷不下雨
时间:
2019-5-10 16:54
标题:
单片机怎么调节AD9850产生10MHZ方波信号?(目前程序显示成矩形波)
程序运行正确,电路可以显示正常的正弦波,方波的占空比设置不对,显示成了矩形波的样子,频率也只在50KHZ-3MHZ之间有波形,高了低了都会失真
希望哪位大神可以帮忙看着是哪里出了问题,虚心请教
单片机源程序如下:
#include"reg51.h"
#include <intrins.h> //编译预处理命令
#define LCD_GO_HOME 0x02 //AC=0,光标、画面回HOME位
//输入方式设置
#define LCD_AC_AUTO_INCREMENT 0x06 //数据读、写操作后,AC自动增一
#define LCD_AC_AUTO_DECREASE 0x04 //数据读、写操作后,AC自动减一
#define LCD_MOVE_ENABLE 0x05 //数据读、写操作,画面平移
#define LCD_MOVE_DISENABLE 0x04 //数据读、写操作,画面不动
//设置显示、光标及闪烁开、关
#define LCD_DISPLAY_ON 0x0C //显示开
#define LCD_DISPLAY_OFF 0x08 //显示关
#define LCD_CURSOR_ON 0x0A //光标显示
#define LCD_CURSOR_OFF 0x08 //光标不显示
#define LCD_CURSOR_BLINK_ON 0x09 //光标闪烁
#define LCD_CURSOR_BLINK_OFF 0x08 //光标不闪烁
//光标、画面移动,不影响DDRAM
#define LCD_LEFT_MOVE 0x18 //LCD显示左移一位
#define LCD_RIGHT_MOVE 0x1C //LCD显示右移一位
#define LCD_CURSOR_LEFT_MOVE 0x10 //光标左移一位
#define LCD_CURSOR_RIGHT_MOVE 0x14 //光标右移一位
//工作方式设置
#define LCD_DISPLAY_DOUBLE_LINE 0x38 //两行显示
#define LCD_DISPLAY_SINGLE_LINE 0x30 //单行显示
void LCD_cls(void);
void LCD_write_data(unsigned char);
void LCD_initial(void);
void LCD_set_position(unsigned char);
void LCD_prints(unsigned char *);
void LCD_printc(unsigned char);
#define LCD_DATA P0 //LCD的数据口
sbit LCD_BUSY=LCD_DATA^7; //LCD忙信号位
sbit LCD_RS=P2^5; //LCD寄存器选择
sbit LCD_RW=P2^6; //LCD读写控制
sbit LCD_EN=P2^7; //LCD使能信号*/
extern void _nop_ (void);
unsigned char s; //无符号
char code tab[4][4]={ {'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}}; //0到F的16个键植
////////////////////////////////////////////////////////////////////
//---------------------------------------------------//
// 程序 //
//---------------------------------------------------//
sbit ad9850_w_clk =P1^2; //P2.2口接ad9850的w_clk脚/PIN7
sbit ad9850_fq_up =P1^1; //P2.1口接ad9850的fq_up脚/PIN8
sbit ad9850_rest =P1^0; //P2.0口接ad9850的rest脚/PIN12
sbit ad9850_bit_data =P1^3; //P1.7口接ad9850的D7脚/PIN25
//***************************************************//
// ad9850复位(串行模式) //
//---------------------------------------------------//
void ad9850_reset_serial()
{
ad9850_w_clk=0;
ad9850_fq_up=0;
//rest信号
ad9850_rest=0;
ad9850_rest=1;
ad9850_rest=0;
//w_clk信号
ad9850_w_clk=0;
ad9850_w_clk=1;
ad9850_w_clk=0;
//fq_up信号
ad9850_fq_up=0;
ad9850_fq_up=1;
ad9850_fq_up=0;
}
//***************************************************//
// 向ad9850中写命令与数据(串行) //
//---------------------------------------------------//
void ad9850_wr_serial(unsigned char w0,double frequence)
{
unsigned char i,w;
long int y;
double x;
//计算频率的HEX值
x=4294967295/125;//适合125M晶振
//如果时钟频率不为180MHZ,修改该处的频率值,单位MHz !!!
frequence=frequence/1000000;
frequence=frequence*x;
y=frequence;
//写w2数据
w=(y>>8);
for(i=0;i<8;i++)
{
ad9850_bit_data=(w>>i)&0x01;
ad9850_w_clk=1;
ad9850_w_clk=0;
}
//写w1数据
w=(y>>24);
for(i=0;i<8;i++)
{
ad9850_bit_data=(w>>i)&0x01;
ad9850_w_clk=1;
ad9850_w_clk=0;
}
//写w0数据
w=w0;
for(i=0;i<8;i++)
{
ad9850_bit_data=(w>>i)&0x01;
}
}
//////////////////////////////////////////////////////////////////////
void LCD_check_busy(void) //检测LCD状态,看它是不是还在忙呢
{
while(1)
{
LCD_EN=0;
LCD_RS=0;
LCD_RW=1;
LCD_DATA=0xff;
LCD_EN=1;
if(!LCD_BUSY)break;
}
LCD_EN=0;
}
void LCD_cls(void) //LCD清屏
{
LCD_check_busy();
LCD_RS=0;
LCD_RW=0;
LCD_DATA=1;
LCD_EN=1;
LCD_EN=0;
}
void LCD_write_instruction(unsigned char LCD_instruction) //写指令到LCD
{
LCD_check_busy();
LCD_RS=0;
LCD_RW=0;
LCD_DATA=LCD_instruction;
LCD_EN=1;
LCD_EN=0;
}
void LCD_write_data(unsigned char LCD_data) //输出一个字节数据到LCD
{
LCD_check_busy();
LCD_RS=1;
LCD_RW=0;
LCD_DATA=LCD_data;
LCD_EN=1;
LCD_EN=0;
}
void LCD_set_position(unsigned char x) //LCD光标定位到x处
{
LCD_write_instruction(0x80+x);
}
/*
void LCD_go_home(void) //LCD光标归位
{
LCD_write_instruction(LCD_GO_HOME);
}
*/
void LCD_printc(unsigned char lcd_data) //输出一个字符到LCD
{
LCD_write_data(lcd_data);
}
void LCD_prints(unsigned char *lcd_string) //输出一个字符串到LCD
{
unsigned char i=0;
while(lcd_string[i]!=0x00)
{
LCD_write_data(lcd_string[i]);
i++;
}
}
void LCD_initial(void) //初始化LCD
{
LCD_write_instruction(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
LCD_write_instruction(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
LCD_write_instruction(LCD_DISPLAY_DOUBLE_LINE);
LCD_cls();
}
void delay(unsigned char a)
{
unsigned char i;
while(a--)
for(i=100;i>0;i--)
;
}
char kbscan() //键盘扫描
{
unsigned char hang,lie,key;
if(P3!=0x0f)
delay(5);
if(P3!=0x0f)
{
switch(P3&0x0f)
{
case 0x0e:hang=3;break;
case 0x0d:hang=2;break;
case 0x0b:hang=1;break;
case 0x07:hang=0;break;
}
P3=0xf0;
P3=0xf0;
switch(P3&0xf0)
{
case 0xe0:lie=0;break;
case 0xd0:lie=1;break;
case 0xb0:lie=2;break;
case 0x70:lie=3;break;
}
P3=0x0f;
while(P3!=0x0f);
key=tab[hang][lie];
}
else
key=0;
return (key);
}
void main()
{
unsigned char temp[10];
unsigned int shuzi[10];
long int f=10000;
s=0;
LCD_initial();
LCD_prints("SET Frequence:");
LCD_set_position(0x4E);
LCD_printc('H');
LCD_set_position(0x4f);
LCD_printc('z');
//LCD_cls();
P3=0x0f;
P0=0xff;
//---------------------------------------------------//
ad9850_reset_serial();
//ad9850_wr_serial(0x00,2500);//串行写2500Hz程序
//---------------------------------------------------//
while(1)
{
ad9850_wr_serial(0x00,f);
temp[s]=kbscan();
shuzi[s]=temp[s]-48;
if(s==1)
{
f=shuzi[0];
}
if(s==2)
{
f=shuzi[1]+10*shuzi[0];
}
if(s==3)
{
f=shuzi[2]+10*shuzi[1]+100*shuzi[0];
//shuzi[3]+10*shuzi[2]+100*shuzi[1]+1000*shuzi[0];
}
if(s==4)
{
f=shuzi[3]+10*shuzi[2]+100*shuzi[1]+1000*shuzi[0];
}
if(s==5)
{
f=shuzi[4]+10*shuzi[3]+100*shuzi[2]+1000*shuzi[1]+10000*shuzi[0];
}
if(s==6)
{
f=shuzi[5]+10*shuzi[4]+100*shuzi[3]+1000*shuzi[2]+10000*shuzi[1]+100000*shuzi[0];
}
if(s==7)
{
f=shuzi[6]+10*shuzi[5]+100*shuzi[4]+1000*shuzi[3]+10000*shuzi[2]+100000*shuzi[1]+1000000*shuzi[0];
}
if(s==8)
{
f=shuzi[7]+10*shuzi[6]+100*shuzi[5]+1000*shuzi[4]+10000*shuzi[3]+100000*shuzi[2]+1000000*shuzi[1]+10000000*shuzi[0];
}
s=0;
shuzi[0]=0;shuzi[1]=0;shuzi[2]=0;shuzi[3]=0;shuzi[4]=0;
shuzi[5]=0;shuzi[6]=0;shuzi[7]=0;shuzi[8]=0;shuzi[9]=0; }
else
{
P0=temp[s];
LCD_set_position(0x40+s);
LCD_printc(temp[s]);
s=s+1;
}
}
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1