⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zjh.c

📁 实现信号算法的研究
💻 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 + -