校园打铃系统的设计.docx

上传人:b****6 文档编号:8669190 上传时间:2023-02-01 格式:DOCX 页数:32 大小:495.30KB
下载 相关 举报
校园打铃系统的设计.docx_第1页
第1页 / 共32页
校园打铃系统的设计.docx_第2页
第2页 / 共32页
校园打铃系统的设计.docx_第3页
第3页 / 共32页
校园打铃系统的设计.docx_第4页
第4页 / 共32页
校园打铃系统的设计.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

校园打铃系统的设计.docx

《校园打铃系统的设计.docx》由会员分享,可在线阅读,更多相关《校园打铃系统的设计.docx(32页珍藏版)》请在冰豆网上搜索。

校园打铃系统的设计.docx

校园打铃系统的设计

 

嵌入式系统综合设计实训报告

——校园打铃系统的设计

 

校园打铃系统的设计

一、实训目的

1、设计一个校园打铃系统,使用的是24小时计时制,能够设置多个打铃时间,同时要求能够在系统掉电时,时间能够继续,打铃时间的数据能够保持。

2、掌握LCD1602、DS1302、DS18b20、AT24C02等相关知识

3、进一步了解时钟电路、复位电路、工作电源电路、程序存储器选择电路

二、实训内容

1、时钟功能:

能显示年、月、日、星期、时、分、秒、温度等信息

2、调整功能:

能校正年、月、日、时、分、秒、星期等信息

3、打铃功能:

按指定的时间发出声音,并且闪光

4、设置的作息时间数据在单片机掉电后不会丢失

三、实训整体框图

图1系统总体设计图

四、各功能模块介绍

1、最小系统

单片机最小系统包括单片机(STC89C52)、时钟电路、复位电路、工作电源电路、程序存储器选择电路五个部分。

2、时钟模块DS1302

DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。

实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。

工作电压宽达2.5~5.5V。

采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。

3、存储模块AT24C02

AT24C02提供2k位的串行电可擦写可编程只读存储器(EEPROM),组织形式为256字×8位字长,采用IIC总线接口。

4、温度采集模块DS18B20

DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。

因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。

5、打铃模块

采用蜂鸣器和LED指示灯作为系统打铃的声光报警器。

6、液晶显示模块LCD1602

LCD1602液晶显示器可以显示2行16列,共32个字符。

7、键盘输入模块

采用16键的矩阵式键盘,分别定义为0-9的数字键与其他的功能键。

图2矩阵式键盘

8、LCD1602显示介面设计

2

0

1

1

-

0

8

-

2

2

S

u

n

2

3

1

2

4

9

±

2

6

.

7

º

C

当前时间显示介面(“♫”为打铃标志符号)

2

0

1

1

-

0

8

-

2

2

S

u

n

2

3

1

2

4

9

±

2

6

.

7

º

C

修改时间显示介面

S

e

t

u

p

r

i

n

g

b

e

l

l

t

i

m

e

r

0

1

2

3

1

2

4

9

设置打铃时间显示介面

9、矩阵键盘功能划分

●“15”键:

界面切换功能,能够依次显示主界面、修改时间界面、打铃时间界面

●“14”键:

保存修改后的时间

●“12”键:

关闭响铃

10、系统流程图

 

五、程序代码

以下代码实现的功能是:

◆能够显示年月日、时分秒、星期、温度

◆能够修改小时、分钟、秒钟并且保存修改的时间

◆能够设置打铃时间,到设置的时间时蜂鸣器发出响声,设定为响10s,小灯亮。

1、zdy.h

inta,b,T;//自定义的变量

2、ds18b20.h

#include

sbitDQ=P2^2;//DQ的控制位

voiddelay5us(void)//延时5微秒

{

_nop_();

}

voiddelay1(intx)//x=(1.20us,2.28us,3.36us,5.52us,50.412us,60.492us,65.535us)

{

unsignedinti;

for(i=0;i

}

//初始化,主机发送复位脉冲,从机如果存在则发送存在的应答脉冲

bitrst1bus(void)

{

bitf;

DQ=1;//准备阶段

DQ=0;//将DQ线拉低

delay1(65);//延时500us,主机发送复位脉冲:

480us至960us的低电平

DQ=1;//将DQ线拉高

delay1(3);//延时40us;//主机释放总线:

15us至60us的高电平

f=DQ;//从机如果存在则60us至240us内回复低电平

delay1(10);//延时100us;

DQ=1;

delay1(40);//延时350us;//结束阶段

return(f);//f=0:

从设备存在;f=1:

从设备不存在

}

//位写入函数:

每次写1位数据

voidwritebit(bitx)

{

DQ=1;//准备阶段

DQ=0;

_nop_();//延时2us,主机发送15us的低电平

_nop_();

DQ=x;

delay1(6);//延时60us,从机DS18B20在至少60us内完成采样

DQ=1;//结束阶段

_nop_();//延时1us;

}

//写字节函数:

每次写8位数据,即1字节数据;低位在前,高位在后

voidwritebyte(unsignedcharx)

{

bitf;

unsignedchari;

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

{

f=(bit)(x&0x01);

x=x>>1;

writebit(f);//写1位数据;低位在前,高位在后

}

}

//位读出函数:

每次读1位数据

bitreadbit(void)

{

bitf;

DQ=1;//准备阶段

DQ=0;//1us的低电平

_nop_();//延时2us;

_nop_();

DQ=1;//线与的条件

delay5us();//延时10us;//主机释放总线15us

delay5us();

f=DQ;//主机采样DS18B20的线与运算

delay1(4);//延时45us;

DQ=1;//结束阶段

_nop_();//延时1us;

return(f);

}

//读字节函数:

每次读8位数据,即1字节数据;低位在前,高位在后

//返回值为单字节变量

unsignedcharreadbyte(void)

{

bitf;

unsignedchari,x=0;

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

{

x=x>>1;

f=readbit();

if(f==1)

x=x|0x80;//读1位数据;低位在前,高位在后

}

return(x);

}

voidds18b20(void)

{

unsignedcharf1,f2,g;

f1=rst1bus();//将DS18B20的初始化赋给f1

if(f1==0)//f==0有设备存在,复位成功

{

writebyte(0xcc);//跳跃ROM指令

writebyte(0x44);//发送温度转换指令

g=readbit();

while(!

g)

{

g=readbit();//为0,还没转换完成;为1:

温度转换完成

}

f2=rst1bus();//第二次将DS18B20的初始化赋给f2

if(f2==0)//f==0有设备存在,复位成功

{

writebyte(0xcc);//跳跃ROM指令

writebyte(0xBE);//发送读取RAM指令

a=readbyte();//读低八位

b=readbyte();//读高八位

}

}

}

3、at24c02.h

sbitsda=P2^0;

sbitscl=P2^1;

unsignedcharcodetable[]={3,5,0,1,1,2,0,3,3,5,0,1,1,1,0,9};

unsignedcharcodetab[]={0x00,0x01,0x02,0x03,0x04,0x05,0x07,0x23,0x12,0x14,0x16,0x34,0x35,0x38,0x44,0x46};

//开始信号

/*SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。

*/

voidi2cstart(void)

{

scl=0;

sda=1;

scl=1;

sda=0;

scl=0;

}

//停止信号

/*SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。

*/

voidi2cstop(void)

{

scl=0;

sda=0;

scl=1;

sda=1;

}

//上升沿写入数据

voidwrite(unsignedcharx)//上升沿写入数据,高位在前,低位在后

{

unsignedchary,i;

y=x;

CY=0;//位信号

scl=0;

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

{

y=y<<1;

sda=CY;//准备数据

scl=1;//上升沿

scl=0;//为第二次发送数据作准备

}

}//scl低电平时,准备好要写入的位数据;scl上升为高电平时,写入一位

//下降沿读出数据

unsignedcharread(void)//下降沿读取数据

{

unsignedcharx,i;

bitf;

x=0;

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

{

sda=1;//主机释放总线,准备接收从机发送的位数据

x=x<<1;//向左移动接收一个信号

scl=1;

f=sda;//读取数据(线与操作)

scl=0;//下降沿

x=x+(unsignedchar)f;//把数据放在x的最低位,接收8位

}

return(x);

}

/*从机应答——主机发送一个数据后,从机在主机发送第9个时钟时应答:

收到,应答0;没收到,应答1*/

bitack(void)

{

bitf;

sda=1;//主机释放总线,准备接收从机的应答

scl=1;

f=sda;//读取数据

scl=0;//下降沿

return(f);//返回的应答信号

}

/*主机应答——从机发送一个数据后,主机在主机发送第9个时钟时应答:

收到并且需要另外的数据,应答0;收到并且不需要另外的数据,应答1*/

voidnoack(bitf)//f为0或者为1

{

sda=f;//准备数据

scl=1;//上升沿

scl=0;

}

//忙检测

/*写操作需要一定的时间,或采用忙检测:

0——完成写;1——正在进行写*/

voidi2cbusy(void)//忙检测

{

bitf;

do

{

i2cstart();//启动信号

write(0xa0);//芯片地址

f=ack();//f=0不忙,f=1正在忙

}while(f);

}

//学字节操作

/*字节写:

x--器件地址;y--单元地址;z--数据*/

voidwriteby(unsignedcharx,unsignedchary,unsignedcharz)

{

i2cstart();//启动信号

write(x&0xfe);//最低位必须为0,芯片地址

ack();//从机应答

write(y);//芯片单元地址

ack();//从机应答

write(z);//写一个具体的数据

ack();//从机应答

i2cstop();//停止信号

i2cbusy();

}

/*随机读操作:

x--器件地址;y--单元地址;返回读取的数据*/

unsignedcharrandomread(unsignedcharx,unsignedchary)//随机读操作

{

unsignedcharz;

i2cstart();

write(x&0xfe);//最低位必须为0(假的写操作)

ack();//从机应答

write(y);

ack();//从机应答

//伪写操作

i2cstart();

write(x|0x01);//最低位必须为1

ack();//从机应答

z=read();

noack

(1);//主机应答(1--不需要其他数据)

i2cstop();

return(z);

}

4、lcd1602.h

sbitLcdRS=P1^0;//寄存器选择高-->数据存储器,低-->指令存储器

sbitLcdRW=P1^1;//读写操作高-->读操作,低-->写操作

sbitLcdEN=P2^5;//片选高电平/下降沿触发

sfrLcdIO=0x80;

voiddelay(void)//延时

{

inti,j;

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

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

}

//写指令(RS=0,RW=0,EN=下降沿触发)

voidwritecom(unsignedcharx)

{

//准备阶段

LcdRS=1;

LcdRW=1;

LcdEN=0;

//运行阶段

LcdRS=0;

LcdRW=0;

LcdEN=1;

LcdIO=x;

delay();

LcdEN=0;

//结束阶段

LcdRS=1;

LcdRW=1;

LcdEN=0;

}

//写数据(RS=1,RW=0,EN=下降沿触发)

voidwritedate(unsignedcharx)

{

//准备阶段

LcdRS=0;

LcdRW=1;

LcdEN=0;

//运行阶段

LcdRS=1;

LcdRW=0;

LcdEN=1;

LcdIO=x;

delay();

LcdEN=0;

//结束阶段

LcdRS=0;

LcdRW=1;

LcdEN=0;

}

//读状态(RS=0,RW=1,EN=1)

unsignedcharreadsta()

{

//准备阶段

unsignedcharx;

LcdRS=1;

LcdRW=0;

LcdEN=0;

//运行阶段

LcdRS=0;

LcdRW=1;

LcdEN=1;

x=LcdIO;

delay();

//结束阶段

LcdRS=1;

LcdEN=0;

LcdRW=0;

return(x);

}

//忙检测

voidbusy(void)//忙检测

{

unsignedchary;

bitf;

y=readsta();

f=(bit)(y>>7);//强制转换

while(f==1)//忙检测

{

y=readsta();

f=(bit)(y>>7);

}

}

voidlcd1602()

{

busy();

writecom(0x38);//设置5*716行2列显示屏

busy();

writecom(0x08);//清屏显示:

busy();

writecom(0x01);//设置显示:

光标打开

busy();

writecom(0x06);//设置指针加1

busy();

writecom(0x0c);//清屏显示:

}

5、key.h

unsignedcharkey0()

{

unsignedchari=0,x=0;

while(i<1)

{

P3=0xfe;//控制扫描哪一行行(11111110)

x=P3;

x=x&0xf0;//e用来判断按键的按下(是用来取高四位)

if(x!

=0xf0)//表示有按键按下进入按键赋值状态

{

x=P3;

break;

}

i=i+1;

}

returnx;

}

unsignedcharkey1()

{

unsignedchari=0,x=0;

while(i<1)

{

P3=0xfd;//控制扫描哪一行行(11111101)

x=P3;

x=x&0xf0;//e用来判断按键的按下(是用来取高四位)

if(x!

=0xf0)//表示有按键按下进入按键赋值状态

{

x=P3;

break;

}

i=i+1;

}

returnx;

}

unsignedcharkey2()

{

unsignedchari=0,x=0;

while(i<1)

{

P3=0xfb;//控制扫描哪一行行(11111011)

x=P3;

x=x&0xf0;//e用来判断按键的按下(是用来取高四位)

if(x!

=0xf0)//表示有按键按下进入按键赋值状态

{

x=P3;

break;

}

i=i+1;

}

returnx;

}

unsignedcharkey3()

{

unsignedchari=0,x=0;

while(i<1)

{

P3=0xf7;//控制扫描哪一行行(11110111)

x=P3;

x=x&0xf0;//e用来判断按键的按下(是用来取高四位)

if(x!

=0xf0)//表示有按键按下进入按键赋值状态

{

x=P3;

break;

}

i=i+1;

}

returnx;

}

unsignedchargetkey(void)//获取按键值

{

unsignedchark0,k1,k2,k3,answer=16;

intb=0;

if(b==0)

{

k0=key0();

k1=key1();

k2=key2();

k3=key3();

switch(k0)

{

case0xee:

answer=0;break;

case0xde:

answer=1;break;

case0xbe:

answer=2;break;

case0x7e:

answer=3;break;

}

switch(k1)

{

case0xed:

answer=4;break;

case0xdd:

answer=5;break;

case0xbd:

answer=6;break;

case0x7d:

answer=7;break;

}

switch(k2)

{

case0xeb:

answer=8;break;

case0xdb:

answer=9;break;

case0xbb:

answer=10;break;

case0x7b:

answer=11;break;

}

switch(k3)

{

case0xe7:

answer=12;break;

case0xd7:

answer=13;break;

case0xb7:

answer=14;break;

case0x77:

answer=15;break;

}

if(answer!

=16)

returnanswer;//表示按下的键是哪一个

else

return16;//表示没有按键按下

}

}

6、ds1302.h

#definesecond0x80//秒钟寄存器地址

#defineminute0x82//分钟寄存器地址

#definehour0x84//小时寄存器地址

#definedate0x86//日期寄存器地址

#definemouth0x88//月寄存器地址

#defineweekday0x8a//星期寄存器地址

#defineyear0x8c//年寄存器地址

#defineprotect0x8e//写保护寄存器地址

#definechange0x90//充电寄存器地址

sbitrst=P2^4;

sbitsclk=P2^1;

sbitio=P2^0;

unsignedcharcodetab3[2][17]={"Setupringbell","timer0000:

00:

00"};

unsignedcharcodetab1[]={0x00,0x01,0x02,0x03};//自定义字符数据地址

unsignedcharcodetab0[]={0x0f,0x1f,0x02,0x0f,0x0a,0x1f,0x02,0x00,0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x00,0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00,0x00,0x0f,0x09,0x09,0x09,0x09,0x1b,0x1b};

unsignedchartab2[2][17]={"2013-09-03W2","23:

59:

50+28.5C"};//固定显示数字

unsignedchars[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//定义显示0-9和显示“.”

unsignedchara1=0;

//写函数

voidwrite_ds1302(unsignedcharx)//有一个参数,无返回值

{

unsignedchari;

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

{

sclk=0;

io=(bit)(x&01);//

x=x>>1;//xzouyiyiwei

sclk=1;//

}

}

//读函数

unsignedcharread_ds1302(void)//无参数,有返回值

{

inti;

uns

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

当前位置:首页 > 初中教育 > 科学

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

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