单片机课设报告.docx
《单片机课设报告.docx》由会员分享,可在线阅读,更多相关《单片机课设报告.docx(26页珍藏版)》请在冰点文库上搜索。
单片机课设报告
第一章绪论
1.1课程设计的目的
提高学生在单片机应用方面的实践技能,树立严谨的科学作风,培养学生综合运用理论知识解决实际问题的能力。
学生通过单片机硬件设计和软件设计、组装焊接、程序调试、整理资料等环节,初步掌握单片机应用系统的开发设计过程。
1.2课程设计要求
完成一个以单片机为核心的温度检测系统(实物)设计制作。
性能参数:
温度测量范围:
-0℃~100℃,测量误差≤0.5℃。
主要器件:
MCU选用8051系列,显示选用LCD1602,使用温度传感器,使用AD转换。
基本功能:
完成实时温度检测并显示。
扩展功能:
时钟显示(能调整),温度控制(能设定温控区间),温度数据无线传输,等其他功能。
第二章方案设计
2.1方案选择
2.1.1测温电路方案
方案一
进而考虑到用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。
方案二
由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D转换电路,感温电路比较麻烦
2.1.2显示电路方案
方案一:
采用数码管动态显示,使用七段LED数码管,采用动态显示的方法来显示各项指标,此方法虽然价格成本低,但是显示单一,且功耗较大。
方案二:
采用LCD液晶显示
采用1602 LCD液晶显示,此方案显示内容相对丰富,且价格不高。
综合上述原因,采用方案二,使用LCD液晶作显示电路。
综合上诉,测温电路选择方案一,显示电路选择方案二。
2.2系统设计原理
利用温度传感器DS18B20可以直接读取被测温度值,进行转换的特性,模拟温度值经过DS18B20处理后转换为数字值,然后送到单片机中进行数据处理,并与设置的温度报警限比较,超过限度后通过扬声器报警。
同时处理后的数据送到LED显示。
2.3系统组成
本设计是以80C51单片机为核心设计的一种数字温度控制系统,系统整体硬件电路包括:
传感器数据采集电路,温度显示电路,上下限报警调整电路,单片机主板电路等组成。
系统框图主要由主控制器、单片机复位、报警设置、时钟振荡、LED显示、温度传感器组成。
系统框图如图1所示。
图1系统框图
1、主控制器
单片机AT80C51具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用系统可用两节电池供电。
2、显示电路
显示电路采用LED液晶显示数码管,从P3到RXD,TXD串口输出段码。
显示电路是使用的串口显示,这种那个显示的最大优点是使用口资源比较少。
3、温度传感器
温度传感器采用DS18B20温度传感器。
DS18B20输出信号全数字化,便于单片机处理和控制。
第三章硬件设计
3.1核心处理器的设计
3.1.180C51单片机的介绍
单片机是电路的核心部分,系统采用了51系列单片机。
在众多的51单片机系列中,AT89系列单片机在我国得到及其广泛的应用,越来越受到人们的瞩目。
AT89系列单片机是美国ATMEL公司的8位Flash单片机产品。
它的最大特点是在片内含有Flash存储器,在系统的开发过程中修改程序容易,使开发调试更为方便。
AT89系列单片机以8031为内核,是与8051系列单片机兼容的系列,其型号可以分为标准型、低档型和高档型3类。
高档型单片机有AT89S51、AT89S52、AT89S53和AT89S8252等型号,其中AT89S52为ATMEL所生产的一种低功耗、高性能CMOS8位微控制器,内部有8KB的可下载Flash存储器,2KB的EEPROM,提高了存储容量,系统不必扩展外部程序存储器和数据存储器这样大大的减少了系统硬件部分。
因此,本系统使用80C51单片机作为微处理器.如图2所示。
图280C51管脚图
3.1.280C51单片机的中断系统
80C51系列单片机的中断系统有5个中断源,2个优先级,可以实现二级中断服务嵌套。
由片内特殊功能寄存器中的中断允许寄存器IE控制CPU是否响应中断请求;由中断优先级寄存器IP安排各中断源的优先级;同一优先级内各中断同时提出中断请求时,由内部的查询逻辑确定其响应次序。
3.1.380C51单片机的定时/计数器
在单片机应用系统中,常常会有定时控制需求,如定时输出、定时检测、定时扫描等;也经常要对外部事件进行计数。
80C51单片机内集成有两个可编程的定时/计数器:
T0和T1,它们既可以工作于定时模式,也可以工作于外部事件计数模式,此外,T1还可以作为串行口的波特率发生器。
3.1.3复位电路的设计
单片机复位电路如图3所示,上电复位就是VCC通过电阻R2和电容C2构成回路,该回路是一个对电容C2充电和放电的电路,所以复位端口得到一个周期性变化的电压值,并且有一定时间的电压值高于CPU复位电压,实现上电复位功能。
图3单片机复位电路
3.1.4晶振电路的设计
单片机晶振电路的设计如图4所示,19号引脚为反向振荡放大器的输入及内部时钟工作电路的输入。
18号引脚是来自反向振荡器的输出按照理论上AT89C51使用的是12MHz的晶振,但实测使用11.0592MHz。
所以设计者通常用的是11.0592MHz。
图4单片机晶振电路
3.1.5报警电路的设计
报警电路的设计如图5所示,当温度大于等于上限温度时,嗡鸣器实现报警。
图5单片机报警电路
3.1.6调温调时电路的设计
调温调时电路如图6所示,通过按键进行调温调时。
图6调温调时电路
3.2液晶显示模块的设计
3.2.1LED液晶显示屏的介绍
液晶显示器(LCD)英文全称为Liquid Crystal Display,它一种是采用了液晶控制透光度技术来实现色彩的显示器。
和CRT显示器相比,LCD的优点是很明显的。
由于通过控制是否透光来控制亮和暗,当色彩不变时,液晶也保持不变,这样就无须考虑刷新率的问题。
显示接口用来显示系统的状态,命令或采集的电压数据。
本系统显示部分用的是LCD液晶模块,采用一个16×1的字符型液晶显示模块。
点阵图形式液晶由M行×N 列个显示单元组成,假设LCD 显示屏有64行,每行有128列,每8列对应1个字节的8 个位,即每行由16字节,共
16×8=128个点组成,屏上64×16 个显示单元和显示RAM区1024个字节相对应,每一字节的内容和屏上相应位置的亮暗对应。
一个字符由 6×8 或 8×8点阵组成,即要找到和屏上某几个位置对应的显示 RAM区的8个字节,并且要使每个字节的不同的位为1,其它的为0,为1的点亮,为0的点暗,这样一来就组成某个字符。
但对于内带字符发生器的控制器来说,显示字符就比较简单了,可让控制器工作在文本方式,根据在LCD 上开始显示的行列号及每行的列数找出显示 RAM对应的地址,设立光标,在此送上该字符对应的代码即可。
1602液晶模块简介微功耗、体积小、显示内容丰富、超薄轻巧,常用在袖珍式仪表和低功耗应用系统中。
1602的管脚分布如图7所示。
图7液晶显示屏
3.2.2液晶显示部分与STC89C52的接口
LCD显示分为静态显示和动态显示。
这里采用静态显示,系统通过单片机的串行口来实现静态显示。
串行口为方式零状态,即工作在移位寄存器方式,波特率为振荡频率的1/12。
当器件执行任何一条将SBUF作为目的寄存器的命令时,数据便开始从RXD端发送。
在写信号有效时,相隔一个机器周期后发送控制端SEND有效,即允许RXD发送数据,同时允许从TXD端输出移位脉冲。
3.3数字温度传感器DS18B20
3.3.1DS18B20的介绍
由dallas半导体公司生产的ds18b20型单线智能温度传感器,属于新一代适配微处理器的智能温度传感器,可广泛用于工业、民用、军事等领域的温度测量及控制仪器、测控系统和大型设备中。
它具有体积小,接口方便,传输距离远等特点。
3.3.2DS18B20的性能特点
采用单总线的接口方式,测量温度范围宽,测量精度高,在使用中不需要任何外围元件,持多点组网功能,供电方式灵活,测量参数可配置,负压特性,掉电保护功能。
3.3.3温度采集电路
图8温度采集电路
第四章软件设计
鉴于课设时间较短,故采用老师已有的设计进行实际操作。
4.1程序设计
4.1.1程序框图
系统软件设计主要包括显示子程序,报警子程序,温度传感器的子程序。
以是
主程序与各个子程序的程序流程图。
主程序框图如下。
图9主程序图
读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,检验有错时不进行温度数据的改写。
温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。
温度转换命令子程序流程图,如图10。
图10子程序图
4.1.2程序
#include
#include
sbitRS=P2^0;//定义1602端口
sbitRW=P2^1;
sbitEN=P2^2;
sbitKEY_AJ1=P1^0;//定义温设按键输入端口
sbitKEY_AJ2=P1^1;
sbitKEY_AJ3=P1^2;//定义时间按键输入端口
sbitKEY_AJ4=P1^3;
sbitSPK=P2^3;//定义喇叭端口
#defineuintunsignedint
#defineRS_CLRRS=0
#defineRS_SETRS=1
#defineRW_CLRRW=0
#defineRW_SETRW=1
#defineEN_CLREN=0
#defineEN_SETEN=1
#defineDataPortP0
unsignedcharset=30;
unsignedcharsetg;
unsignedcharsets;
unsignedcharsetb;
unsignedchartemp=60;
unsignedchartempg;
unsignedchartemps;
unsignedchartempb;
unsignedintTIME=0;
unsignedcharTIMESS;
unsignedcharTIMESG;
unsignedcharTIMEFS;
unsignedcharTIMEFG;
unsignedcharTIMEMS;
unsignedcharTIMEMG;
voidDelayUs2x(unsignedchart);//函数声明
voidDelayMs(unsignedchart);
voidDisplay(unsignedcharFirstBit,unsignedcharNum);
voidInit_Timer0(void);
voidinit_adc(void);//初始化AD
uintget_adc(void);//获取AD结果,返回UINT型值
/*------------------------------------------------
uS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5uS
------------------------------------------------*/
voidDelayUs2x(unsignedchart)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
voidDelayMs(unsignedchart)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bitLCD_Check_Busy(void)
{
DataPort=0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return(bit)(DataPort&0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
voidLCD_Write_Com(unsignedcharcom)
{
//while(LCD_Check_Busy());//忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort=com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
voidLCD_Write_Data(unsignedcharData)
{
//while(LCD_Check_Busy());//忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort=Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
voidLCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s)
{
if(y==0)
{
LCD_Write_Com(0x80+x);//表示第一行
}
else
{
LCD_Write_Com(0xC0+x);//表示第二行
}
while(*s!
='\0')
{
LCD_Write_Data(*s);
s++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
voidLCD_Write_Char(unsignedcharx,unsignedchary,unsignedcharData)
{
if(y==0)
{
LCD_Write_Com(0x80+x);
}
else
{
LCD_Write_Com(0xC0+x);
}
LCD_Write_Data(Data);
}
/*****************************
AD
******************************/
voidinit_adc(void)
{
P1ASF=0x10;//AD功能寄存器,设置I/O口作为AD转换实用。
使用P1.0口。
ADC_RES=0;//清理结果寄存器的值
ADC_RESL=0;//清理结果寄存器的值
ADC_CONTR=0x84;//开启AD电源并设置转换周期为540个时钟周期转换一次。
//ADC_POWER=1; CHS2,1,0为0,用p1.0作为输入。
SPEED1,0为0,540个时钟,
DelayMs
(2);
}
uintget_adc(void)
{
uintd=0;
ADC_CONTR=0X8C;
_nop_();
_nop_();
_nop_();
_nop_();
while(!
(ADC_CONTR&0X10));
ADC_CONTR&=~0X10;
d|=ADC_RES;
d<<=2;
d|=ADC_RESL;
returnd;
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
voidLCD_Init(void)
{
LCD_Write_Com(0x38);/*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08);/*显示关闭*/
LCD_Write_Com(0x01);/*显示清屏*/
LCD_Write_Com(0x06);/*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C);/*显示开及光标设置*/
}
/***********
按键控制设置温度
******************************/
voidKEY_TempSet(void)
{
if(!
KEY_AJ1)//如果检测到低电平,说明按键按下
{
if(set<101)//加操作
set++;
}
if(!
KEY_AJ2)//如果检测到低电平,说明按键按下
{
if(set>0)//减操作
set--;
}
}
/***********
按键控制时间
******************************/
voidKEY_SETtime(void)
{
if(!
KEY_AJ3)//如果检测到低电平,说明按键按下
{
TIME+=3600;
}
if(!
KEY_AJ4)//如果检测到低电平,说明按键按下
{
TIME+=60;
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
/*-----------------------------------------------
1602显示函数
------------------------------------------------*/
voidwrite_1602(void)
{
TIMEMG=((TIME%3600)%60)%10+'0';
TIMEMS=((TIME%3600)%60)/10+'0';
TIMEFG=((TIME%3600)/60)%10+'0';
TIMEFS=((TIME%3600)/60)/10+'0';
TIMESG=(TIME/3600)%10+'0';
TIMESS=(TIME/3600)/10+'0';
LCD_Write_Char(0,0,'T');
LCD_Write_Char(1,0,'I');
LCD_Write_Char(2,0,'M');
LCD_Write_Char(3,0,'E');
LCD_Write_Char(5,0,TIMESS);
LCD_Write_Char(6,0,TIMESG);
LCD_Write_Char(7,0,':
');
LCD_Write_Char(8,0,TIMEFS);
LCD_Write_Char(9,0,TIMEFG);
LCD_Write_Char(10,0,':
');
LCD_Write_Char(11,0,TIMEMS);
LCD_Write_Char(12,0,TIMEMG);
/****************************************
***************************************/
setg=(set%100)%10+'0';
sets=(set%100)/10+'0';
setb=set/100+'0';
LCD_Write_Char(0,1,'H');
LCD_Write_Char(1,1,':
');
LCD_Write_Char(2,1,setb);
LCD_Write_Char(3,1,sets);
LCD_Write_Char(4,1,setg);
LCD_Write_Char(6,1,'C');
tempg=(temp%100)%10+'0';
temps=(temp%100)/10+'0';
tempb=temp/100+'0';
LCD_Write_Char(9,1,'T');
LCD_Write_Char(10,1,'=');
LCD_Write_Char(11,1,tempb);
LCD_Write_Char(12,1,temps);