我ad9850的程序图,求高人指点,我把不会的部分用红色字...
求高手加q2293859733,求助!非常着急...
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P1^0;
sbit LCD_RW = P1^1;
sbit LCD_E = P1^2;
#define LCD_DATA P0 //液晶1602管脚设置
sbit w_clk = P1^3; // ad9850 w_clk;
sbit fq_ud = P1^4; //ad9850 fqud;
sbit reset = P1^5; //ad9850 reset
sbit s01=P1^6;
sbit s02=P1^7 ; //波形转换使能
unsigned char code Lcdtab1[]= {"Freq: Hz"};
unsigned char code Lcdtab2[]= {"AD9850 Sine -->"};
unsigned char code Lcdtab3[]= {"AD9850 Tria -->"};
unsigned char code Lcdtab4[]= {"AD9850 Squa -->"};
unsigned char code Lcdtab5[]= {"CXL Grad design"};
unsigned char code Lcdtab6[]= {"DDS WELCOME !"};
unsigned char code Lcdtab7[]= {"AD9850 GND -->"};//1602预读字体
double Con_Word_1 = 0x00;
double Con_Word_2 = 0x00;
long uint ConTrol_Word = 0x00;//根据设置的频率换算成将要送入AD9850中的整数量;
long uint Frequency_Out;
uchar a,b,c,d,e,f,g,h,wav;
uchar AnJianCiShuBiangLiang = 0x00;
long uint SheZhiZhongYaoXianShiDeShuJu = 0x00;
uchar dingshiqilideshijianbianliang = 0x00;(定时器的时间变量)
uchar lianjiabiaozhi = 0x00;lianjianbiaozhi = 0x00;
long uint Out_Signal_Max = 30000000;//设置子程序中的上限值,设30MHz
uint Light_Bian_Liang = 0x00;
sbit P3_3 = P3^3;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;
sbit P3_6 = P3^6;
sbit P3_7 = P3^7;//矩阵键盘设置
uchar j = 0,dat = 0;
uchar keyzhi = 0x00;
void lcd_init(void);
void display_string(unsigned char x,unsigned char y,unsigned char *s);
Qu_Chu_Shu_Ma_Ge_Wei();
void time0(void)interrupt 1 using 1 //Interruption
{
EA=0;
dingshiqilideshijianbianliang++;
TH0=0xa6; //shi de sha ping
TL0=0x66;
ET0 =1 ;
TR0 = 1;
EA=1;
}
void delay(long unsigned int h)
{
while(h--); //0.01MS
}
void WriteDataLcd(unsigned char wdata)
{
LCD_RS=1;
LCD_RW=0;
LCD_E=0;
LCD_E=1;
LCD_DATA=wdata;
delay(100); //短暂延时,代替检测忙状态
LCD_E=0;
//LCD_RW = 1;
//LCD_E=1;
}
void WriteCommandLcd(unsigned char wdata)
{
LCD_RS=0;
LCD_RW=0;
LCD_E=0;
LCD_E=1;
LCD_DATA=wdata;
delay(100); //短暂延时,代替检测忙状态
LCD_E=0;
}
//LCD初始化
void lcd_init(void)
{
LCD_DATA = 0;
delay(1000);
WriteCommandLcd(0x38);
delay(500);
WriteCommandLcd(0x38); //显示模式设置
delay(500);
WriteCommandLcd(0x38); //显示模式设置
delay(500);
WriteCommandLcd(0x01); //关闭显示
WriteCommandLcd(0x38); //显示清屏
WriteCommandLcd(0x0c); //显示光标移动设置
WriteCommandLcd(0x06); //显示开及光标移动设置
//WriteCommandLcd(0x0f);
//WriteCommandLcd(0x80);
//WriteDataLcd(0x30);
//WriteDataLcd(0x31);
//WriteDataLcd(0x32);
//WriteDataLcd(0x33);
}
void display_xy(unsigned char x,unsigned char y)
{
if(y==0x01)
{
x = x + 0x40 + 0x80;
}
else
{
x = x+0x80;
}
WriteCommandLcd(x);
}
void display_char(unsigned char x,unsigned char y,unsigned char dat)
{
display_xy(x,y);
WriteDataLcd(dat);
}
void display_string(unsigned char x,unsigned char y,unsigned char *s) (这段是不是申明?*s是什么意思?while(*s)用法)
{
display_xy(x,y);
while(*s)
{
WriteDataLcd(*s);
s++;
}
}
Qu_Chu_Shu_Ma_Ge_Wei()
{
a = Frequency_Out % 10;
b = (Frequency_Out % 100)/10;
c = (Frequency_Out % 1000)/100;
d = (Frequency_Out % 10000)/1000;
e = (Frequency_Out % 100000)/10000;
f = (Frequency_Out % 1000000)/100000;
g = (Frequency_Out % 10000000)/1000000;
h = (Frequency_Out % 100000000)/10000000;
}
scan_KEY(void) //The subprogram is used to scan key
{
uchar key = 0;
key = P3; //Eliminate themost high bit and low three bits
key = key & 0xf8;
switch(key)
{
case 0xb0:
keyzhi = 3 ;break;
case 0xa8:
keyzhi = 2 ;break;
case 0x98:
keyzhi = 1 ;break;
case 0x70:
keyzhi = 6 ;break;
case 0x68:
keyzhi = 5 ;break;
case 0x58:
keyzhi = 4 ;break;
default:
keyzhi=0;
}
return(keyzhi);
}
keychuli()
{
P3_3 = 0x01;P3_4 = 0x01;P3_5 = 0x01;
P3_6 = 0x00;P3_7 = 0x00;
delay(100);
if((P3_3&P3_4&P3_5) == 0x00)
{
//delay(1000);
if((P3_3&P3_4&P3_5) == 0x00)
{
P3_6 = 0x00;P3_7 = 0x01;
dat = scan_KEY();
if(dat == 0x00)
{
P3_6 = 0x01;P3_7 = 0x00;
dat = scan_KEY();
}
}
else
{
dat = 0x00;
goto down;//无键按下
}
}
down:return(dat);
}
display_data()
{
Qu_Chu_Shu_Ma_Ge_Wei();
display_string(0,0,Lcdtab1); //显示第一行,从第2个位置开始
WriteCommandLcd(0x85);//显示数值的话,用其真实的地址,如0x83等,
WriteDataLcd(0x30+h);
WriteDataLcd(0x30+g);
WriteDataLcd(0x30+f);
WriteDataLcd(0x30+e);
WriteDataLcd(0x30+d);
WriteDataLcd(0x30+c);
WriteDataLcd(0x30+b);
WriteDataLcd(0x30+a);
}
Calculate_Control_Word(long uint Frequency_Out)
{
//Con_Word_1 = Frequency_Out * 85;
//Con_Word_2 = Frequency_Out * 0.88526071724;
Con_Word_1 = Frequency_Out * 34;
Con_Word_2 = Frequency_Out * 0.3537898195;//125M晶振
Con_Word_2 = Con_Word_2 + 0.5;
Con_Word_1 = Con_Word_1 + Con_Word_2; //根据设定的频率以浮点形式计算控制字
ConTrol_Word = Con_Word_1 / 1;//将控制字换算成整数形式
}
Send_Control_Word(long uint ConTrol_Word)
{
long uint ConTrol_Word_Temporary ;
uchar data_word ;
w_clk = 0x00; //根据时序图
fq_ud = 0x00; //根据时序图
data_word = 0x00; //相位、掉电等相关控制字
P0 = data_word;
w_clk=1;
delay(50);
w_clk=0;
ConTrol_Word_Temporary = ConTrol_Word;
ConTrol_Word = ConTrol_Word >> 24;
data_word = ConTrol_Word % 256;//取出W1,频率控制字中的最高字节;
P0 = data_word;//AD9850并口接P0;
w_clk=1;
delay(50);
w_clk=0;
ConTrol_Word = ConTrol_Word_Temporary;
ConTrol_Word = ConTrol_Word >> 16;
data_word = ConTrol_Word % 256;//取出W2,频率控制字中的次高字节;
P0 = data_word;
w_clk=1;
delay(50);
w_clk=0;
ConTrol_Word = ConTrol_Word_Temporary;
ConTrol_Word = ConTrol_Word >> 8;
data_word = ConTrol_Word % 256;//取出W3,频率控制字中的第三字节;
P0 = data_word;
w_clk=1;
delay(50);
w_clk=0;
ConTrol_Word = ConTrol_Word_Temporary;
data_word = ConTrol_Word % 256;//取出W4,频率控制字中的最后一个字节;
P0= data_word;
w_clk=1;
delay(50);
w_clk=0; //根据时序图
fq_ud=1; //根据时序图
}
main()
{
unsigned char i = 0x00;
long uint shiyanshuju = 0x00;
reset = 1; //复位AD9850;
delay(10000);
reset = 0; //AD9850恢复工作模式;
lcd_init();
TMOD=0x01; //用来实现时间设置
TH0=0xa6;
TL0=0x66;
ET0 = 1;
TR0 = 1;
EA = 0x00;
Frequency_Out =1000;//开机默认的频率输出值;
Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;
Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;
display_data();
display_string(0,1,Lcdtab6);
AnJianCiShuBiangLiang = 0x00;
//WriteCommandLcd(0xc5);
//WriteDataLcd(0x30+(Step_Data/1000));
//WriteDataLcd(0x30+(Step_Data/100)%10);
//WriteDataLcd(0x30+(Step_Data/10)%10);
//WriteDataLcd(0x30+(Step_Data%10));
//display_string(9,1,"Hz");
while(1)
{
if(dingshiqilideshijianbianliang == 10)
{
WriteCommandLcd(0x85+AnJianCiShuBiangLiang);//显示数值的话,用其真实的地址,如0x83等,拼音是定时器计数器的时间变量
WriteDataLcd(0x20); //空格
dingshiqilideshijianbianliang = 11;
}
if(dingshiqilideshijianbianliang == 20)
{
WriteCommandLcd(0x85+AnJianCiShuBiangLiang);//显示数值的话,用其真实的地址,如0x83等,
WriteDataLcd(0x30+shiyanshuju);
dingshiqilideshijianbianliang = 0x00;
}
keychuli(); //键盘配置;
if(dat == 0x02)
{
dat = 0x00;delay(5000); //升频键;
if(AnJianCiShuBiangLiang == 7)
{
if((Frequency_Out+1) <= 30000000)
{
Frequency_Out = Frequency_Out+1;
}
}
if(AnJianCiShuBiangLiang == 6)
{
if((Frequency_Out+10) <= 30000000)
{
Frequency_Out = Frequency_Out+10;
}
}
if(AnJianCiShuBiangLiang == 5)
{
if((Frequency_Out+100) <= 30000000)
{
Frequency_Out = Frequency_Out+100;
}
}
if(AnJianCiShuBiangLiang == 4)
{
if((Frequency_Out+1000) <= 30000000)
{
Frequency_Out = Frequency_Out+1000;
}
}
if(AnJianCiShuBiangLiang == 3)
{
if((Frequency_Out+10000) <= 30000000)
{
Frequency_Out = Frequency_Out+10000;
}
}
if(AnJianCiShuBiangLiang == 2)
{
if((Frequency_Out+100000) <= 30000000)
{
Frequency_Out = Frequency_Out+100000;
}
}
if(AnJianCiShuBiangLiang == 1)
{
if((Frequency_Out+1000000) <= 30000000)
{
Frequency_Out = Frequency_Out+1000000;
}
}
if(AnJianCiShuBiangLiang == 0)
{
if((Frequency_Out+10000000) <= 30000000)
{
Frequency_Out = Frequency_Out+10000000;
}
}
display_data();//刷新显示;;
if(AnJianCiShuBiangLiang == 7)
{
shiyanshuju = a;
}
if(AnJianCiShuBiangLiang == 6)
{
shiyanshuju = b;
}
if(AnJianCiShuBiangLiang == 5)
{
shiyanshuju = c;
}
if(AnJianCiShuBiangLiang == 4)
{
shiyanshuju = d;
}
if(AnJianCiShuBiangLiang == 3)
{
shiyanshuju = e;
}
if(AnJianCiShuBiangLiang == 2)
{
shiyanshuju = f;
}
if(AnJianCiShuBiangLiang == 1)
{
shiyanshuju = g;
}
if(AnJianCiShuBiangLiang == 0)
{
shiyanshuju = h;
}
dingshiqilideshijianbianliang = 18;
}
if(dat == 0x05)
{
dat = 0x00;delay(5000); //降频键;
if(AnJianCiShuBiangLiang == 7)
{
if(Frequency_Out >= 1)
{
Frequency_Out = Frequency_Out-1;
}
}
if(AnJianCiShuBiangLiang == 6)
{
if(Frequency_Out >= 10)
{
Frequency_Out = Frequency_Out-10;
}
}
if(AnJianCiShuBiangLiang == 5)
{
if(Frequency_Out >= 100)
{
Frequency_Out = Frequency_Out-100;
}
}
if(AnJianCiShuBiangLiang == 4)
{
if(Frequency_Out >= 1000)
{
Frequency_Out = Frequency_Out-1000;
}
}
if(AnJianCiShuBiangLiang == 3)
{
if(Frequency_Out >= 10000)
{
Frequency_Out = Frequency_Out-10000;
}
}
if(AnJianCiShuBiangLiang == 2)
{
if(Frequency_Out >= 100000)
{
Frequency_Out = Frequency_Out-100000;
}
}
if(AnJianCiShuBiangLiang == 1)
{
if(Frequency_Out >= 1000000)
{
Frequency_Out = Frequency_Out-1000000;
}
}
if(AnJianCiShuBiangLiang == 0)
{
if(Frequency_Out >= 10000000 & Frequency_Out <= 30000000)
{
Frequency_Out = Frequency_Out - 10000000;
}
}
display_data();//刷新显示;;
if(AnJianCiShuBiangLiang == 7)
{
shiyanshuju = a;
}
if(AnJianCiShuBiangLiang == 6)
{
shiyanshuju = b;
}
if(AnJianCiShuBiangLiang == 5)
{
shiyanshuju = c;
}
if(AnJianCiShuBiangLiang == 4)
{
shiyanshuju = d;
}
if(AnJianCiShuBiangLiang == 3)
{
shiyanshuju = e;
}
if(AnJianCiShuBiangLiang == 2)
{
shiyanshuju = f;
}
if(AnJianCiShuBiangLiang == 1)
{
shiyanshuju = g;
}
if(AnJianCiShuBiangLiang == 0)
{
shiyanshuju = h;
}
dingshiqilideshijianbianliang = 18;
}
if(dat == 0x03)
{
dat = 0x00;delay(5000); //光标左移键;
EA = 0x01;
if(AnJianCiShuBiangLiang == 0x00)
{
AnJianCiShuBiangLiang = 0x07;
}
else
{
AnJianCiShuBiangLiang--;
}
display_data();//刷新显示;;
display_string(0,1,Lcdtab5);
if(AnJianCiShuBiangLiang == 7)
{
shiyanshuju = a;
}
if(AnJianCiShuBiangLiang == 6)
{
shiyanshuju = b;
}
if(AnJianCiShuBiangLiang == 5)
{
shiyanshuju = c;
}
if(AnJianCiShuBiangLiang == 4)
{
shiyanshuju = d;
}
if(AnJianCiShuBiangLiang == 3)
{
shiyanshuju = e;
}
if(AnJianCiShuBiangLiang == 2)
{
shiyanshuju = f;
}
if(AnJianCiShuBiangLiang == 1)
{
shiyanshuju = g;
}
if(AnJianCiShuBiangLiang == 0)
{
shiyanshuju = h;
}
dingshiqilideshijianbianliang = 18;
}
if(dat == 0x01)
{
dat = 0x00;delay(5000); //光标右移键;
EA = 0x01;
if(AnJianCiShuBiangLiang == 0x07)
{
AnJianCiShuBiangLiang = 0x00;
}
else
{
AnJianCiShuBiangLiang++;
}
display_data();//刷新显示;
display_string(0,1,Lcdtab5);
if(AnJianCiShuBiangLiang == 7)
{
shiyanshuju = a;
}
if(AnJianCiShuBiangLiang == 6)
{
shiyanshuju = b;
}
if(AnJianCiShuBiangLiang == 5)
{
shiyanshuju = c;
}
if(AnJianCiShuBiangLiang == 4)
{
shiyanshuju = d;
}
if(AnJianCiShuBiangLiang == 3)
{
shiyanshuju = e;
}
if(AnJianCiShuBiangLiang == 2)
{
shiyanshuju = f;
}
if(AnJianCiShuBiangLiang == 1)
{
shiyanshuju = g;
}
if(AnJianCiShuBiangLiang == 0)
{
shiyanshuju = h;
}
dingshiqilideshijianbianliang = 18;
}
if(dat == 0x04)
{
dat = 0x00;delay(1000); //确定、输出波形选择键;
EA = 0x00; s01=0x00;s02=0x00;
display_data();//刷新显示;
Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;
Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;
AnJianCiShuBiangLiang = 0x00;
{
switch(wav)
{
case 0: //波形选择;
{
s01=0;
s02=1;
display_string(0,1,Lcdta
呃,我也是做这个,可是我还没写程序。你厉害噢~~
额 void display_string(unsigned char x,unsigned char y,unsigned char *s) (这段是不是申明?*s是什么意思?while(*s)用法)
{
display_xy(x,y);
while(*s)
{
WriteDataLcd(*s);
s++;
}
}
就这段程序的 函数命名分析可知 这段代码的作用是 LCD输出一个字符串 这里的 *s是一个指针 指向待输出的字符串数组的首地址
while(*s)的意思是 当 *s指向的数据返回 0 时证明已经到了数据的尽头,即显示完毕。因为循环体内有s++;这句用来指向下一个数据
我自己的个人习惯是
while( s[i]!='\0' )
{
WriteDataLcd(s[i]);
i++;
}
这样可能稍微好理解一些