📄 ad9835_v2.c
字号:
//F=12MHz with LCD1602
//2008/4/13 AD9835 on AT89C51
#include <reg51.H>
#include <stdio.h>
#include <INTRINS.H>//_nop_()
typedef unsigned char uchar;
typedef unsigned int uint;
//键排列
// 7 8 9 C
// 4 5 6 D
// 1 2 3 E
// A 0 B F
//LCD 1602
sbit LCD_D7=P2^7;
sbit LCD_D6=P2^6;
sbit LCD_D5=P2^5;
sbit LCD_D4=P2^4;
sbit LCD_E =P2^3;
sbit LCD_RW=P2^2;
sbit LCD_RS=P2^1;
//I/O
sbit BEP=P2^0;//Beep
sbit LED=P3^2;//RED LED
//AD9835
sbit DAT=P3^0;//
sbit CLK=P3^1;//
sbit SYC=P3^3;//
//FREQ
sbit FRQ=P3^5;//T1 check
#define No_key 255
//键值
#define MHz 12 //MHz
#define KHz 13 //KHz
#define Hzz 14 //Hz
#define point 15//小数点
#define shift 11//不用
#define back 10 //改正
uchar freq[8]={0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00};//8位频率数800.0Hz
uchar F_word[4];
uchar step=8,cur=7,act=0,key=No_key;//act有效位
uchar buf[9];//输入缓存
/*------------------------------------------------------------------
Public function prototypes
--------------------------------------------------------------------*/
void LCD_init (void);
void LCD_en_write (void);
void LCD_write_char (uchar cd,uchar ab);
void LCD_set_xy (uchar x, uchar y);
void LCD_write_str (uchar X,uchar Y,uchar *s);
void LCD_byte (uchar abc);
void delay_nus (uint n);
void del_ms (uint n);
uchar Key_scan (void);
void Key_num (uchar n); //输入数字并显示
uchar Key_table (k);
void bee(); //低有效蜂鸣
void Long_bee (void); //低有效蜂鸣长声
void AD9835_byte (uchar a); //发一个字节
void AD9835_word (uchar *p); //发一个字两个字节
void AD9835_init (void); //初始化和写频
void AD9835_calc (void); //计算出频率寄存器的四个字节值
void disp(void); //显示
//------------------------------------
void LCD_init(void) //液晶初始化
{
P1=0xFF;
P3=0xff; //输出
LCD_RS=0; //
del_ms(50);
LCD_write_char(0x30,0);
del_ms(6);
LCD_write_char(0x30,0); //
del_ms(1);
LCD_write_char(0x30,0); //上电即显示正常,无需复位
del_ms(1);
LCD_write_char(0x02,0);
del_ms(1);
LCD_write_char(0x28,0); //4bit test显示模式设置(不检测忙信号)
del_ms(1);
LCD_write_char(0x08,0); // 显示关闭
del_ms(1);
LCD_write_char(0x01,0); // 显示清屏
del_ms(1);
LCD_write_char(0x06,0); // 显示光标移动设置
del_ms(1);
LCD_write_char(0x0C,0); // 显示开及光标设置
del_ms(10);
}
//---------------------------------------------
void LCD_write_str(uchar X,uchar Y,uchar *s)
{
LCD_set_xy( X, Y ); //写地址
while (*s) // 写显示字符
{
LCD_write_char( 0, *s );
s ++;
}
}
void LCD_set_xy( uchar x, uchar y ) //写地址函数
{
uchar address;
if (y == 0) address = 0x80 + x;
else
address = 0xc0 + x;
LCD_write_char( address, 0 );
}
//------------------------------------------------
void LCD_en_write(void) //液晶使能
{
_nop_();
LCD_E=1;//EN=1
_nop_();
LCD_E=0;//EN=0
}
//------------------------------------------------
void LCD_write_char(uchar cd,uchar ab) // 写数据
{
delay_nus(20);
if(cd==0)
{
LCD_RS=1; //RS=1,写显示内容
LCD_byte(ab);
}
else
{
LCD_RS=0; //RS=0,写命令
LCD_byte(cd);
}
}
//-----------------------------------------------
void LCD_byte(uchar abc)//
{
delay_nus(50);
if(((abc<<0)&0x80)==0) //MSB is output first
LCD_D7=0; //abc=0
else LCD_D7=1; //abc=1
if(((abc<<1)&0x80)==0) //MSB is output first
LCD_D6=0; //abc=0
else LCD_D6=1; //abc=1
if(((abc<<2)&0x80)==0) //MSB is output first
LCD_D5=0; //abc=0
else LCD_D5=1; //abc=1
if(((abc<<3)&0x80)==0) //MSB is output first
LCD_D4=0; //abc=0
else LCD_D4=1; //abc=1
LCD_en_write();
if(((abc<<4)&0x80)==0) //MSB is output first
LCD_D7=0; //abc=0
else LCD_D7=1; //abc=1
if(((abc<<5)&0x80)==0) //MSB is output first
LCD_D6=0; //abc=0
else LCD_D6=1; //abc=1
if(((abc<<6)&0x80)==0) //MSB is output first
LCD_D5=0; //abc=0
else LCD_D5=1; //abc=1
if(((abc<<7)&0x80)==0) //MSB is output first
LCD_D4=0; //abc=0
else LCD_D4=1; //abc=1
LCD_en_write();
}
//-------------------------------------
uchar Key_table(k)
{
uchar TempNum;
switch (k)
{
case 0x11:TempNum=12;break;
case 0x12:TempNum=13;break;
case 0x14:TempNum=14;break;
case 0x18:TempNum=15;break;
case 0x88:TempNum=10;break;
case 0x28:TempNum=11;break;
case 0x48:TempNum=0;break;
case 0x84:TempNum=1;break;
case 0x44:TempNum=2;break;
case 0x24:TempNum=3;break;
case 0x82:TempNum=4;break;
case 0x42:TempNum=5;break;
case 0x22:TempNum=6;break;
case 0x81:TempNum=7;break;
case 0x41:TempNum=8;break;
case 0x21:TempNum=9;break;
default:break;
}
return TempNum;
}
//--------------------------------------
uchar Key_scan(void)
{uchar sccode,recode;
P1=0xf0;
if((P1&0xf0)!=0xf0) /* 若有健按下*/
{del_ms(12); /*延时去抖动*/
if((P1&0xf0)!=0xf0)
{sccode=0xfe; /*逐行扫描初值*/
while((sccode&0x10)!=0)
{P1=sccode; /*输出行扫描码*/
if((P1&0xf0)!=0xf0) /*本行有键按下*/
{recode=(P1&0xf0)|0x0f;
return((~sccode)+(~recode)); /*返回特征字节码*/
}
else
sccode=(sccode<<1)|0x01; /*行扫描码左移一位*/
}
}
}
return No_key; /*无键按下返回0*/
}
//-------------------------------
void Key_num(unsigned char n)//输入数字并显示
{
if(step==0){Long_bee();}
else {
buf[step]=n;n=n|0x30;
LCD_set_xy(cur,0); //地址
LCD_write_char(0,n);
step--;cur++;}
key=No_key;
}
//---------------------------
void bee()//低有效蜂鸣
{
P2=P2&0xFE;//P2.0=0
del_ms(100);
P2=P2|0x01;//P2.0=1
}
//---------------------------
void Long_bee(void)//长蜂鸣
{
BEP=0;//PB0=1
del_ms(400);
BEP=1;//PB0=0
}
//----------------------------------------------
void delay_nus(uint n) //N us延时函数
{
uint i=0;
for (i=0;i<n;i++)
_nop_();
}
//--------------------------------------
void del_ms(uint n)//n毫秒延时
{ uchar j;
while(n--)
{for(j=0;j<125;j++);}
}
//---------------------------
void disp(void)//显示
{
uchar disbuf[8];
uchar i;
for(i=0;i<=7;i++)
{disbuf[i]=freq[i]|0x30;}
if(disbuf[7]==0x30)
{disbuf[7]=0x20;
if(disbuf[6]==0x30)
{disbuf[6]=0x20;
if(disbuf[5]==0x30)
{disbuf[5]=0x20;
if(disbuf[4]==0x30)
{disbuf[4]=0x20;
if(disbuf[3]==0x30)
{disbuf[3]=0x20;
if(disbuf[2]==0x30)
{disbuf[2]=0x20;
}
}
}
}
}
}
LCD_set_xy(0,1);//地址
LCD_write_char(0,disbuf[7]);
LCD_write_char(0,disbuf[6]);
LCD_write_char(0,disbuf[5]);
LCD_write_char(0,disbuf[4]);
LCD_write_char(0,disbuf[3]);
LCD_write_char(0,disbuf[2]);
LCD_write_char(0,disbuf[1]);
LCD_write_char(0,0x2e);//小数点
LCD_write_char(0,disbuf[0]);
LCD_write_str(9,1," Hz TJX");
}
//--------------------------------
void AD9835_byte(uchar a)//发一个字节
{
uchar n=0;
for(n=0;n<8;n++)
{
if(((a<<n)&0x80)==0){DAT=0;} //DATA=0 MSB is output first
else{DAT=1;} //DATA=1
CLK=0; //SCLK=0
_nop_();
_nop_();
CLK=1; //SCLK=1
}
}
//---------------------------
void AD9835_word(uchar *p)//发一个字两个字节
{
SYC=0;//FSYNC=0
AD9835_byte(*p);
p++;
AD9835_byte(*p);
SYC=1;//FSYNC=1
}
//--------------------------------
void AD9835_init(void)//passed!
{
uchar dds[2]={0xF8,0X00};
AD9835_word(dds);
dds[0]=0x33;
dds[1]=F_word[0];
AD9835_word(dds);
dds[0]=0x22;
dds[1]=F_word[1];
AD9835_word(dds);
dds[0]=0x31;
dds[1]=F_word[2];
AD9835_word(dds);
dds[0]=0x20;
dds[1]=F_word[3];
AD9835_word(dds);
dds[0]=0xC0;
dds[1]=0x00;
AD9835_word(dds);
}
//-------------------------------------
//Fc=50MHz K=85.8993459 passed!!
//计算出频率寄存器的四个字节值
void AD9835_calc(void)
{
unsigned long z=0;
float x;
x=(freq[0]*0.1+freq[1]*1+freq[2]*10+freq[3]*100+freq[4]*1000+freq[5]*10000
+freq[6]*100000+freq[7]*1000000)*85.8993459;
z=x;
F_word[3]=(char)z;
F_word[2]=(char)(z>>8);
F_word[1]=(char)(z>>16);
F_word[0]=(char)(z>>24);
}
//------------------------------------
int main(void)
{
uchar smalkey=0,flag=0;//位置
uchar i,j,k1=No_key,k2=No_key;
uchar dot=0xff;//小数点cursor
uchar intc=0;//整数位,有效数位
del_ms(100);
LCD_init();
LCD_write_str(0,0,"InputF= ");//显示第一行
del_ms(100);
disp(); //第二行显示默认值800Hz
AD9835_calc();
AD9835_init(); //输出800Hz正弦波
while(1)
{
del_ms(200);
k2=Key_scan();
if (k2!=No_key)
{key=k2;k2=No_key;bee();
key=Key_table(key);
switch(key)
{case 1:
{Key_num(1);}break;
case 2:
{Key_num(2);}break;
case 3:
{Key_num(3);}break;
case 4:
{Key_num(4);}break;
case 5:
{Key_num(5);}break;
case 6:
{Key_num(6);}break;
case 7:
{Key_num(7);}break;
case 8:
{Key_num(8);}break;
case 9:
{Key_num(9);}break;
case 0:
{Key_num(0);}break;
case MHz:
{
if(dot<7)
{
for(i=0;i<=7;i++)
{freq[i]=9;}
Long_bee();
}
else if(dot==0xff)
{
for(i=0;i<=7;i++)
{freq[i]=0;}
if(step<7)
{
for(i=0;i<=7;i++)
{freq[i]=9;}
Long_bee();
}
else
{
freq[7]=buf[8];
}
}
else
{
for(i=0;i<=7;i++)
{freq[i]=0;}
intc=8-dot;
act=7+intc; //整数位
i=6+intc;j=8; //起始位
for(;act>0;act--)
{freq[i]=buf[j];i--;j--;}
}
disp();
LCD_write_str(0,0,"InputF= ");
AD9835_calc();
AD9835_init();
dot=0xff;
act=0;
step=8;
cur=7;
for(i=0;i<=8;i++)
{buf[i]=0;}
key=No_key;
}break;
case KHz:
{
if(dot<4)
{for(i=0;i<=7;i++)
{freq[i]=9;}
Long_bee();}
else if(dot==0xff)
{
for(i=0;i<=7;i++)
{freq[i]=0;}
if(step<4)
{
for(i=0;i<=7;i++)
{freq[i]=9;}
Long_bee();}
else
{
for(i=0;i<=7;i++)
{freq[i]=0;}
act=8-step;
i=act+3;j=8;
for(;act>0;act--)
{freq[i]=buf[j];i--;j--;}
}
}
else
{
for(i=0;i<=7;i++)
{freq[i]=0;}
intc=8-dot;
act=4+intc;
i=3+intc;j=8;
for(;act>0;act--)
{freq[i]=buf[j];i--;j--;}
}
disp();
LCD_write_str(0,0,"InputF= ");
AD9835_calc();
AD9835_init();
dot=0xff;
act=0;
step=8;
cur=7;
for(i=0;i<=8;i++)
{buf[i]=0;}
key=No_key;
}break;
case Hzz:
{
if(dot<1)
{ for(i=0;i<=7;i++)
{freq[i]=9;}
Long_bee();}
else if(dot==0xff)//no dot
{
for(i=0;i<=7;i++)
{freq[i]=0;}
if(step<1)
{
for(i=0;i<=7;i++)
{freq[i]=9;}
Long_bee();}
else
{
for(i=0;i<=7;i++)
{freq[i]=0;}
act=8-step;
i=act;j=8;
for(;act>0;act--)
{freq[i]=buf[j];i--;j--;}
}
}
else
{
for(i=0;i<=7;i++)
{freq[i]=0;}
intc=8-dot;
act=1+intc;
i=intc;j=8;
for(;act>0;act--)
{freq[i]=buf[j];i--;j--;}
}
for(i=0;i<=7;i++)
{
if(freq[i]>0)
{flag=1;}}//Not all=0;
if(flag==0)
{Long_bee();
freq[0]=1;}//all=0
else {flag=0;}
disp();
LCD_write_str(0,0,"InputF= ");
AD9835_calc();
AD9835_init();
dot=0xff;
act=0;
step=8;
cur=7;
for(i=0;i<=8;i++)
{buf[i]=0;}
key=No_key;
}break;
case point:
{
if(step==0)
{Long_bee();}
else
{
LCD_write_str(cur,0,".");
dot=step;
cur++;}
key=No_key;
}break;
case back://
{
if(cur==7)
{
Long_bee();
key=No_key;break;
}
if(dot==step)
{dot=0xff;}
else {step++;}
cur--;
LCD_set_xy(cur,0);
LCD_write_char(0x0d,0); //display blink on
key=No_key;
}break;
case shift://
{ key=No_key;}break;//
default:break;
}//switch
}//if
} //while
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -