📄 wave.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 + -