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

📄 波形发生器.c

📁 这是本人参加电子设计竞赛过程中编写的几个单片机程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*********************************************************/
/**                波形发生器                 **
*********************************************************/

#include <absacc.h>
#include <reg51.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define LED1 XBYTE [0xA000]   //数码管地址
#define LED2 XBYTE [0xA001]
#define LED3 XBYTE [0xA002]
#define LED4 XBYTE [0xA003]
#define LED5 XBYTE [0xA004]
#define LED6 XBYTE [0xA005]
#define LED7 XBYTE [0xA006]
#define LED8 XBYTE [0xA007]

#define KEY XBYTE [0xA100]  //键盘地址

#define lcdDl XBYTE [0xA201] //左半边液晶数据地址
#define lcdDr XBYTE [0xA301] //右半边液晶数据地址
#define lcdlCommand XBYTE [0xA200]//左半边液晶命令地址
#define lcdrCommand XBYTE [0xA300]//右半边液晶命令地址

#define FPGADATA XBYTE[0xA400]

/*液晶显示使用的常量*/
#define strat_yaddr 0x40
#define strat_xaddr 0xb8
#define strat_dispaddr 0xc0

xdata uchar RAM[32768] _at_ 0x0000;//外部RAM地址

/*扫描键盘使用的变量 */
sbit first_row = P1^4;      //键盘第一行控制
sbit second_row = P1^3;     //键盘第二行控制
bit first_getkey = 0,control_readkey = 0;  //读键盘过程中的标志位
bit getkey = 0; //获得有效键值标志位 等于1时代表得到一个有效键值
bit keyon = 0;  //防止按键冲突标志位
uchar keynum = 0;  //获得的有效按键值寄存器 

/*读写flash使用的变量*/
sbit scl = P1^0; //24C16 scl
sbit sda = P1^1; //24c16 sdl

/*P0用来传输数据*/
sbit XC1 = P1^2;
sbit XC2 = P1^5;
sbit XC3 = P1^6;
sbit XC4 = P1^7;
sbit RXD_FPGA = P3^0;
sbit TXD_FPGA = P3^1;

/*选择功能所用变量*/
double frequency_variable=0.1;
double range_variable=0.1;
uchar key_f=0;
uchar key_fhang=1;
uchar key_shang=2;
uchar key_rhang=2;

/*数码管显示使用的变量和常量*/
uchar lednum = 0;  //数码管显示位控制寄存器
uchar led[8] = {0,0,0,0,0,0,0,0};  //数码管显示内容寄存器
uchar code segtab[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x8c,0xff}; //七段码段码表
                      // "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "P" ,"black" 

void leddisp(void); //数码管显示函数
void readkey(void); //读键盘函数

/**********************************
  液晶驱动函数
***********************************/
void lcdlon_off(uchar D);
void setlstartx(uchar D);
void setlstarty(uchar D);
void setlstartline(uchar D);
void lcdron_off(uchar D);
void setrstartx(uchar D);
void setrstarty(uchar D);
void setrstartline(uchar D);
void lcdlwrite(uchar D);
void lcdrwrite(uchar D);
void initial_lcd(void);
void clear_lcd(void);

/**********************************
	24c16驱动函数
**********************************/
void  delay(uchar time_nop);
void  Start_I2c(void);
void  Stop_I2c(void);
uchar SendByte(uchar c);
uchar RcvByte(void);
void  Ack_I2c(uchar a);
uchar ISendByte(uchar sla,uchar c);
uchar ISendStr(uchar sla,uchar suba,uchar *s,uchar no);
uchar IRcvByte(uchar sla,uchar *c);
uchar IRcvStr(uchar sla,uchar suba,uchar *s,uchar no);
void  write_24lc16b(uint adrress, uchar *wdata, uchar number);
void  read_24lc16b(uint adrress, uchar *rdata, uchar number);

//写入液晶函数
void write_chinese(uchar  word_datas1[32], uchar hang,uchar  lie );//写单个字符
void write_string(uchar  word_data[16],uchar  hang,uchar lie );  //写单个字符

void show_data(double  print,uchar hang,uchar lie,uchar wei);//第i行第j列开始显示,显示wei个数,格式为科学计数法或小数
void show_bfs(double print,uchar hang,uchar lie,uchar wei);//第i行第j列开始显示,显示wei个数,格式为百分数(0~1)
void write_data(uint datas,uchar i,uchar j);

//功能函数
void wave_choose(void);//测试波形列表并选择功能
void frequency_input(void);//频率输入
void step_choosef(void);//步进选择
void step_chooser(void);//步进选择
void range_input(void);//幅度输入
void  eeprom_24c16(void);//写24c16函数
void reeprom_24c16(void);//读24c16函数
void next_hang(void);//下翻
void last_hang(void);//上翻
void ensure_opt(void);//确定键
void senddata(uchar datas);//发送数据
uchar receivedata(void);//接受数据

//在液晶上所需显示的内容
uchar code shuzi0[16];
uchar code shuzi1[16];
uchar code shuzi2[16];
uchar code shuzi3[16];
uchar code shuzi4[16];
uchar code shuzi5[16];
uchar code shuzi6[16];
uchar code shuzi7[16];
uchar code shuzi8[16];
uchar code shuzi9[16];
uchar code dian[16];
uchar code exp[16];
uchar code space[16];
uchar code fuhao[16];
uchar code baifenhao[16];
uchar code string_k[16];
uchar code string_H[16];
uchar code string_z[16];
uchar code string_V[16];
uchar code arrow[32];
uchar code functionlists[11][32];
uchar code shujuchuanshu[4][32];
uchar code pinlvzhi[3][32];
uchar code bujinzhi[4][32];
uchar code fuduzhi[3][32];

void intT0() interrupt 1 //T0 定时中断处理函数
{
	TH0 = -2720/256;  //定时器中断时间间隔 4ms
 	TL0 = -2720%256;

 	leddisp();  //每次定时中断显示更新一次

 	if(control_readkey == 1)  //每两次定时中断扫描一次键盘
   	{
    	readkey();
   	}
 	control_readkey = !control_readkey;
}


void main(void)
{

	TMOD = 0x01;    
 	TH0 = -2720/256;  //定时器中断时间间隔 4ms
 	TL0 = -2720%256;
	TCON = 0x10;
 	ET0 = 1;
    EA = 1;
    XC1 = 0;
    XC2 = 0;
    XC3 = 0;
    XC4 = 0;
    frequency_variable=0.1;
    range_variable=0.1;
    key_f=0;
    key_fhang=1;
    key_shang=2;
    key_rhang=2;
	initial_lcd();//初始化液晶

	while(1)
	{
 		if(getkey == 1)  //判断是否获得有效按键
  	    {
     		getkey = 0;
  			switch(keynum) //判断键值,对不同键值采取相应的用户定义处理方式
       		{
				case 0x01:
 		 	        wave_choose();
					break;
                
				case 0x04:  		
					EA = 0;
					eeprom_24c16();
					EA = 1;
			 		break;
				case 0x08: 		 
					ensure_opt();
					break;
                case 0x09: 		 
					next_hang();
					break;
                case 0x0a: 		 
					last_hang();
					break;
				case 0x0b: 		 
					step_choosef();
					break;
                case 0x0c: 		 
					step_chooser();
					break;
	   			case 0x0e:
				    EA = 0;
					reeprom_24c16();
					EA = 1;
                    break;
				case 0x10:
					clear_lcd();    //当按下第二行倒数第一列按键时,液晶屏被全部清空
					break;
				default:
					led[0] = keynum;  //当按下其他按键时,全部数码管显示按键值
     				led[1] = keynum;  
    	    		led[2] = keynum;
     				led[3] = keynum;
     				led[4] = keynum;
     				led[5] = keynum;
     				led[6] = keynum;
     				led[7] = keynum;
					break;
    		}
     	}
 	}
}


/****************************************************************************************                                                   *
功能: 选择波形
****************************************************************************************/
void wave_choose(void)//测试功能列表并选择功能
{
     uchar i,j;
	 double qq=0.0000016;
	 key_f=1;
	 clear_lcd();
	 for(i=0;i<2;i++)
         write_chinese(functionlists[i],1,2*i+2);
     for(i=0;i<3;i++)
         for(j=0;j<3;j++)
             write_chinese(functionlists[3*i+j+2],i+2,2*j+2);
     write_chinese(arrow,key_fhang,1);
     show_data(qq,1,9,3);
}
/****************************************************************************************                                                   *
功能: 频率输入
****************************************************************************************/
void frequency_input(void)
{
     uchar i;
     key_f=2;
	 clear_lcd();
	 for(i=0;i<3;i++)
         write_chinese(pinlvzhi[i],1,2*i+1);
     show_data(frequency_variable,2,3,4);
	 write_string(string_k,2,8);
	 write_string(string_H,2,9);
	 write_string(string_z,2,10);
}

/****************************************************************************************                                                   *
功能: 幅度输入
****************************************************************************************/
void range_input(void)
{
     uchar i;
     key_f=2;
	 clear_lcd();
	 for(i=0;i<3;i++)
         write_chinese(fuduzhi[i],1,2*i+1);
     show_data(range_variable,2,3,2);
     write_string(string_V,2,6);
}

/****************************************************************************************                                                   *
功能: 频率步进选择
****************************************************************************************/
void step_choosef(void)
{
     uchar i;
     key_f=3;
	 clear_lcd();
     for(i=0;i<4;i++)
         write_chinese(bujinzhi[i],1,2*i+1);
	 show_data(100,2,3,3);
	 show_data(1,3,3,1);
	 write_string(string_k,3,4);
	 show_data(10,4,3,2);
	 write_string(string_k,4,5);
	 write_chinese(arrow,key_shang,1);
}

/****************************************************************************************                                                   *
功能: 幅度步进选择
****************************************************************************************/
void step_chooser(void)
{
     uchar i;
     key_f=5;
	 clear_lcd();
     for(i=0;i<4;i++)
         write_chinese(bujinzhi[i],1,2*i+1);
	 show_data(0.1,2,3,3);
	 write_string(string_V,3,4);
	 show_data(1,3,3,1);
	 write_string(string_V,4,5);
	 write_chinese(arrow,key_rhang,1);
}

/****************************************************************************************                                                   *
功能: 下翻
****************************************************************************************/
void next_hang(void)
{
      if(key_f==1)
      {
           if(key_fhang==4)
               key_fhang=1;
           else 
               key_fhang++;
           wave_choose();
      }  
      if(key_f==2)
	  {
	       if(key_shang==2)
		   {
		        if(frequency_variable<300)
	                 frequency_variable=frequency_variable+0.1;
		   }
		   else if(key_shang==3)
           {
			    if(frequency_variable<300)  
		             frequency_variable=frequency_variable+1.0;
			}
		   else
		   {
		        if(frequency_variable<300)
		             frequency_variable=frequency_variable+10.0;
			}
           frequency_input();
	  }
	  if(key_f==3)
      {
           if(key_shang==4)
               key_shang=2;
           else 
               key_shang++;
           step_choosef();
      } 
	  if(key_f==4)
	  {
	       if(key_rhang==2)
		   {
		        if(range_variable<5)
	                 range_variable=frequency_variable+0.1;
		   }
		   else 
           {
			    if(range_variable<5)  
		             range_variable=frequency_variable+1.0;
			}
           range_input();
	  }
 	  if(key_f==5)
      {
           if(key_shang==3)
               key_rhang=2;
           else 
               key_rhang++;
           step_chooser();
      }  
}

/****************************************************************************************                                                   *
功能: 上翻
****************************************************************************************/
void last_hang(void)
{
      if(key_f==1)
      {
           if(key_fhang==1)
               key_fhang=4;
           else 
               key_fhang--;
           wave_choose();
      }
      if(key_f==2)
	  {
	       if(key_shang==2)
		   {
		        if(frequency_variable>=0.2)
	                 frequency_variable=frequency_variable-0.1;
		   }
		   else if(key_shang==3)
           {
			    if(frequency_variable>=1.1)  
		             frequency_variable=frequency_variable-1.0;
			}
		   else
		   {
		        if(frequency_variable>=10.1)
		             frequency_variable=frequency_variable-10.0;
			}
           frequency_input();
	  }
	  if(key_f==3)
      {
           if(key_shang==2)
               key_shang=4;
           else 
               key_shang--;
           step_choosef();
      }  
	  if(key_f==4)
	  {
	       if(key_rhang==2)
		   {
		        if(range_variable>=0.2)
	                 range_variable=frequency_variable-0.1;
		   }
		   else 
           {
			    if(range_variable>=1.1)  
		              range_variable=frequency_variable-1.0;
			}
		   range_input();
	  }
	  if(key_f==5)
      {
           if(key_shang==2)
               key_shang=3;
           else 
               key_shang--;
           step_chooser();
      }  
}


/****************************************************************************************                                                   *
功能: 确定
****************************************************************************************/
void ensure_opt(void)
{
      if(key_f==1)
	  {
 		   frequency_input();
	  }
	  if(key_f==2)
      {
           range_input();
	  }
	  if(key_f==3)
      {
	       frequency_input();
	  }
	  if(key_f==4)
      {
	       if(key_fhang==4)
		   {
		        
		   }
	  }
	  if(key_f==5)
      {
	       range_input();
	  }
}
//发送数据
void senddata(uchar datas)
{
     uchar i;
     for(i=0;i<2;i++)
         write_chinese(shujuchuanshu[i],2,4*i+2);
     EA=0;
     P0=datas;
     XC1=1;
	 delay(6);
     XC1=0;
     EA=1;
}
//接受数据
uchar receivedata(void)
{
     uchar fpgabuf=0;
     uchar i;
     for(i=0;i<2;i++)
         write_chinese(shujuchuanshu[i+2],2,4*i+2);
     fpgabuf=FPGADATA;
     for(i=0;i<4;i++)
	{
	    led[2*i] =fpgabuf%10;
	    led[2*i+1] =fpgabuf/10;
	}     
     return fpgabuf;
}
/****************************************************************************************                                                   *
功能: 掉电存储,EEPROM
****************************************************************************************/

void eeprom_24c16(void)
{
	uchar wdata[2] = {0x03,0x04};
    write_24lc16b(0, wdata , 1);
	write_24lc16b(1, wdata + 1, 1);    
}
void reeprom_24c16(void)
{
    uchar i;
    uchar rdata[2] = {0x00,0x00};
    read_24lc16b(0, rdata , 1);
	read_24lc16b(1, rdata + 1, 1);
    for(i=0;i<4;i++)
	{
	    led[2*i] =rdata[0];
	    led[2*i+1] =rdata[1];
	}
}
/***************************************************
			键盘扫描函数
原型:   void readkey(void);
功能:  当获得有效按键时,令getkey=1,keynum为按键值

****************************************************/
void readkey(void)
{
	uchar M_key = 0;  

 	first_row = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -