基于单片机编程的波形发生以及仿真图
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
display(); //显示程序
}
}
void Timer0() interrupt 1
{
TH0=th; //重新赋初值
TL0=tl;
if (keycount==0) //输出正弦波
{
P1=sin_tab[qudian]; //把正弦波数据赋给P1口然后数据由P1口传到da中
qudian+=1; //100点,每隔1点输出一个数据
{
0x00,0x0f,0x1f,0x2f,0x3f,0x4f,0x5f,0x6f,0x7f,0x8f,0x9f,0xaf,0xbf,0xcf,0xdf,0xef,
0xff,0xef,0xdf,0xcf,0xbf,0xaf,0x9f,0x8f,0x7f,0x6f,0x5f,0x4f,0x3f,0x2f,0x1f,0x0f
if(qudian>=100)
{
qudian=0;
}
}
else if(keycount==1) //输出三角波
{
P1=sanjiao_tab[qudian]; //把三角波数据赋给P1口然后数据由P1口传到da中
qudian++;
if(qudian>=32)
{
qudian=0;
}
}
else if(keycount==2) //输出锯齿波
};
//--------------------------------------------------------------------------------
//锯齿波信号数据表
uchar code jc_tab[33]=
{
0x00,0x08,0x0f,0x18,0x1f,0x28,0x2f,0x38,0x3f,0x48,0x4f,0x58,0x5f,0x68,0x6f,0x78,
case 3: //方波频率加1
plcount++;
if(plcount>1000)plcount=0;
break;
}
th=(65536-50000/plcount)/256; //重新计算初值
tl=(65536-50000/plcount)%256;
}
}
//**********************************频率减1处理***********
break;
case 1: //显示和指示三角波的频率
fenli(plcount);
led0=1;
led1=0;
break;
case 2: //显示和指示锯齿波的频率
fenli(plcount);
led0=1;
led1=1;
led2=0;
break;
case 3: //显示和指示方波的频率
fenli(plcount);
}
}
//*********************************频率加1处理************************
if(S2==0)
{
delayms(10);
if(S2==0)
{
flag=0;
switch(keycount)
{
case 0: //正弦波频率加1
plcount++;
break;
case 2: //锯齿波频率减1
plcount--;
if(plcount<0) plcount=999;
break;
caseFra Baidu bibliotek3: //方波频率减1
plcount--;
if(plcount<0) plcount=999;
break;
}
th=(65536-50000/plcount)/256; //重新计算初值
TL0=tl=(65536-50000/plcount)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //定时器0开始计数
}
//主函数
void main()
{
Timerinit(); //定时器初始化
dawr=0;//选通da
cs=0;
while(1)
{
keyscan(); //扫描按键
if(S1==0)
{
delayms(10);//去抖
if(S1==0)
{
flag=0;
switch(keycount)
{
case 0: //正弦波频率减1
plcount--;
if(plcount<0) plcount=999;
break;
case 1: //三角波频率减1
plcount--;
if(plcount<0) plcount=999;
{
P1=jc_tab[qudian];//把锯齿波数据赋给P1口然后数据由P1口传到da中
qudian++;
if(qudian>=32)
{
qudian=0;
}
}
else if(keycount==3) //输出方波
{
qudian++;
if(qudian>=32)
{
qudian=0;
}
else if(qudian<16) P1=0xff; //高电平和低电平各取一半,即十六个点然后形成方波
led0=1;
led1=1;
led2=1;
led3=0;
break;
}
P0 = table[xianshi[0]];
wei0=0;
delayms(1);
wei0=1;
P0 = table[xianshi[1]];
wei1=0;
delayms(1);
wei1=1;
P0 = table[xianshi[2]];
xianshi[1]=PL%100/10; //十位
xianshi[2]=PL%10; //个位
}
//显示函数
void display()
{
switch(keycount)
{
case 0: //显示和指示正弦波的频率
fenli(plcount);
led3=1;//循环显示时关掉第四个led
led0=0;
0x2,0x1,0x0,0x0,0x0,0x0,0x2,0x3,0x6,0x8,0xc,0xf,0x13,0x18,0x1d,0x22,0x28,0x2e,0x34,0x3b,0x42,0x49,
0x50,0x58,0x5f,0x67,0x6f,0x77} ;
//三角波信号数据表
uchar code sanjiao_tab[32]=
0x7f,0x88,0x8f,0x98,0x9f,0xa8,0xaf,0xb8,0xbf,0xc8,0xcf,0xd8,0xdf,0xe8,0xef,0xf8,
0xff};
sbit led0=P3^0;//正弦波led波形指示
sbit led1=P3^1;//三角波指示
sbit led2=P3^2;//锯齿波指示
if(plcount>1000) plcount=0;
break;
case 1: //三角波频率加1
plcount++;
if(plcount>1000) plcount=0;
break;
case 2: //锯齿波频率加1
plcount++;
if(plcount>1000) plcount=0;
break;
else P1=0x00;
}
}
下面是总的设计电路图
图(1-1)仿真电路
1、正弦波仿真效果图
2、三角波仿真效果图
图(1-2)三角波发生,频率显示及led指示
3、锯齿波仿真效果图
图(1-3)锯齿波发生,频率显示及led指示
4、正弦波仿真效果图
图(1-4)锯齿波发生,频率显示及led指示
uint plcount=10; //频率计数
uint qudian; //波形取点
//毫秒延时程序
void delayms(int ms)
{
uchar i;
while(ms--)
{
for(i=250;i>0;i--);
}
}
//***********************************键盘扫描*******************
sbit dawr=P3^6;//da控制
sbit cs=P3^5;
uchar xianshi[3]; //保存显示数据
char flag=1; //按键标志,当flag=1时表示没有按下,当flag=0时表示有按键按下
int keycount=0; //按键计数
uchar th,tl; //用于对定时器赋值
void keyscan()
{
if(flag==1)
{
if(S3==0) //用S3切换波形
{
delayms(10); //延时去抖
if(S3==0) //按键计数,便于切换波形
{
flag=0;
keycount++;//按键计数
if(keycount>=4) keycount=0; //四种波形计数4次大于等于四时清零
tl=(65536-50000/plcount)%256;
}
}
}
if(S1!=0 && S2!=0 && S3!=0) flag=1; //判断按键是否弹起
}
//数据分离
void fenli(uint PL) //PL为频率计数的形参
{
//显示字母,表示波形类型
xianshi[0]=PL%1000/100; //百位
,0xf0,0xec,0xe7,0xe2,0xdd,0xd7,0xd1,0xcb,0xc4,0xbd,0xb6,0xaf,0xa7,0xa0,0x98,0x90,0x88,0x80,0x78,
0x70,0x68,0x60,0x58,0x51,0x49,0x42,0x3b,0x34,0x2e,0x28,0x22,0x1d,0x18,0x14,0xf,0xc,0x9,0x6,0x4,
sbit led3=P3^3;//方波指示
//数码管位选控制口定义
sbit wei3=P2^4;
sbit wei2=P2^3;
sbit wei1=P2^2;
sbit wei0=P2^1;
//按键口定义
sbit S1=P2^5;//控制频率的减
sbit S2=P2^6;//控制频率的加
sbit S3=P2^7;//控制切换
wei2=0;
delayms(1);
wei2=1;
P0=0x76;
wei3=0;delayms(1);
wei3=1;
}
void Timerinit()
{
TMOD=0x01; //定时器0方式1
//定时器初值计算公式:X=65536-(t/Tcy)
TH0=th=(65536-50000/plcount)/256; //定时器初值
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,//0-4
0x6d,0x7d,0x07,0x7f,0x6f, //5-9
0x77,0x7c,0x39,0x5e,0x79,0x71};//a-f
//正弦波数据表
ucharcodesin_tab[100]={0x80,0x88,0x90,0x97,0x9f,0xa7,
0xaf,0xb6,0xbd,0xc4,0xcb,0xd1,0xd7,0xdd,
0xe2,0xe7,0xec,0xf0,0xf3,0xf6,0xf9,0xfb,0xfd,0xfe,0xff,0xff,0xff,0xff,0xfd,0xfc,0xf9,0xf7,0xf3
}
}
void Timer0() interrupt 1
{
TH0=th; //重新赋初值
TL0=tl;
if (keycount==0) //输出正弦波
{
P1=sin_tab[qudian]; //把正弦波数据赋给P1口然后数据由P1口传到da中
qudian+=1; //100点,每隔1点输出一个数据
{
0x00,0x0f,0x1f,0x2f,0x3f,0x4f,0x5f,0x6f,0x7f,0x8f,0x9f,0xaf,0xbf,0xcf,0xdf,0xef,
0xff,0xef,0xdf,0xcf,0xbf,0xaf,0x9f,0x8f,0x7f,0x6f,0x5f,0x4f,0x3f,0x2f,0x1f,0x0f
if(qudian>=100)
{
qudian=0;
}
}
else if(keycount==1) //输出三角波
{
P1=sanjiao_tab[qudian]; //把三角波数据赋给P1口然后数据由P1口传到da中
qudian++;
if(qudian>=32)
{
qudian=0;
}
}
else if(keycount==2) //输出锯齿波
};
//--------------------------------------------------------------------------------
//锯齿波信号数据表
uchar code jc_tab[33]=
{
0x00,0x08,0x0f,0x18,0x1f,0x28,0x2f,0x38,0x3f,0x48,0x4f,0x58,0x5f,0x68,0x6f,0x78,
case 3: //方波频率加1
plcount++;
if(plcount>1000)plcount=0;
break;
}
th=(65536-50000/plcount)/256; //重新计算初值
tl=(65536-50000/plcount)%256;
}
}
//**********************************频率减1处理***********
break;
case 1: //显示和指示三角波的频率
fenli(plcount);
led0=1;
led1=0;
break;
case 2: //显示和指示锯齿波的频率
fenli(plcount);
led0=1;
led1=1;
led2=0;
break;
case 3: //显示和指示方波的频率
fenli(plcount);
}
}
//*********************************频率加1处理************************
if(S2==0)
{
delayms(10);
if(S2==0)
{
flag=0;
switch(keycount)
{
case 0: //正弦波频率加1
plcount++;
break;
case 2: //锯齿波频率减1
plcount--;
if(plcount<0) plcount=999;
break;
caseFra Baidu bibliotek3: //方波频率减1
plcount--;
if(plcount<0) plcount=999;
break;
}
th=(65536-50000/plcount)/256; //重新计算初值
TL0=tl=(65536-50000/plcount)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //定时器0开始计数
}
//主函数
void main()
{
Timerinit(); //定时器初始化
dawr=0;//选通da
cs=0;
while(1)
{
keyscan(); //扫描按键
if(S1==0)
{
delayms(10);//去抖
if(S1==0)
{
flag=0;
switch(keycount)
{
case 0: //正弦波频率减1
plcount--;
if(plcount<0) plcount=999;
break;
case 1: //三角波频率减1
plcount--;
if(plcount<0) plcount=999;
{
P1=jc_tab[qudian];//把锯齿波数据赋给P1口然后数据由P1口传到da中
qudian++;
if(qudian>=32)
{
qudian=0;
}
}
else if(keycount==3) //输出方波
{
qudian++;
if(qudian>=32)
{
qudian=0;
}
else if(qudian<16) P1=0xff; //高电平和低电平各取一半,即十六个点然后形成方波
led0=1;
led1=1;
led2=1;
led3=0;
break;
}
P0 = table[xianshi[0]];
wei0=0;
delayms(1);
wei0=1;
P0 = table[xianshi[1]];
wei1=0;
delayms(1);
wei1=1;
P0 = table[xianshi[2]];
xianshi[1]=PL%100/10; //十位
xianshi[2]=PL%10; //个位
}
//显示函数
void display()
{
switch(keycount)
{
case 0: //显示和指示正弦波的频率
fenli(plcount);
led3=1;//循环显示时关掉第四个led
led0=0;
0x2,0x1,0x0,0x0,0x0,0x0,0x2,0x3,0x6,0x8,0xc,0xf,0x13,0x18,0x1d,0x22,0x28,0x2e,0x34,0x3b,0x42,0x49,
0x50,0x58,0x5f,0x67,0x6f,0x77} ;
//三角波信号数据表
uchar code sanjiao_tab[32]=
0x7f,0x88,0x8f,0x98,0x9f,0xa8,0xaf,0xb8,0xbf,0xc8,0xcf,0xd8,0xdf,0xe8,0xef,0xf8,
0xff};
sbit led0=P3^0;//正弦波led波形指示
sbit led1=P3^1;//三角波指示
sbit led2=P3^2;//锯齿波指示
if(plcount>1000) plcount=0;
break;
case 1: //三角波频率加1
plcount++;
if(plcount>1000) plcount=0;
break;
case 2: //锯齿波频率加1
plcount++;
if(plcount>1000) plcount=0;
break;
else P1=0x00;
}
}
下面是总的设计电路图
图(1-1)仿真电路
1、正弦波仿真效果图
2、三角波仿真效果图
图(1-2)三角波发生,频率显示及led指示
3、锯齿波仿真效果图
图(1-3)锯齿波发生,频率显示及led指示
4、正弦波仿真效果图
图(1-4)锯齿波发生,频率显示及led指示
uint plcount=10; //频率计数
uint qudian; //波形取点
//毫秒延时程序
void delayms(int ms)
{
uchar i;
while(ms--)
{
for(i=250;i>0;i--);
}
}
//***********************************键盘扫描*******************
sbit dawr=P3^6;//da控制
sbit cs=P3^5;
uchar xianshi[3]; //保存显示数据
char flag=1; //按键标志,当flag=1时表示没有按下,当flag=0时表示有按键按下
int keycount=0; //按键计数
uchar th,tl; //用于对定时器赋值
void keyscan()
{
if(flag==1)
{
if(S3==0) //用S3切换波形
{
delayms(10); //延时去抖
if(S3==0) //按键计数,便于切换波形
{
flag=0;
keycount++;//按键计数
if(keycount>=4) keycount=0; //四种波形计数4次大于等于四时清零
tl=(65536-50000/plcount)%256;
}
}
}
if(S1!=0 && S2!=0 && S3!=0) flag=1; //判断按键是否弹起
}
//数据分离
void fenli(uint PL) //PL为频率计数的形参
{
//显示字母,表示波形类型
xianshi[0]=PL%1000/100; //百位
,0xf0,0xec,0xe7,0xe2,0xdd,0xd7,0xd1,0xcb,0xc4,0xbd,0xb6,0xaf,0xa7,0xa0,0x98,0x90,0x88,0x80,0x78,
0x70,0x68,0x60,0x58,0x51,0x49,0x42,0x3b,0x34,0x2e,0x28,0x22,0x1d,0x18,0x14,0xf,0xc,0x9,0x6,0x4,
sbit led3=P3^3;//方波指示
//数码管位选控制口定义
sbit wei3=P2^4;
sbit wei2=P2^3;
sbit wei1=P2^2;
sbit wei0=P2^1;
//按键口定义
sbit S1=P2^5;//控制频率的减
sbit S2=P2^6;//控制频率的加
sbit S3=P2^7;//控制切换
wei2=0;
delayms(1);
wei2=1;
P0=0x76;
wei3=0;delayms(1);
wei3=1;
}
void Timerinit()
{
TMOD=0x01; //定时器0方式1
//定时器初值计算公式:X=65536-(t/Tcy)
TH0=th=(65536-50000/plcount)/256; //定时器初值
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,//0-4
0x6d,0x7d,0x07,0x7f,0x6f, //5-9
0x77,0x7c,0x39,0x5e,0x79,0x71};//a-f
//正弦波数据表
ucharcodesin_tab[100]={0x80,0x88,0x90,0x97,0x9f,0xa7,
0xaf,0xb6,0xbd,0xc4,0xcb,0xd1,0xd7,0xdd,
0xe2,0xe7,0xec,0xf0,0xf3,0xf6,0xf9,0xfb,0xfd,0xfe,0xff,0xff,0xff,0xff,0xfd,0xfc,0xf9,0xf7,0xf3