51单片机课程设计文档格式.docx
《51单片机课程设计文档格式.docx》由会员分享,可在线阅读,更多相关《51单片机课程设计文档格式.docx(27页珍藏版)》请在冰豆网上搜索。
(1)时钟电路
单片机工作的时间基准是由时钟电路提供的,在单片机的XTAL1和XTAL2两个引脚间,接一只晶振及两只电容就构成了单片机的时钟电路。
电路中,电容器C1和C2对振荡频率有微调作用,同时帮助晶振起振,通常取值范围在22±
0.1PF,一般晶振为11.0592MHZ,电容取22PF。
石英晶体选择11.0592MHZ。
(2)复位电路
单片机系统的复位电路在可以采用的是按钮式上电复位电路形式,其中电阻R采用10KΩ的阻值,电容采22μF的电容值。
3应用软件设计
3.1主程序设计
酒精测试仪的基本功能是通过酒精传感器采集到气体的酒精浓度,之后经过ADC0809数模转换发送给单片机,之后单片机发送给1602液晶进行显示。
当检测到的酒精浓度值超过了所设计的阈值,则酒精传感器模块将输出低电平,将其接到单片机P1^7引脚上,当单片机检测到该引脚为低电平时,则驱动蜂鸣器发生进行报警。
流程图:
3.2子程序设计
3.2.1显示子程序设计
采用1602液晶屏进行显示,将液晶数据输入端接到单片机P0口,单片机驱动液晶进行显示。
3.2.2报警子程序设计
报警电路采用蜂鸣器进行报警,当酒精浓度超过了设定值,则蜂鸣器发声进行报警,将蜂鸣器接到单片机的P3^3引脚。
3.2.3酒精检测子程序设计
酒精检测模块采用MQ-Snsor酒精气体传感器和ADC0809组成,将采集到的酒精浓度经过模数转换器发给单片机。
4系统调试与性能分析
4.1开机界面
开机之后1602界面显示,酒精检测模块气体中酒精度发送给单片机。
4.2浓度判断
当检测到的酒精浓度大于设定的阈值时,则单片机驱动蜂鸣器发生进行报警,提示检测者酒精浓度已经超标。
4.3阈值修改
(1)硬件修改
通过改变酒精传感器的电阻值来改变传感器对气体酒精度的检测灵敏度,来修改阈值。
(2)软件修改
通过对系统运行程序进行阈值设定,检测到的酒精浓度,进行人为的软件设定阈值,进行判别。
总结:
本作品针对生活中因醉酒驾驶引发交通事故日益严重,明确研究方向,制定计划方案。
深入研究酒精传感器、模数转换器等器件原理,查阅相关酒驾标准。
为制作出满足实际要求的作品,做好充分的准备。
在此期间所遇到的问题,通过最有效、最准确的渠道进行解决,为成功扫清障碍。
随着对单片机、ADC0809、LCD显示器的加深了解,对信号采集和数据算法处理的进一步学习;
加入温度、湿度和气压的影响,在现有基础上进行改进,一定会使测得的数据更加准确,使作品与预期目标更接近。
使其能成为商品,进入家庭,实现我们以此为课题的最终目的。
参考文献
[1]单成祥.传感器的理论与设计基础及其应用[M].北京:
国防工业出版社,[2]张福学.现代传感器电路[M].北京:
中国计量出版社,2000,441
[3]吴兴惠,王彩君.传感器与信号传感器[M].北京:
电子工业出版社,1998[4]万隆,巴奉丽.单片机原理及应用技术[M].北京:
清华大学出版社,2010[5]汤竟南,沈国琴.51单片机C语言开发与实例[M].人民邮电出版社
[6]雷伏容,张小林,崔浩.51单片机常用模块设计查询手册[M].北京:
清华大学出版社,2010
[7]韩成,张延拿了就用单片机[M].北京:
人民邮电出版社,2008
[8]赵建领.51系列单片机开发宝典[M].北京:
电子工业出版社,2007-04
[9]张毅刚单片机原理及接口技术:
人民邮电出版社
附录
附录A硬件电路图
附录B程序清单
/*****************************************************/
//项目名称:
//程序内容:
通过酒精模块将采集到的酒精浓度显示到1602上
//如果浓度超过设定值,则进行报警。
#include<
reg52.h>
//头文件
#defineucharunsignedchar//宏定义无符号字符型
#defineuintunsignedint//宏定义无符号整型
ucharcodetable[]="
0123456789"
;
ucharcodetable1[]="
voltage:
"
ucharcodetable2[]="
alcoholtester"
//位控制码
sbitST=P1^2;
//A/D启动转换信号
sbitOE=P1^0;
//数据输出允许信号
sbitEOC=P1^3;
//A/D转换结束信号
sbitCLK=P1^6;
//时钟脉冲
sbitdula=P2^6;
sbitwela=P2^7;
sbitrs=P3^5;
sbitlcden=P3^4;
sbitDOUT=P1^7;
sbitbeep=P3^3;
uintz,x,c,v,AD0809,date,a,i;
//定义数据类型
voidyanshi(ucharz)//延时子函数
{
uintx,y;
x=0;
y=0;
for(x=z;
x>
0;
x--)
for(y=110;
y>
y--);
}
voiddelay(uintx)//延时函数,参数x
uinta,b;
for(a=x;
a>
0;
a--)
{
for(b=10;
b>
b--)
;
}
/**************************************************/
/*函数名称:
write_com*/
/*函数描述:
1602写命令函数*/
/*输入参数:
com*/
/*参数描述:
控制命令*/
/*返回值:
无*/
voidwrite_com(ucharcom)
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
write_date*/
1602写数据函数*/
date*/
要写入的数据*/
voidwrite_date(uchardate)
P0=date;
rs=1;
voidinitLCD(void)//1602初始化函数
dula=0;
wela=0;
write_com(0x38);
delay(20);
write_com(0x0f);
write_com(0x06);
write_com(0x01);
/***********************************************
液晶显示程序
***********************************************/
voidxianshi()//显示函数
{
uintz,x,c,v;
z=date/1000;
//求千位
x=date%1000/100;
//求百位
c=date%100/10;
//求十位
v=date%10;
//求个位
for(a=20;
a>
a--)//液晶1602显示
write_com(0x80+0x40+9);
write_date(table[z]);
write_com(0x80+0x40+10);
write_date(table[x]);
write_com(0x80+0x40+11);
write_date('
.'
);
write_com(0x80+0x40+12);
write_date(table[c]);
write_com(0x80+0x40+13);
write_date(table[v]);
}
/***************************************
CLK振荡信号
****************************************/
voidtimer0()interrupt1//定时器0工作方式1
TH0=(65536-2)/256;
//重装计数初值
TL0=(65536-2)%256;
CLK=!
CLK;
//取反
/****************************************
主函数
*****************************************/
voidmain()
{
TMOD=0X01;
//定时器中断0
CLK=0;
//脉冲信号初始值为0
//定时时间高八位初值
//定时时间低八位初值
EA=1;
//开CPU中断
ET0=1;
//开T/C0中断
TR0=1;
initLCD();
write_com(0x80);
for(i=0;
i<
16;
i++)
write_date(table2[i]);
yanshi(5);
write_com(0x80+0x40);
8;
write_date(table1[i]);
}
while
(1)//无限循环
beep=1;
ST=0;
//使采集信号为低
ST=1;
//开始数据转换
//停止数据转换
while(!
EOC);
//等待数据转换完毕
OE=1;
//允许数据输出信号
AD0809=P1;
//读取数据
OE=0;
//关闭数据输出允许信号
if(AD0809>
=251)//电压显示不能超过5V
AD0809=250;
date=AD0809*20;
xianshi();
//液晶显示显示函数
if(DOUT==0)//当浓度高于设定值时,执行条件函数
yanshi(5);
//延时抗干扰
if(DOUT==0)//确定浓度高于设定值时,执行条件函数
beep=0;
yanshi(2000);
beep=1;
}
}
第二部分:
课堂设计内容:
温度测量系统
1实验目的
根据温度控制系统的要求和特点,设计了一种基于51单片机的温度显示系统。
该系统以单片机为控制核心,结合外围信号采集电路、LCD显示电路、报警电路,实现对温度的测量报警控制。
2实验内容
温度控制装置由单片机最小系统、LCD液晶显示电路、报警电路、温度传感器。
等四部分组成。
3实验原理
将温度传感器采集的数据输入单片机,单片机与程序内预先设定好电压阈值进行比较,如果温度数据大于所设定的温度阈值,则蜂鸣器发生进行报警,整个过程LCD实时显示:
温度阈值、实际温度值。
4实验步骤
主程序主要完成初始化、以及调用显示、指示灯、温度采集等等。
具体模块包括:
显示程序设计
温度采集程序设计
温度处理程序设计
显示程序设计
主要将几个数组的内容通过LCD1602的写数据指令显示在LCD屏上。
温度采集程序
通过18B20温度传感器实时采集温度并发送给单片机。
温度处理程序设计
将采集到的实时温度与设定温度阈值进行比较,如果温度大于预先设定的阈值,则蜂鸣器发生进行报警。
5流程图:
6程序清单:
//将DS18B20所采集到的温度实时显示到1602上。
//温度超过阈值则报警
reg52.H>
intrins.H>
math.H>
#defineucharunsignedchar
#defineuintunsignedint//宏定义
ucharvalue,aa;
unsignedinttmp;
//数码管段选引脚
//数码管位选引脚
sbitds=P2^2;
//18b20引脚定义
sbitRS=P3^5;
sbitLCDEN=P3^4;
//1602引脚定义
sbitbeep=P2^3;
voiddelayUs()//延时函数
_nop_();
//延时一个机器周期,包含在intrins.h文件中
voiddelayMs(uinta)//延时函数,参数a
uinti,j;
for(i=a;
i>
i--)
for(j=100;
j>
j--);
voidwriteComm(ucharcomm)//写命令
RS=0;
//写命令是RS需给低电平
P0=comm;
LCDEN=1;
//写命令时LCDEN需给高电平
delayUs();
//延时一个机器周期
LCDEN=0;
delayMs
(1);
voidwriteData(uchardat)//写数据:
RS=1,RW=0;
RS=1;
//写数据时RS=1
P0=dat;
//写数据时LCDEN=1
voidinit()//初值函数
dula=wela=0;
//段选,位选清零,数码管不显示
writeComm(0x38);
writeComm(0x0c);
writeComm(0x06);
writeComm(0x01);
//1602的命令初始化
voidwriteString(uchar*str,ucharlength)//将数据一个接着一个的写入1602中
uchari;
for(i=0;
i<
length;
i++)
writeData(str[i]);
//将数组中数据以循环的方式写入到1602中
voiddsInit()//DS18B20温度初值函数
unsignedinti;
ds=0;
i=100;
while(i>
0)i--;
//延时
ds=1;
i=4;
voiddsWait()//等待函数
while(ds);
while(~ds);
while(i>
0)i--;
bitreadBit()//bit函数返回值只能是0,1读一位数据函数
bitb;
//bit只定义一位0,1
i++;
//起到延时作用
b=ds;
i=8;
returnb;
//返回b,0,1
unsignedcharreadByte()//读一位字节数据函数
unsignedcharj,dat;
dat=0;
i<
j=readBit();
dat=(j<
<
7)|(dat>
>
1);
//位或运算,读出的数据最低位在最前//面,这样刚好一个字节在dat里
returndat;
voidwriteByte(unsignedchardat)//向18b20写一个字节数据函数
unsignedcharj;
for(j=0;
j<
8;
j++)
b=dat&
0x01;
dat>
=1;
//对dat右移一位,将值赋给dat
if(b)//写1
{
ds=0;
i++;
ds=1;
i=8;
while(i>
else
//写0
voidsendChangeCmd()//DS18B20开始获取温度并转换
dsInit();
//DS18B20温度初值
dsWait();
//等待函数
//延时
writeByte(0xcc);
//向18b20写一个字节数据函数,写跳过读ROM指令
writeByte(0x44);
//向18b20写一个字节数据函数,写温度转换指令
voidsendReadCmd()//读取寄存器中存储的温度数据
writeByte(0xbe);
intgetTmpValue()
unsignedinttmpvalue;
intvalue;
floatt;
unsignedcharlow,high;
sendReadCmd();
low=readByte();
high=readByte();
tmpvalue=high;
tmpvalue<
=8;
tmpvalue|=low;
//按位进行或运算tmpvalue=(tmpvalue|low)
value=tmpvalue;
t=value*0.0625;
value=t*100+(value>
0?
0.5:
-0.5);
//大于0加0.5,小于0减0.5
returnvalue;
voiddisplay(intv)
unsignedcharcount;
unsignedchardatas[]={0,0,0,0,0};
tmp=abs(v);
datas[0]=tmp/10000;
datas[1]=tmp%10