我是靠谱客的博主 儒雅橘子,这篇文章主要介绍基于51单片机信号发生器仿真设计基于51单片机信号发生器仿真设计,现在分享给大家,希望可以做个参考。

本设计

基于51单片机信号发生器仿真设计

(仿真+程序源码+设计说明书)

仿真原版本:proteus 7.8

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:S0015

目录标题

  • 基于51单片机信号发生器仿真设计
    • 仿真电路
    • 程序
      • LCD1602显示
      • 按键扫描
      • 主函数
        • 正弦波发生子程序
        • 矩形波发生子程序
        • 三角波发生子程序
        • 锯齿波发生子程序
    • 设计说明书
    • 设计清单

设计说明:

本设计采用AT89C51单片机作为控制核心,外围采用数字/模拟转换电路(DAC0832)、运放电路(LM324)、按键和LCD液晶显示电路。电路采用单片机和一片DAC0832数模转换器组成数字式低频信号发生器,可产生正弦波、矩形波、锯齿波和三角波四种波形。系统通过单片机产生数字信号,通过DAC0832转换为模拟信号,再通过放大器LM324就可以得到双极性的各种波形,最终由示波器显示出来。通过键盘来控制四种波形的类型选择、频率变化,并通过液晶1602显示其各自的波形类型以及频率数值。

本设计硬件电路简单,软件功能完善,控制系统可靠,性价比较高,具有一定的实用价值和参考价值

仿真电路

矩形波

img

三角波

img

正玄波

img

锯齿波

img

程序

img

程序设计流程图

img

LCD1602显示

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//---------------------------- //写LCD命令 //--------------------------------- void Write_LCD_Command(uchar cmd) { while((Busy_Check()&0x80)==0x80); //忙等待 RS=0; //选择命令寄存器 RW=0; //写 EN=0; P1=cmd;EN=1;DelayMS(1);EN=0; } //-------------------------------------- //发送数据 //--------------------------------------- void Write_LCD_Data(uchar dat) { while((Busy_Check()&0x80)==0x80); //忙等待 RS=1; RW=0; EN=0; P1=dat;EN=1;DelayMS(1);EN=0; } //------------------------------------ //LCD初始化 //----------------------------------------- void Init_LCD() { Write_LCD_Command(0x38); DelayMS(1); Write_LCD_Command(0x01); //清屏 DelayMS(1); Write_LCD_Command(0x06); //字符进入模式:屏幕不动,字符后移 DelayMS(1); Write_LCD_Command(0x0C); //显示开、关光标 DelayMS(1); } //--向LCD写频率值 void Write_freq(uint k) { uchar qian,bai,shi,ge; qian=k/1000; bai=k/100%10; shi=k/10%10; ge=k%10; Write_LCD_Command(0x86+0x40); Write_LCD_Data(0x30+qian); Write_LCD_Data(0x30+bai); Write_LCD_Data(0x30+shi); Write_LCD_Data(0x30+ge); Write_LCD_Data(0x48); Write_LCD_Data(0x5a); } //--LCD上显示不同波形频率 void Xianshi_f() { if(WaveChoice==1) { freq=(10000000/(50000+2860*ys)); Write_freq(freq); } if(WaveChoice==2) { freq=(10000000/(50000+2300*ys)); Write_freq(freq); } if(WaveChoice==3) { freq=(10000000/(14000+2300*ys)); Write_freq(freq); } if(WaveChoice==4) { freq=(10000000/(15000+2300*ys)); Write_freq(freq); } } //--LCD上写波形类型 void Write_wave(uchar t ) { switch(t) { case 0: //-- 无输出 Write_LCD_Command(0x86); DelayMS(5); for (i=0;i<sizeof(No)-1;i++) { Write_LCD_Data(No[i]); DelayMS(5); } break; case 1: //--正弦波 ys=25; Write_LCD_Command(0x86); DelayMS(5); for (i=0;i<sizeof(Sin)-1;i++) { Write_LCD_Data(Sin[i]); DelayMS(5); } break; case 2: //---矩形波 ys=30; Write_LCD_Command(0x86); DelayMS(5); for (i=0;i<sizeof(Squ)-1;i++) { Write_LCD_Data(Squ[i]); DelayMS(5); } break; case 3: //---三角波 ys=30; Write_LCD_Command(0x86); DelayMS(5); for (i=0;i<sizeof(Tri)-1;i++) { Write_LCD_Data(Tri[i]); DelayMS(5); } break; case 4: //----锯齿波 ys=30; Write_LCD_Command(0x86);//液晶显示位置 DelayMS(5); for (i=0;i<sizeof(Saw)-1;i++) { Write_LCD_Data(Saw[i]); DelayMS(5); } break; } }

按键扫描

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//----按键扫描 void keyscanf() { if(K2==0) { DelayMS(5); if(K2==0) { while(!K2); ys--; if(ys==0) ys=20; } } if(K3==0) { DelayMS(5); if(K3==0) { while(!K3); ys++; if(ys>22) ys=20; } } if(K4==0) { DelayMS(5); if(K4==0) { while(!K4); if(WaveChoice==2) sqar_num=sqar_num+2; if(sqar_num==238) sqar_num=128; } } if(K5==0) { DelayMS(5); if(K5==0) { while(!K5); if(WaveChoice==2) sqar_num=sqar_num-2; if(sqar_num==18) sqar_num=128; } } }

主函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//----主程序--- void main() { Init_LCD(); IE=0X81; IT0=1; Write_LCD_Command(0x80);//--显示wave: DelayMS(5); for (i=0;i<sizeof(Wave)-1;i++) { Write_LCD_Data(Wave[i]); DelayMS(5); } Write_LCD_Command(0x80+0X40);//----显示freq: DelayMS(5); for (i=0;i<sizeof(Fre)-1;i++) { Write_LCD_Data(Fre[i]); DelayMS(5); } Write_wave(WaveChoice); while (1) { keyscanf(); Out_Wave(WaveChoice); if(!(K1&K2&K3)) Xianshi_f(); } }

本系统采用编程的方法,来输出四种不同的波形即正弦波、矩形波、三角波、锯齿波。各种波形的产生方法如下。

正弦波发生子程序

正弦波的产生比较特殊,它不能由单片机直接产生,只能由如图17所示的阶梯波来向正弦波逼近。很显然,在一个周期内阶梯波的阶梯数目越多,单片机输出的波形也就越接近正弦波。

img

图17 正弦波信号的产生

先假定正弦波的振幅是2.56 V,则波谷对应的数字量为最小值00H,波峰对应的数字量为最大值FFH。将正弦波的第一个周期的波形按角度均分为若干等份,并计算出各点对应的电压值,电压值计算方法:Vx=2.5·(1+sinθ),因为00H~FFH对应的数字量为0~255,所以根据算出的电压就可直接写出各点所对应的数字量。单片机将一个周期的数字量存入一定的存储区域中,然后依次循环取出这些数字量,并送D/A电路转换成阶梯波,即近似的正弦波输出。图18为正弦波产生的流程图。

img

图18 正弦波产生的流程图

矩形波发生子程序

如图19所示,矩形波的实现比较简单。首先定义一个无符号字符型变量i=0,使自变量i不断的自动加1,若i的值小于squa_num,将P0口赋值为0xFF;若i的值大于squa_num,则将P0口赋值为0x00。当i自加到256后又自动变为0,以此循环,即可得到矩形波。当squa_num=128时,此时输出的为方波。调节squa_num的大小,即可实现矩形波占空比的调节;调节延时时间的大小,即可实现矩形波频率的改变。

img

图19 矩形波产生流程图

三角波发生子程序

三角波中的斜线用一个个小台阶来逼近,当台阶间隔很小时,波形基本上近似一直线。首先定义一个无符号字符型变量i=0,使自变量i不断的自动加1,若i的值小于128,将P0口赋值为i;若i的值大于128,则将P0口赋值为256-i。当i自加到256后又自动变为0,以此循环,从而P0口实现了周期性的数字量变换,在经过数模转换后转变成模拟信号,经运算放大电路后就得到了周期性的三角波。三角波产生流程图如图20所示。

img

​ 图20 三角波发生流程图

锯齿波发生子程序

锯齿波的实现过程与三角波类似,也是定义一个变量i=0,并使P0=i,自变量i不断的自动加1,直到加到255,然后i又可以自动归为0,再不断的重复上过程。在此过程中,P0口的值也随着i一样变化,经数模转换DAC0832后,周期性逐一变化的数字量就转换为锯齿波输出了。通过调节P0口每相邻两个值之间的延迟时间,就可以改变锯齿波的频率。图21为锯齿波发生流程图。

img

图21 锯齿波发生流程图

设计说明书

image-20220903152949631

信号发生器是一种常用的信号源,广泛地应用于电子电路、自动控制系统和教学实验等领域。 本设计采用AT89C51单片机作为控制核心,外围采用数字/模拟转换电路(DAC0832)、运放电路(LM324)、按键和LCD液晶显示电路。电路采用单片机和一片DAC0832数模转换器组成数字式低频信号发生器,可产生正弦波、矩形波、锯齿波和三角波四种波形。系统通过单片机产生数字信号,通过DAC0832转换为模拟信号,再通过放大器LM324就可以得到双极性的各种波形,最终由示波器显示出来。通过键盘来控制四种波形的类型选择、频率变化,并通过液晶1602显示其各自的波形类型以及频率数值。

本设计硬件电路简单,软件功能完善,控制系统可靠,性价比较高,具有一定的实用价值和参考价值。

关键词: AT89C51 单片机; 函数信号发生器;DAC0832;LCD液晶显示

设计清单

下载链接
image-20220903152959508

最后

以上就是儒雅橘子最近收集整理的关于基于51单片机信号发生器仿真设计基于51单片机信号发生器仿真设计的全部内容,更多相关基于51单片机信号发生器仿真设计基于51单片机信号发生器仿真设计内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(84)

评论列表共有 0 条评论

立即
投稿
返回
顶部