太原理工单片机课程设计.docx

上传人:b****5 文档编号:3869692 上传时间:2022-11-26 格式:DOCX 页数:22 大小:186.84KB
下载 相关 举报
太原理工单片机课程设计.docx_第1页
第1页 / 共22页
太原理工单片机课程设计.docx_第2页
第2页 / 共22页
太原理工单片机课程设计.docx_第3页
第3页 / 共22页
太原理工单片机课程设计.docx_第4页
第4页 / 共22页
太原理工单片机课程设计.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

太原理工单片机课程设计.docx

《太原理工单片机课程设计.docx》由会员分享,可在线阅读,更多相关《太原理工单片机课程设计.docx(22页珍藏版)》请在冰豆网上搜索。

太原理工单片机课程设计.docx

太原理工单片机课程设计

单片机课程设计书

 

学院:

信息工程学院

班级:

自动化0802

姓名:

白亮

学号:

2008001103

教师:

李丽宏

一。

设计目的:

通过综合利用所学过单片机知识完成一个单片机应用系统设计,从而加深对单片机软硬知识的理解,获得初步的应用经验,为走出校门从事单片机应用的相关工作打下基础。

2.设计题目:

基于对用液晶显示器来实现对于DS18B20传回的温度进行数据显示,从而判断现场温度的变化指数。

当温度低于28度时进行下线缓慢报警,当处于28~29度时进行快速报警时长较长:

当温度在32~33度时同样是快速报警,在33度以上是慢速报警。

三.基于AT89C52单片机基本特性:

8位的CPU,片内有振荡器和时钟电路,工作频率为0~24MHz片内有256字节数据存储器RAM片内有8K字节程序存储器ROM4个8位的并行I/O口(P0、P1、P2、P3)1个全双工串行通讯口3个16位定时器/计数器(T0、T1、T2)可处理6个中断源,两级中断优先级.Vcc,GND:

正电源端与接地端(+5V)XTAL1,XTAL2:

片内振荡电路输入/输出端CPU都是按照一定的时钟节拍与时序进行工作:

时钟周期:

Tc=晶振频率fosc的倒数机器周期:

Tm==12个时钟周期(Tc)指令周期:

Ti:

执行一条指令所需的机器周期(Tm)数

P1.0—P1.7:

准双向I/O口(内置了上拉电阻)输出时一切照常,仅在作输入口用时要先对其写“1”

P0.0—P0.7:

双向I/O(内置场效应管上拉)寻址外部程序存储器时分时作为双向8位数据口和输出低8位地址复用口;不接外部程序存储器时可作为8位准双向I/O口使用。

寻址外部程序存储器时分时作为双向8位数据口和输出低8位地址复用口;不接外部程序存储器时可作为8位准双向I/O口使用。

P2.0—P2.7:

双向I/O(内置了上拉电阻)寻址外部程序存储器时输出高8位地址;不接外部程序存储器时可作为8位准双向I/O口使用。

寻址外部程序存储器时输出高8位地址;不接外部程序存储器时可作为8位准双向I/O口使用。

P3.0—P3.7:

双功能口(内置了上拉电阻)它具有特定的第二功能。

在不使用它的第二功能时它就是普通的通用准双向I/O口。

单总线数字温度传感器DS18B20:

单总线即只有一根数据线,系统中的数据交换,控制都由这根线完成。

单总线通常要求外接一个约为4.7K—10K的上拉电阻,这样,当总线闲置时其状态为高电平。

DS18B20单线数字温度传感器,即“一线器件”,其具有独特的优点:

    

(1)采用单总线的接口方式与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。

单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。

    

(2)测量温度范围宽,测量精度高DS18B20的测量范围为-55℃~+125℃;在-10~+85°C范围内,精度为±0.5°C。

    (3)在使用中不需要任何外围元件。

    (4)持多点组网功能多个DS18B20可以并联在惟一的单线上,实现多点测温。

    (5)供电方式灵活DS18B20可以通过内部寄生电路从数据线上获取电源。

因此,当数据线上的时序满足一定的要求时,可以不接外部电源,从而使系统结构更趋简单,可靠性更高。

    (6)测量参数可配置DS18B20的测量分辨率可通过程序设定9~12位。

    (7)负压特性电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。

(8)掉电保护功能DS18B20内部含有EEPROM,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

    DS18B20具有体积更小、适用电压更宽、更经济、可选更小的封装方式,更宽的电压适用范围,适合于构建自己的经济的测温系统,因此也就被设计者们所青睐。

主要由4部分组成:

64位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。

ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。

64位ROM的排的循环冗余校验码(CRC=X^8+X^5+X^4+1)。

ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。

四。

电路图如下所示:

6.原理图如下:

 

N

Y

Y

N

 

五.实际单片机板如下所示:

//DS18B20温度检测及其液晶显示

#include//包含单片机寄存器的头文件

#include//包含_nop_()函数定义的头文件

unsignedcharcodedigit[11]={"0123456789-"};//定义字符数组显示数字

unsignedcharcodeStr[]={"RICHMCUDS18B20"};//说明显示的是温度

unsignedcharcodeError[]={"DS18B20ERROR"};//说明没有检测到DS18B20

unsignedcharcodeError1[]={"PLEASECHECK"};//说明没有检测到DS18B20

unsignedcharcodeTemp[]={"WENDU:

"};//说明显示的是温度

unsignedcharcodeCent[]={"Cent"};//温度单位

unsignedcharflag,tltemp;//负温度标志和临时暂存变量

/*以下是对液晶模块的操作程序*/

sbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚

sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚

sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚

sbitBF=P0^7;//忙碌标志位,,将BF位定义为P0.7引脚

/*函数功能:

延时1ms

(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒*/

voiddelay1ms()

{

unsignedchari,j;

for(i=0;i<4;i++)

for(j=0;j<33;j++)

;

}

/*函数功能:

延时若干毫秒

入口参数:

n*/

voiddelaynms(unsignedcharn)

{

unsignedchari;

for(i=0;i

delay1ms();

}

/*函数功能:

判断液晶模块的忙碌状态

返回值:

result。

result=1,忙碌;result=0,不忙*/

bitBusyTest(void)

{

bitresult;

RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态

RW=1;

E=1;//E=1,才允许读写

_nop_();//空操作

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

result=BF;//将忙碌标志电平赋给result

E=0;//将E恢复低电平

returnresult;

}

/*

函数功能:

将模式设置指令或显示地址写入液晶模块

入口参数:

dictate*/

voidWriteInstruction(unsignedchardictate)

{

while(BusyTest()==1);//如果忙就等待

RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令

RW=0;

E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,

//就是让E从0到1发生正跳变,所以应先置"0"

_nop_();

_nop_();//空操作两个机器周期,给硬件反应时间

P0=dictate;//将数据送入P0口,即写入指令或地址

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=1;//E置高电平

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令

}

/*函数功能:

指定字符显示的实际地址

入口参数:

x*/

voidWriteAddress(unsignedcharx)

{

WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x"

}

voidWriteData(unsignedchary)

{

while(BusyTest()==1);

RS=1;//RS为高电平,RW为低电平时,可以写入数据

RW=0;

E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,

//就是让E从0到1发生正跳变,所以应先置"0"

P0=y;//将数据送入P0口,即将数据写入液晶模块

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=1;//E置高电平

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令

}

/*函数功能:

对LCD的显示模式进行初始化设置*/

voidLcdInitiate(void)

{

delaynms(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间

WriteInstruction(0x38);//显示模式设置:

16×2显示,5×7点阵,8位数据接口

delaynms(5);//延时5ms ,给硬件一点反应时间

WriteInstruction(0x38);

delaynms(5);//延时5ms ,给硬件一点反应时间

WriteInstruction(0x38);//连续三次,确保初始化成功

delaynms(5);//延时5ms ,给硬件一点反应时间

WriteInstruction(0x0c);//显示模式设置:

显示开,无光标,光标不闪烁

delaynms(5);//延时5ms ,给硬件一点反应时间

WriteInstruction(0x06);//显示模式设置:

光标右移,字符不移

delaynms(5);//延时5ms ,给硬件一点反应时间

WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除

delaynms(5);//延时5ms ,给硬件一点反应时间

}

/*以下是DS18B20的操作程序***/

sbitDQ=P3^3;

unsignedchartime;//设置全局变量,专门用于严格延时

/*函数功能:

将DS18B20传感器初始化,读取应答信号

出口参数:

flag*/

bitInit_DS18B20(void)

{

bitflag;//储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在

DQ=1;//先将数据线拉高

for(time=0;time<2;time++)//略微延时约6微秒

;

DQ=0;//再将数据线从高拉低,要求保持480~960us

for(time=0;time<200;time++)//略微延时约600微秒

;//以向DS18B20发出一持续480~960us的低电平复位脉冲

DQ=1;//释放数据线(将数据线拉高)

for(time=0;time<10;time++)

;//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)

flag=DQ;//让单片机检测是否输出了存在脉冲(DQ=0表示存在)

for(time=0;time<200;time++)//延时足够长时间,等待存在脉冲输出完毕

;

return(flag);//返回检测成功标志

}

/*函数功能:

从DS18B20读取一个字节数据

出口参数:

dat*/

unsignedcharReadOneChar(void)

{

unsignedchari=0;

unsignedchardat;//储存读出的一个字节数据

for(i=0;i<8;i++)

{

DQ=1;//先将数据线拉高

_nop_();//等待一个机器周期

DQ=0;//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序

_nop_();//等待一个机器周期

DQ=1;//将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备

for(time=0;time<2;time++)

;//延时约6us,使主机在15us内采样

dat>>=1;

if(DQ==1)

dat|=0x80;//如果读到的数据是1,则将1存入dat

else

dat|=0x00;//如果读到的数据是0,则将0存入dat

//将单片机检测到的电平信号DQ存入r[i]

for(time=0;time<8;time++)

;//延时3us,两个读时序之间必须有大于1us的恢复期

}

return(dat);//返回读出的十六进制数据

}

/*函数功能:

向DS18B20写入一个字节数据

入口参数:

dat*/

WriteOneChar(unsignedchardat)

{

unsignedchari=0;

for(i=0;i<8;i++)

{

DQ=1;//先将数据线拉高

_nop_();//等待一个机器周期

DQ=0;//将数据线从高拉低时即启动写时序

DQ=dat&0x01;//利用与运算取出要写的某位二进制数据,

//并将其送到数据线上等待DS18B20采样

for(time=0;time<10;time++)

;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样

DQ=1;//释放数据线

for(time=0;time<1;time++)

;//延时3us,两个写时序间至少需要1us的恢复期

dat>>=1;//将dat中的各二进制位数据右移1位

}

for(time=0;time<4;time++)

;//稍作延时,给硬件一点反应时间

}

/*函数功能:

做好读温度的准备*/

voidReadyReadTemp(void)

{

Init_DS18B20();//将DS18B20初始化

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0x44);//启动温度转换

delaynms(200);//转换一次需要延时一段时间

Init_DS18B20();//将DS18B20初始化

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0xBE);//读取温度寄存器,前两个分别是温度的低位和高位

}

/*以下是与温度有关的显示设置*/

/*函数功能:

显示没有检测到DS18B20*/

voiddisplay_error(void)

{

unsignedchari;

WriteAddress(0x00);//写显示地址,将在第1行第1列开始显示

i=0;//从第一个字符开始显示

while(Error[i]!

='\0')//只要没有写到结束标志,就继续写

{

WriteData(Error[i]);//将字符常量写入LCD

i++;//指向下一个字符

delaynms(100);//延时100ms较长时间,以看清关于显示的说明

}

WriteAddress(0x40);//写显示地址,将在第1行第1列开始显示

i=0;//从第一个字符开始显示

while(Error1[i]!

='\0')//只要没有写到结束标志,就继续写

{

WriteData(Error1[i]);//将字符常量写入LCD

i++;//指向下一个字符

delaynms(100);//延时100ms较长时间,以看清关于显示的说明

}

while

(1)//进入死循环,等待查明原因

;

}

/*函数功能:

显示说明信息*/

voiddisplay_explain(void)

{

unsignedchari;

WriteAddress(0x00);//写显示地址,将在第1行第1列开始显示

i=0;//从第一个字符开始显示

while(Str[i]!

='\0')//只要没有写到结束标志,就继续写

{

WriteData(Str[i]);//将字符常量写入LCD

i++;//指向下一个字符

delaynms(100);//延时100ms较长时间,以看清关于显示的说明

}

}

/*函数功能:

显示温度符号*/

voiddisplay_symbol(void)

{

unsignedchari;

WriteAddress(0x40);//写显示地址,将在第2行第1列开始显示

i=0;//从第一个字符开始显示

while(Temp[i]!

='\0')//只要没有写到结束标志,就继续写

{

WriteData(Temp[i]);//将字符常量写入LCD

i++;//指向下一个字符

delaynms(50);//延时1ms给硬件一点反应时间

}

}

/*函数功能:

显示温度的小数点*/

voiddisplay_dot(void)

{

WriteAddress(0x49);//写显示地址,将在第2行第10列开始显示

WriteData('.');//将小数点的字符常量写入LCD

delaynms(50);//延时1ms给硬件一点反应时间

}

/*函数功能:

显示温度的单位(Cent)*/

voiddisplay_cent(void)

{

unsignedchari;

WriteAddress(0x4c);//写显示地址,将在第2行第13列开始显示

i=0;//从第一个字符开始显示

while(Cent[i]!

='\0')//只要没有写到结束标志,就继续写

{

WriteData(Cent[i]);//将字符常量写入LCD

i++;//指向下一个字符

delaynms(50);//延时1ms给硬件一点反应时间

}

}

/*函数功能:

显示温度的整数部分入口参数:

x*/

voiddisplay_temp1(unsignedcharx)

{

unsignedcharj,k,l;//j,k,l分别储存温度的百位、十位和个位

j=x/100;//取百位

k=(x%100)/10;//取十位

l=x%10;//取个位

WriteAddress(0x46);//写显示地址,将在第2行第7列开始显示

if(flag==1)//负温度时显示“—”

{

WriteData(digit[10]);//将百位数字的字符常量写入LCD

}

else{

WriteData(digit[j]);//将十位数字的字符常量写入LCD

}

WriteData(digit[k]);//将十位数字的字符常量写入LCD

WriteData(digit[l]);//将个位数字的字符常量写入LCD

delaynms(50);//延时1ms给硬件一点反应时间

}

/*函数功能:

显示温度的小数数部分

入口参数:

x*/

voiddisplay_temp2(unsignedcharx)

{

WriteAddress(0x4a);//写显示地址,将在第2行第11列开始显示

WriteData(digit[x]);//将小数部分的第一位数字字符常量写入LCD

delaynms(50);//延时1ms给硬件一点反应时间

}

voidwarn(uints,ucharled)//蜂鸣器报警,灯闪烁。

{

uchari;i=s;

beep=0;//蜂鸣器响。

相应灯亮。

P1=~(led);

while(i--);

{

P1=a[i];

}

delayms(5);

beep=1;

P1=0xff;//用温度显示函数起到延时作用。

i=s;

while(i--)

{

P1=a[3];

}

}

voiddeal(uintt)//温度处理函数。

{

uchari;

if((t>=warn_l2)&&(t=

{

warn(40,0x01);//第一个灯亮,蜂鸣器发出报警

}

if((t

{

warn(10,0x03);//第一个和第二个灯亮,蜂鸣器报警

}

if((t>=warn_h1)&&(t=

{

warn(40,0x04);//第三个灯亮,报警四十次。

}

if((t>warn_h2))//温度高于33度

{

warn(10,0x0c);//第三个和第四个灯亮,报警十次。

}

else

{

i=40;//其它温度不报警。

while(i--);

{

P1=0x0f;

}

}

}

voidmain(void)//主函数。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 职业教育 > 中职中专

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1