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

📄 wave.c

📁 基于C8051F020的单片机开发平台 设计的波形发生器程序!
💻 C
字号:
//-----------------------------------------------------------------------------
//  程序描述:
//  BTF020 针对C8051F020单片机(SOC)设计的BT F020开发评估板
//  本程序是利用020的DA0口输出正弦波、三角波、矩形波 
//  其中KEY1为正弦波KEY2为三角波,KEY3为矩形波,KEY4为频率增加
//  并在LCD上显示出来(注:J18要短接给LCD供电).
//作者:哈尔滨工程大学 信息与通信工程学院 杨蕊 王琢
//时间:2008-12-16
//版本:V1.0
//注:早上没事,做个思维训练,利用了开发板内带的各种例程简单的拼凑除了这个程序涉及到的D/A程序、key程序、LCD程序,
//    调试已通过。但没有优化,只为给初学者做练习!
//-----------------------------------------------------------------------------

#include <c8051f020.h>                    // SFR declarations
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------
sfr16 RCAP4    = 0xe4;              // Timer4 capture/reload
sfr16 T4       = 0xf4;              // Timer4
sfr16 DAC0     = 0xd2;              // DAC0 data

sbit	key1=P2^0;
sbit	key2=P2^1;
sbit	key3=P2^2;
sbit	key4=P2^3;

#define CEON		P4|=0x1;		// 片选允许
#define CEOFF		P4&=~0x1;		// 片选禁止
#define BANK1		P4|=0x2;		// 选择BANK1:64-128K
#define BANK0		P4&=~0x2;		// 选择BANK0:0-64K

#define SYSCLK 4000000

void Timer4_Init (int counts);
void Timer4_ISR (void);
void SYSCLK_Init (void);

unsigned long x;
unsigned char da_count=0;
unsigned int sample_rate=1000;
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
unsigned char xdata Netdata[16]={0x77,0x77,0x77,0x2e,0x68,0x72,0x65,0x65,0x75,0x2e,
                                0x63,0x6f,0x6d,0x20};                                
                               
                                
unsigned char xdata NCDdata[17]={0x20,0x20,0x57,0x41,0x56,0x45,0x20,0x20,0x59,0x52,
                                 0x20,0x20,0x57,0x5a,0x20,0x20};

unsigned char xdata NCDsine[16]={0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x69,0x6e,0x65,0x20,0x20,
                                 0x20,0x20,0x20,0x20};
								 //sina显示
unsigned char xdata NCDtriangle[16]={0x20,0x20,0x20,0x20,0x74,0x72,0x69,0x61,0x6e,0x67,0x6c,0x65,
                                 0x20,0x20,0x20,0x20};
								 //triangle
unsigned char xdata NCDsquare[16]={0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x71,0x75,0x61,0x72,0x65,
                                 0x20,0x20,0x20,0x20};
unsigned char *lcdpoint;        //square
unsigned char lcd_data_count;
char result[256]={0};

//正弦函数表 来自例程DTMF 十六进制
char xdata sine_table[256] = {   0x00, 0x03, 0x06, 0x09, 0x0c, 0x0f, 0x12, 0x15,
                                 0x18, 0x1c, 0x1f, 0x22, 0x25, 0x28, 0x2b, 0x2e,
                                 0x30, 0x33, 0x36, 0x39, 0x3c, 0x3f, 0x41, 0x44,
                                 0x47, 0x49, 0x4c, 0x4e, 0x51, 0x53, 0x55, 0x58,
                                 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64, 0x66, 0x68,
                                 0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x72, 0x73, 0x75,
                                 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7c,
                                 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
                                 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e,
                                 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x77,
                                 0x76, 0x75, 0x73, 0x72, 0x70, 0x6f, 0x6d, 0x6c,
                                 0x6a, 0x68, 0x66, 0x64, 0x62, 0x60, 0x5e, 0x5c,
                                 0x5a, 0x58, 0x55, 0x53, 0x51, 0x4e, 0x4c, 0x49,
                                 0x47, 0x44, 0x41, 0x3f, 0x3c, 0x39, 0x36, 0x33,
                                 0x30, 0x2e, 0x2b, 0x28, 0x25, 0x22, 0x1f, 0x1c,
                                 0x18, 0x15, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03,
                                 0x00, 0xfd, 0xfa, 0xf7, 0xf4, 0xf1, 0xee, 0xeb,
                                 0xe8, 0xe4, 0xe1, 0xde, 0xdb, 0xd8, 0xd5, 0xd2,
                                 0xd0, 0xcd, 0xca, 0xc7, 0xc4, 0xc1, 0xbf, 0xbc,
                                 0xb9, 0xb7, 0xb4, 0xb2, 0xaf, 0xad, 0xab, 0xa8,
                                 0xa6, 0xa4, 0xa2, 0xa0, 0x9e, 0x9c, 0x9a, 0x98,
                                 0x96, 0x94, 0x93, 0x91, 0x90, 0x8e, 0x8d, 0x8b,
                                 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x84,
                                 0x83, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81,
                                 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82,
                                 0x83, 0x84, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
                                 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94,
                                 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4,
                                 0xa6, 0xa8, 0xab, 0xad, 0xaf, 0xb2, 0xb4, 0xb7,
                                 0xb9, 0xbc, 0xbf, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
                                 0xd0, 0xd2, 0xd5, 0xd8, 0xdb, 0xde, 0xe1, 0xe4,
                                 0xe8, 0xeb, 0xee, 0xf1, 0xf4, 0xf7, 0xfa, 0xfd
                                  };
//三角函数表 十进制
char xdata tri_table[256] = {  0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
             32,34,36,38,40	,42	,44	,46	,48	,50	,52	,54	,56	,58	,60	,62	,64	,66	,
             68,70,72,74,76	,78	,80	,82	,84	,86	,88	,90	,92	,94	,96	,98	,100,102,
             104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,
             140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,
             176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,
             212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,
             248,250,252,254,252,250,248,246,244,242,240,238,236,234,232,230,228,226,
             224,222,220,218,216,214,212,210,208,206,204,202,200,198,196,194,192,190,
             188,186,184,182,180,178,176,174,172,170,168,166,164,162,160,158,156,154,
             152,150,148,146,144,142,140,138,136,134,132,130,128,126,124,122,120,118,
             116,114,112,110,108,106,104,102,100,98,96,94,92,90,88,86,84,82,80,78,76,
             74,72,70,68,66,64,62,60,58,56,54,52,50,48,46,44,42,40,38,36,34,32,30,28,
             26,24,22,20,18,16,14,12,10,8,6,4,2,0
                           };
//矩形波函数表 十进制
char xdata squ_table[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
			 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
			 255,255,255,255,255,255
                          };

void LCD_Init(void)
{
   P2 = 0X80;
   for(x=0;x<1000;x++);   
   P3 = 0x38;				/*两行显示*/
   P2 = 0X00;
   P2 = 0X80;
   for(x=0;x<1000;x++);
   P3 = 0x0e;
   P2 = 0x00;
   P2 = 0x80;
   for(x=0;x<1000;x++);
   P3=  0x06;
   P2 = 0x00;
   P2 = 0x80;
   for(x=0;x<5000;x++);
   P3 = 0x01;
   P2 = 0x00;
   P2 = 0x80; 
   for(x=0;x<5000;x++);
}

void delay(void)
{
	int a=1000;
	while(a!=0)
	{
		a--;
	}
 }
//--------------------------------------------------------------------------
//按键连接到p2.0、p2.1、p2.2、P2.3,均为开漏输出
//--------------------------------------------------------------------------
unsigned char key_in(void)
{
	P2=0xff;
	if(key1==0)
	{
		key1=1;
		delay();
		if(key1==0)
		{
			while(key1==0);
			return(0x31);
		}
	}

	if(key2==0)
	{
		key2=1;
		delay();
		if(key2==0)
		{
			while(key2==0);
			return(0x32);
		}
	}

	if(key3==0)
	{
		key3=1;
		delay();
		if(key3==0)
		{
			while(key3==0);
			return(0x33);
		}
	}

	if(key4==0)
	{
		key4=1;
		delay();
		sample_rate+=1000;//KEY4 通过改变 time 改变波形频率
		if(key4==0)
		{
			while(key4==0);
			return(0x34);
		}
	}
	return(0);
}
//-----------------------------------------------------------------------------
// Timer4_Init
//-----------------------------------------------------------------------------
//
void Timer4_Init (int counts)
{
   T4CON = 0;                      
   CKCON |= 0x40;                   
   RCAP4 = -counts;                
   T4 = RCAP4;
   EIE2 |= 0x04;                    
   T4CON |= 0x04;                   
}
//-----------------------------------------------------------------------------
// Timer4_ISR
//-----------------------------------------------------------------------------
//
void Timer4_ISR (void) interrupt 16 using 3
{
	T4CON &= ~0x80;                 
	DAC0H = result[da_count];
	da_count++;
	if(da_count==255)
	{
		da_count=0;
	}
}
void main(void) 
{	
	unsigned char data1;
	unsigned char data2;
	unsigned long x;  
	unsigned char i;
	WDTCN = 0xde;                          
	WDTCN = 0xad;
	OSCICN = 0x05;						
    EMI0TC  = 0x75;                     
   EMI0CF  =0x3b;           		  
   P74OUT  = 0x3f;					   
    XBR2  = 0x40;						    

	REF0CN = 0x03;                   		
	DAC0CN = 0x97;                   		
	Timer4_Init(SYSCLK/sample_rate); 		// 初始化T4为DAC0定时更新

	CEON;							    	//片选使能
	BANK0;							    	// 选择BANK0:0-64K
//显示欢迎界面 来自LCD程序
	LCD_Init();                             //LCD初始化
 		P2  = 0xA0;                         //准备送数据
	    for(x=0;x<5000;x++);
	    lcdpoint=&NCDdata;					//取地址
	    for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第一行字符
	    { 
		    data2=*lcdpoint;				//读出数据				
		    P3 = data2; 					//写数据到端口
			P2 = 0X20;
	        P2 = 0XA0;						//控制LCD	
	        lcdpoint++;
			for(x=0;x<5000;x++);
		}
		P2 = 0X80;
	   	P3 = 0xc0;
   		P2 = 0x00;		
   		P2 = 0x80; 		
   		for(x=0;x<5000;x++);
	    lcdpoint=&Netdata;
	    for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第二行字符
	    { 
		    data2=*lcdpoint;
		    P3 = data2; 

		    P2 = 0xA0; 						
            for (x=0;x<1;x++);
			P2 = 0x20;	

	        lcdpoint++;
			for(x=0;x<5000;x++);
		}
	EA = 1;                          		// 开中断
	while(1)
	{
		data1=key_in();						//读按键
		//Timer4_Init(SYSCLK/sample_rate); 	// 初始化T4为DAC0定时更新
		if(data1!=0)						//有按键按下,显示对应的按键
		{
//为了简单再用了循环嵌套 
			if (data1==0x34)
			{
				Timer4_Init(SYSCLK/sample_rate);
			}
//输出正弦波 同时液晶显示名称
		     	if (data1==0x31)
			      {
				    for(i=0;i<255;i++)
				    {
					  result[i]=0x80^sine_table[i];
			        	}

					LCD_Init();                         //LCD初始化
 					P2  = 0xA0;                         //准备送数据
	   			 	for(x=0;x<5000;x++);
	   			 	lcdpoint=&NCDsine;					//取地址
	    			for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第一行字符
	    			{ 
		    		data2=*lcdpoint;				//读出数据				
		    		P3 = data2; 					//写数据到端口
					P2 = 0X20;
	        		P2 = 0XA0;						//控制LCD	
	        		lcdpoint++;
					for(x=0;x<5000;x++);
					}
					P2 = 0X80;
	   				P3 = 0xc0;
   					P2 = 0x00;		
   					P2 = 0x80; 		
   					for(x=0;x<1000;x++);

	               lcdpoint=&NCDdata;
	               for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第二行字符
	               { 
		           data2=*lcdpoint;
		           P3 = data2; 

		           P2 = 0xA0; 						//修改后的LCD程序
                   for (x=0;x<1;x++);
			       P2 = 0x20;	

	        lcdpoint++;
			for(x=0;x<5000;x++);
		}

			}
//输出 三角波 并显示名称
			if (data1==0x32)
			{
				for(i=0;i<255;i++)
				{
					result[i]=tri_table[i];
				}
					LCD_Init();                     //LCD初始化
 					P2  = 0xA0;                         //准备送数据
	   			 for(x=0;x<5000;x++);
	   			 lcdpoint=&NCDtriangle;					//取地址
	    		for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第一行字符
	    		{ 
		    data2=*lcdpoint;				//读出数据				
		    P3 = data2; 					//写数据到端口
			P2 = 0X20;
	        P2 = 0XA0;						//控制LCD	
	        lcdpoint++;
			for(x=0;x<5000;x++);

		}
		P2 = 0X80;
	   	P3 = 0xc0;
   		P2 = 0x00;		
   		P2 = 0x80; 		
   		for(x=0;x<1000;x++);
		   		for(x=0;x<5000;x++);
	    lcdpoint=&NCDdata;
	    for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第二行字符
	    { 
		    data2=*lcdpoint;
		    P3 = data2; 

		    P2 = 0xA0; 						//修改后的LCD程序
            for (x=0;x<1;x++);
			P2 = 0x20;	

	        lcdpoint++;
			for(x=0;x<5000;x++);
		}
			}
			
//输出方波 并显示名称
			if (data1==0x33)
			{
				for(i=0;i<255;i++)
				{
					result[i]=squ_table[i];
				}
					LCD_Init();                     //LCD初始化
 					P2  = 0xA0;                         //准备送数据
	   			 for(x=0;x<5000;x++);
	   			 lcdpoint=&NCDsquare;					//取地址
	    		for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第一行字符
	    		{ 
		    data2=*lcdpoint;				//读出数据				
		    P3 = data2; 					//写数据到端口
			P2 = 0X20;
	        P2 = 0XA0;						//控制LCD	
	        lcdpoint++;
			for(x=0;x<5000;x++);
		}
		P2 = 0X80;
	   	P3 = 0xc0;
   		P2 = 0x00;		
   		P2 = 0x80; 		
   		for(x=0;x<1000;x++);
		   		for(x=0;x<5000;x++);
	    lcdpoint=&NCDdata;
	    for(lcd_data_count=14;lcd_data_count>0;lcd_data_count--)//显示第二行字符
	    { 
		    data2=*lcdpoint;
		    P3 = data2; 

		    P2 = 0xA0; 						//修改后的LCD程序
            for (x=0;x<1;x++);
			P2 = 0x20;	

	        lcdpoint++;
			for(x=0;x<5000;x++);
		}
			}

		}
	}

}



⌨️ 快捷键说明

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