前言
??这篇文章是自己写的单片机课设,发这篇文章就当留个小纪念;如果说有什么不太好的地方还请大神请指出 ?Keil C51的代码以及Proteus的仿真的百度网盘链接放到这里 ? 链接: 点我跳转点我点我点我 ?(提取码:TYWL)
提示:以下是本篇文章正文内容,下面案例可供参考
一、课设任务是什么?
- 设计一款能产生3种以上波形的波形发生器
- 设计波形选择按钮(采用3个独立按键)
- 点阵显示波形图案;
- 能同时输出两种波形;
- 显示频率。
二、如何解决这几个任务?
- 能产生3种以上波形
? 分析:通过查阅资料,得知常用的波形有正弦波、方波、锯齿波、三角波四种波形其余的被称为任意波,因此我主要的目的便是输出四种波形. - 能同时输出两种波形
? 同时输出两个波形,就要轮转着用相同的8个I/O口来将波形取码输出到数模转换电路中,也就是对P0这个口时分复用. ? 对于波形的取码,采用二维数组来存放数据. - 设计波形选择按钮(采用3个独立按键)
? 硬件方面:同时输出两个波形,意味着需要对两个波形进行调控,需要两个按键;开始设置波形与结束设置波形各一个按键,共四个按键实现波形选择. ? 程序方面:初步构想是不在主函数中调用键盘扫描,而是在外部中断0服务程序中调用,中断时查询能够节省大部分资源.同时输出两个波形,意味着需要对两个波形进行调控,需要两个按键.再定义两个变量,一个按键对应一个变量就能够解决. - 点阵显示波形图案
? 硬件方面:Proteus中最小的点阵是8*8点阵,如果直接连接到51单片机上I/O口是肯定的不够用的,所以采用串口输出的方式.串并转换芯片采用74HC595;只需要6个引脚就能够控制16个引脚的8*8点阵 ? 程序方面:用一个二维数组来存储点阵显示的数据;为了节省C51的空间,就利用上面波形选择时候两个变量来控制这个二维数组. - 显示频率
?硬件方面:P1口连接LCD1602的8个数据口,其他的命令位是在P2.6 P2.7 ?程序方面:第一行(也就是write_com(0x80))显示波形输出端一的波形.第二行(就是执行write_com(0xc0))显示的是频率.
三、仿真原理图
四、代码
4.1 LCD1602代码
?对于LCD1602来说,将它的代码和主函数放到同一个.c文件中会显得十分的累赘;对于这个波形发生器来说LCD显示只是辅助功能,所以放到一个独立的头文件中是一个不错的选择.
#ifndef _LCD1602_H_
#define _LCD1602_H_
#include<REG52.H>
#define uint unsigned int
#define uchar unsigned char
sbit lcdrs = P2^7;
sbit lcden = P2^6;
void lcd_ram();
void init_lcd();
void write_com(uchar com);
void write_date(uchar date);
void delay_LCD56(uint xms);
uchar code table[];
uchar code table1[];
uchar code zifu[];
#endif
相关的LCD1602.c文件在链接里面有,这里就不再展示
4.2 波形输出以及8*8LED显示代码
?对于波形输出采用定时器中断的方式输出,通过设置定时/计数器的初值就能够控制波形的频率,对于以后功能的扩展是个不错的选择;
void T0_time() interrupt 1
{
TH0=a;
TL0=b;
u++;
if(u>=64)
u=0;
WR1 = 1;
CS0 = 0;
CS1 = 1;
P0 = wave[flag_0][u];
WR1 = 0;
delay(20);
for(temp = 0;temp<4;temp++)
{
line_scan();
send_595(matrix[flag_0][temp]);
delay(3);
ST_CP_0 = 0;
ST_CP_0 = 1;
_nop_();
ST_CP_0 = 0;
}
WR1 = 1;
CS0 = 1;
CS1 = 0;
P0 = wave[flag_1][u];
WR1 = 0;
delay(20);
for(temp = 0;temp<4;temp++)
{
line_scan();
send_595(matrix[flag_1][temp]);
delay(3);
ST_CP_0 = 0;
ST_CP_0 = 1;
_nop_();
ST_CP_0 = 0;
}
}
4.3 波形选择
波形选择用的是外部中断0,节省资源;设置优先级高于定时器中断0,能够打断中断0的服务程序进行设置.
void keyscan()
{
if(s1 == 0)
{
delay(1);
if(s1 == 0)
{
EA = 0;
while(!s1);
if(++flag_0==4)
flag_0=0;
display();
EA = 1;
}
}
if(s2==0)
{
delay(1);
if(s2==0)
{
EA=0;
while(!s2);
if(++flag_1==4)
flag_1=0;
EA=1;
}
}
}
void interrupt_0() interrupt 0 using 3
{
while (s3!=0)
{
keyscan();
}
}
结尾
若有错误,欢迎私信指出
|