单片机实训二程序课室打铃控制系统Word文档格式.docx

上传人:b****6 文档编号:19531777 上传时间:2023-01-07 格式:DOCX 页数:16 大小:20.12KB
下载 相关 举报
单片机实训二程序课室打铃控制系统Word文档格式.docx_第1页
第1页 / 共16页
单片机实训二程序课室打铃控制系统Word文档格式.docx_第2页
第2页 / 共16页
单片机实训二程序课室打铃控制系统Word文档格式.docx_第3页
第3页 / 共16页
单片机实训二程序课室打铃控制系统Word文档格式.docx_第4页
第4页 / 共16页
单片机实训二程序课室打铃控制系统Word文档格式.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

单片机实训二程序课室打铃控制系统Word文档格式.docx

《单片机实训二程序课室打铃控制系统Word文档格式.docx》由会员分享,可在线阅读,更多相关《单片机实训二程序课室打铃控制系统Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。

单片机实训二程序课室打铃控制系统Word文档格式.docx

unsignedchardataflag,vkey,skey;

//设置状态计数标志、按键先前值、按键当前值

bitalarm;

//标识是否启用闹钟,1--启用,0--关闭

sbitrs=P2^6;

//LCD数据/命令选择端(H/L)

sbitrw=P2^5;

//LCD读/写选择端(H/L)

sbitep=P2^7;

//LCD使能控制

sbitPRE=P1^6;

//调整键(k3)杜邦线将P1.6接到独立按键

sbitSET=P1^7;

//调整键(k4)杜邦线将P1.7接到独立按键

sbitSPK=P1^5;

//蜂鸣器

voiddelayms(unsignedcharms);

//延时程序

bitlcd_busy();

//测试LCD忙碌状态程序

voidlcd_wcmd(charcmd);

//写入指令到LCD程序

voidlcd_wdat(chardat);

//写入数据到LCD程序

voidlcd_pos(charpos);

//LCD数据指针位置程序

voidlcd_init();

//LCD初始化设定程序

voidpro_timedate();

//时间日期处理程序

voidpro_display();

//显示处理程序

voidpro_key();

//按键处理程序

voidtime_alarm();

//定时报警功能(闹钟)

unsignedcharscan_key();

//按键扫描程序

unsignedcharweek_proc();

//星期自动计算与显示函数

bitleap_year();

//判断是否为闰年

voidlcd_sef_chr();

//LCD自定义字符程序

voidupdate_disbuf(unsignedchart1,unsignedchart2[],unsignedchardis_h,unsignedchardis_m,unsignedchardis_s);

//更新显示缓冲区函数

//延时程序

voiddelay(unsignedcharms)

{while(ms--)

{unsignedchari;

for(i=0;

i<

250;

i++)

{

_nop_();

//执行一条_nop_()指令为一个机器周期

}

}

//测试LCD忙碌状态

bitlcd_busy()

{

bitresult;

rs=0;

rw=1;

ep=1;

result=(bit)(P0&

0x80);

//LCD的D0--D7中,D7=1为忙碌,D7=0为空闲

ep=0;

returnresult;

//写入指令到LCD

voidlcd_wcmd(charcmd)

while(lcd_busy());

//当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写指令

rw=0;

P0=cmd;

//写入数据到LCD

voidlcd_wdat(chardat)

//当lcd_busy为1时,再次检测LCD忙碌状态,lcd-busy为0时,开始写数据

rs=1;

P0=dat;

//LCD数据指针位置程序

voidlcd_pos(charpos)

lcd_wcmd(pos|0x80);

//数据指针=80+地址码(00H~27H,40H~67H)

//设定二个自定义字符,(注意:

LCD1602中自定义字符的地址为0x00--0x07,即可定义8个字符)

//这里我们设定把一个自定义字符放在0x00位置(000),另一个放在0x01位子(001)

voidlcd_sef_chr()

{//第一个自定义字符

lcd_wcmd(0x40);

//"

01000000"

第1行地址(D7D6为地址设定命令形式D5D4D3为字符存放位置(0--7),D2D1D0为字符行地址(0--7))

lcd_wdat(0x1f);

XXX11111"

第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭)

lcd_wcmd(0x41);

01000001"

第2行地址

lcd_wdat(0x11);

XXX10001"

第2行数据

lcd_wcmd(0x42);

01000010"

第3行地址

lcd_wdat(0x15);

XXX10101"

第3行数据

lcd_wcmd(0x43);

01000011"

第4行地址

第4行数据

lcd_wcmd(0x44);

01000100"

第5行地址

第5行数据

lcd_wcmd(0x45);

01000101"

第6行地址

lcd_wdat(0x0a);

XXX01010"

第6行数据

lcd_wcmd(0x46);

01000110"

第7行地址

第7行数据

lcd_wcmd(0x47);

01000111"

第8行地址

lcd_wdat(0x00);

XXX00000"

第8行数据

//第二个自定义字符

lcd_wcmd(0x48);

01001000"

第1行地址

lcd_wdat(0x01);

XXX00001"

第1行数据

lcd_wcmd(0x49);

01001001"

lcd_wdat(0x1b);

XXX11011"

lcd_wcmd(0x4a);

01001010"

lcd_wdat(0x1d);

XXX11101"

lcd_wcmd(0x4b);

01001011"

lcd_wdat(0x19);

XXX11001"

lcd_wcmd(0x4c);

01001100"

lcd_wcmd(0x4d);

01001101"

lcd_wcmd(0x4e);

01001110"

lcd_wcmd(0x4f);

01001111"

第8行数据

//LCD初始化设定

voidlcd_init()

lcd_wcmd(0x38);

//设置LCD为16X2显示,5X7点阵,八位数据借口

delay

(1);

lcd_wcmd(0x0c);

//LCD开显示及光标设置(光标不闪烁,不显示"

-"

lcd_wcmd(0x06);

//LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)

lcd_wcmd(0x01);

//清除LCD的显示内容

//闰年的计算

bitleap_year()

bitleap;

if((year%4==0&

&

year%100!

=0)||year%400==0)//闰年的条件

leap=1;

else

leap=0;

returnleap;

//星期的自动运算和处理

unsignedcharweek_proc()

{unsignedcharnum_leap;

unsignedcharc;

num_leap=year/4-year/100+year/400;

//自00年起到year所经历的闰年数

if(leap_year()&

month<

=2)//既是闰年且是1月和2月

c=5;

c=6;

week=(year+para_month[month]+date+num_leap+c)%7;

//计算对应的星期

returnweek;

//更新显示缓冲区

voidupdate_disbuf(unsignedchart1,unsignedchart2[],unsignedchardis_h,unsignedchardis_m,unsignedchardis_s)

{dis_buf1[0]=t1;

//

dis_buf1[1]=0x20;

//空格

dis_buf1[2]=50;

//'

2'

dis_buf1[3]=48;

0'

dis_buf1[4]=year/10+48;

dis_buf1[5]=year%10+48;

dis_buf1[6]=0x2d;

dis_buf1[7]=month/10+48;

dis_buf1[8]=month%10+48;

dis_buf1[9]=0x2d;

-'

dis_buf1[10]=date/10+48;

dis_buf1[11]=date%10+48;

dis_buf1[12]=0x20;

dis_buf1[13]=dis_week[4*week];

dis_buf1[14]=dis_week[4*week+1];

dis_buf1[15]=dis_week[4*week+2];

dis_buf2[0]=t2[0];

dis_buf2[1]=t2[1];

dis_buf2[2]=t2[2];

dis_buf2[3]=t2[3];

dis_buf2[4]=t2[4];

dis_buf2[5]=t2[5];

dis_buf2[6]=0x20;

if(alarm)

dis_buf2[7]=0x01;

//alarm=1,显示闹钟启用标致(第二个自定义字符)

dis_buf2[7]=0x20;

//alarm=0,不显示闹钟启用标致

dis_buf2[8]=dis_h/10+48;

dis_buf2[9]=dis_h%10+48;

dis_buf2[10]=0x3a;

:

'

dis_buf2[11]=dis_m/10+48;

dis_buf2[12]=dis_m%10+48;

dis_buf2[13]=0x3a;

dis_buf2[14]=dis_s/10+48;

dis_buf2[15]=dis_s%10+48;

//时间和日期处理程序

voidpro_timedate()

sec++;

if(sec>

59)

{sec=0;

min++;

if(min>

59)

{min=0;

hour++;

if(hour>

23)

{hour=0;

date++;

if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)

if(date>

31){date=1;

month++;

}//大月31天

if(month==4||month==6||month==9||month==11)

30){date=1;

}//小月30天

if(month==2)

{if(leap_year())//闰年的条件

{if(date>

29){date=1;

}}//闰年2月为29天

28){date=1;

}}//平年2月为28天

if(month>

12){month=1;

year++;

if(year>

99)year=0;

week_proc();

if(sec==armsec&

min==armmin&

hour==armhour)

{if(alarm)

TR1=1;

//闹钟启用时,报警时间到,启动Timer1

//显示处理程序

voidpro_display()

{unsignedchari;

lcd_pos(0x00);

for(i=0;

i<

=15;

i++)

{lcd_wdat(dis_buf1[i]);

lcd_pos(0x40);

{lcd_wdat(dis_buf2[i]);

//Timer0中断处理程序,秒的产生

voidtimer0()interrupt1

TH0=0xdc;

//Timer0置10ms定时初值dc00H(2^16=65536D,dc00H=56320D)

TL0=0x00;

//定时时间=(65536-56320)*(1/11.0592)*12=10ms(f0=11.0592Mhz)

sec100++;

if(sec100>

=100)//1秒时间(100*10ms=1000ms=1s)

{sec100=0;

pro_timedate();

//调用时间和日期处理程序

if(sec&

0x01)//"

willar"

闪一秒,停一秒

update_disbuf(0x00,"

"

hour,min,sec);

//0x00表示显示00位置的自定义字符

pro_display();

//调用显示处理函数

//按键扫描程序

unsignedcharscan_key()

skey=0x00;

//给变量vkey置初值

skey|=PRE;

//读取PRE键的状态

skey=skey<

<

1;

//将PRE键的状态存于skey的B1位

skey|=SET;

//读取SET键的状态,并存于skey的B0位

returnskey;

//返回skey的键值(即PRE,SET的状态)

//外部中断INT0中断处理程序

voidint0()interrupt0

TR0=0;

//禁止Timer0

IE=0;

//禁止中断

lcd_wcmd(0x0e);

//显示光标"

_"

整个光标不闪烁

alarm=1;

update_disbuf(0x50,"

alarm:

"

armhour,armmin,armsec);

//更新显示数据,0x50表示要显示"

P"

//调用显示处理程序

lcd_pos(0x47);

//使光标位于第一个调整项下

flag=0;

vkey=0x03;

while(flag^0x0a)

{skey=scan_key();

//扫描按键状态

if(skey^vkey)//若skey与vkey相同,跳出循环,相异执行循环体

{delay(10);

//去按键抖动

skey=scan_key();

//转回扫描按键状态

if(skey^vkey)//若skey与vkey相同,跳出循环,相异执行循环体{vkey=skey;

//将skey的值付给vkey

if(skey==0x01)//PRE键按下

{flag++;

//调整标志位加1

switch(flag)//将光标置于相应调整位置

case1:

lcd_pos(0x49);

break;

//光标置小时报警设置位置

case2:

lcd_pos(0x4c);

//光标置分钟报警设置位置

case3:

lcd_pos(0x4f);

//光标置秒时报警设置位置

case4:

time:

lcd_pos(0x05);

//光标置年调整位置

case5:

lcd_pos(0x08);

//光标置月调整位置

case6:

lcd_pos(0x0b);

//光标置日调整位置

case7:

//光标置时调整位置

case8:

//光标置分调整位置

case9:

//光标置秒调整位置

default:

if(skey==0x02)//SET键按下

{pro_key();

//转设置按键处理程序

//设置LCD开显示及光标不闪烁,不显示"

IE=0x8f;

//CPU开中断,INT0,INT1,开中断

TR0=1;

//Timer0启动

//主程序,初始化及初值设定

voidmain()

{lcd_init();

//初始化LCD

lcd_sef_chr();

//写入自定义字符号

hour=0;

min=0;

sec=0;

//开机时的时,分,秒显示

armhour=0;

armmin=0;

armsec=0;

//开机时的时,分,秒报警初值

year=5;

month=1;

date=1;

//开机时的年,月,日,星期显示

//初始开机,启用闹钟

IE=0x8f;

//CPU开中断,INT0,INT1,Timer0,Timer1开中断

IP=0x04;

//设置INT0为中断最高优先级

IT0=0;

IT1=0;

//外部INT0,INT1设置为电平触发方式(注意,触发不要选边沿方式,易误动)

TMOD=0x11;

//Timer0,Timer1工作于模式1,16位定时方式

TH0=0xdc;

TL0=0x00;

//Timer0置10ms定时初值

TH1=0xff;

TL1=0x00;

//Timer1置初值

TR0=1;

TR1=0;

while

(1);

}//设置按键处理程序

voidpro_key()

{switch(flag)

case0:

alarm=!

alarm;

//启用或关闭闹钟(alarm=1:

启用,alarm=0:

关闭)

//更新显示数据

//调用显示处理

//光标回到原调整位置case1:

armhour++;

if(armhour>

23)armhour=0;

pr

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

当前位置:首页 > 总结汇报 > 学习总结

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

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