📄 zjh.c
字号:
/*
1 、可通过按键实现频率输出步进加减;步进频率范围0~10MHz;
2、步进值有三种选择:10Hz步进、100Hz、1000Hz。
3、采用1602液晶显示屏,可以实时显示输出频率值,显示当前步进值,显示频率的单位都为Hz。
*/
//基本功能全部实现;2009042407
#include <reg52.h> //调用头文件(单片机内部的寄存器定义)
#define uchar unsigned char
#define uint unsigned int
/******本段为硬件I/O口定义********/
sbit LCD_E = P1^1;
sbit LCD_RW = P1^2;
sbit LCD_RS = P1^3;
sbit reset = P1^4; //ad9850 reset
sbit w_clk = P1^7; // ad9850 w_clk;
sbit fqud = P1^6; //ad9850 fqud;
#define LCD_DATA P2 //LCD DATA
#define LCD_BUSY 0x80 // 用于检测LCD的BUSY标识(本程序中用的延时,未检测)
//LCD显示内容,定义到代码段
unsigned char code LcdBuf1[]= {"FRQ: Hz"};
unsigned char code LcdBuf2[]= {"Step:"};
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;
sbit Light = P1^0; //程序状态指示灯,它与单片机对9850控制无关,只是调程序的时候使用!
sbit P3_4 = P3^4;
sbit P3_6 = P3^6;
sbit P3_7 = P3^7;
sbit P3_3 = P3^3;
sbit P3_5 = P3^5; //按键定义
uchar j = 0,dat = 0;
uchar keyzhi = 0x00;
//函数声明
void lcd_init(void);
void display_string(unsigned char x,unsigned char y,unsigned char *s);
//void disp_selec(unsigned char bit_selec,unsigned char seg);
/**************************************************
** 函数名称: delay
** 入口参数:h(unsigned int型)
** 出口参数:无
** 功能描述: 短暂延时,使用11.0592晶体,约0.01MS
****************************************************/
void delay(long unsigned int h)
{
while(h--); //0.001ms
}
/**************************************************
** 函数名称: WriteDataLcd
** 入口参数:wdata(unsigned char型)
** 出口参数:无
** 功能描述: 写数据到LCD
****************************************************/
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;
}
/**************************************************
** 函数名称: WriteCommandLcd
** 入口参数:wdata(unsigned char型)
** 出口参数:无
** 功能描述: 写命令到LCD
****************************************************/
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)
{
delay(15000);
WriteCommandLcd(0x38);
delay(5000);
WriteCommandLcd(0x38); //显示模式设置
delay(5000);
WriteCommandLcd(0x38); //显示模式设置
delay(100);
WriteCommandLcd(0x38);
WriteCommandLcd(0x08);
WriteCommandLcd(0x01); //显示清屏
WriteCommandLcd(0x06); //显示光标移动设置
WriteCommandLcd(0x0c); //显示开及光标设置
}
/**************************************************
** 函数名称: display_xy
** 入口参数:x(unsigned char型),y(unsigned char型)
** 出口参数:无
** 功能描述: 设置光标位置, x是列号,y是行号
****************************************************/
void display_xy(unsigned char x,unsigned char y)
{
if(y==0x01)
{
x = x + 0x40 + 0x80;
}
else
{
x = x+0x80;
}
WriteCommandLcd(x);
}
/********************************************************************
** 函数名称: display_char
** 入口参数:x(unsigned char型),y(unsigned char型),dat(unsigned char型)
** 出口参数:无
** 功能描述: 在具体位置显示单个字符,x是列号,y是行号
*********************************************************************/
void display_char(unsigned char x,unsigned char y,unsigned char dat)
{
display_xy(x,y);
WriteDataLcd(dat);
}
/*********************************************************************
** 函数名称: display_string
** 入口参数:x(unsigned char型),y(unsigned char型),s(指针型)
** 出口参数:无
** 功能描述: 在具体位置显示字符串,以/0结束,x是列号,y是行号
**********************************************************************/
void display_string(unsigned char x,unsigned char y,unsigned char *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;
}
display_data()
{
Qu_Chu_Shu_Ma_Ge_Wei(); //显示各位数之
display_string(1,0,LcdBuf1); //显示第一行,从第2个位置开始
WriteCommandLcd(0x85);//显示数值的话,用其真实的地址,如0x83等,
WriteDataLcd(0x30+h); //如果要显示字符的话,暂时用x、y坐标的方式
WriteDataLcd(0x30+g);
WriteDataLcd(0x30+f);
WriteDataLcd(0x30+e);
WriteDataLcd(0x30+d);
WriteDataLcd(0x30+c);
WriteDataLcd(0x30+b);
WriteDataLcd(0x30+a);
}
scan_KEY(void) //按键扫描
{
uchar key = 0;
key = P3; //Eliminate the most 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_5 = 0x01;
P3_4 = 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);
}
/************AD9850**************/
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 * 42;
//Con_Word_2 = Frequency_Out * 0.9423727466;//100M
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; //根据时序图设置
fqud = 0x00;
data_word = 0x00; //相位、掉电等相关控制字
P2 = 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,频率控制字中的最高字节;
P2 = data_word;
w_clk=1;
delay(50);
w_clk=0;
ConTrol_Word = ConTrol_Word_Temporary;
ConTrol_Word = ConTrol_Word >> 16;
data_word = ConTrol_Word % 256;//取出W2,频率控制字中的次高字节;
P2 = 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,频率控制字中的第三字节;
P2 = data_word;
w_clk=1;
delay(50);
w_clk=0;
ConTrol_Word = ConTrol_Word_Temporary;
data_word = ConTrol_Word % 256;//取出W4,频率控制字中的最后一个字节;
P2 = data_word;
w_clk=1;
delay(50);
w_clk=0; //根据时序图
fqud=1; //根据时序图
}
/************主程序**************/
main()
{
unsigned char i = 0x00;
uint Step_Bian_Liang = 0x00;//步进变量;
uint Step_Data = 10;//默认为10Hz;
reset = 1; //复位AD9850;
delay(1000);
reset = 0; //使AD9850进入正常的工作状态;
lcd_init();
Frequency_Out = 0;//开机默认的频率输出值;
Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;
Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;
display_data();
display_string(0,1,LcdBuf2); //显示第二行,从第0个位置开始
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)
{
keychuli();
if((dat == 0x01)|(dat == 0x02)|(dat == 0x03))
{
dat = 0x00;delay(5000);
Frequency_Out = Frequency_Out + Step_Data;
if(Frequency_Out > 10000000)
{
Frequency_Out =10000000;
}
Light =~Light;
display_data();
reset = 1; //复位AD9850;
delay(100);
reset = 0; //使AD9850进入正常的工作状态;
Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;
Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;
}
if((dat == 0x04)|(dat == 0x05))
{
dat = 0x00;delay(5000);
//Frequency_Out = Frequency_Out - Step_Data;
if(Frequency_Out >= Step_Data)
{
Frequency_Out = Frequency_Out - Step_Data;
}
Light =~Light;
display_data();
reset = 1; //复位AD9850;
delay(1000);
reset = 0; //使AD9850进入正常的工作状态;
Calculate_Control_Word(Frequency_Out);//根据设置的频率换算成将要送入AD9850中的整数值;
Send_Control_Word(ConTrol_Word); //向AD9850送出频率控制字;
}
if(dat == 0x06)
{
dat = 0x00;delay(5000);Light =~Light;
Step_Bian_Liang++;
Step_Bian_Liang = Step_Bian_Liang%3;
if(Step_Bian_Liang == 0x00)
{
Step_Data = 10;
}
if(Step_Bian_Liang == 0x01)
{
Step_Data = 100;
}
if(Step_Bian_Liang == 0x02)
{
Step_Data = 1000;
}
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");
}
//display_string(1,0,"1");
// while(1);
//display_string(0,1,LcdBuf2); //显示第二行,从第0个位置开始
//while(1); //单片机待机
//WriteCommandLcd(0x80);
//WriteDataLcd(0x30);
//WriteCommandLcd(0xc0);
//WriteDataLcd(0x30);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -