c51课程设计报告3.docx
- 文档编号:6360546
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:15
- 大小:113.75KB
c51课程设计报告3.docx
《c51课程设计报告3.docx》由会员分享,可在线阅读,更多相关《c51课程设计报告3.docx(15页珍藏版)》请在冰豆网上搜索。
c51课程设计报告3
实验报告
课程名称C51程序设计
专业班级
姓名
学号
电气与信息学院
和谐勤奋求是创新
实验题目
用DS1302与1602LCD设计的可调式电子日历与时钟
实验室
信号实验室
实验时间
年月日
实验类别
设计
同组人数
人
成绩
指导教师签字:
一、实验目的
1.了解和掌握C51程序设计环境(Keil软件)的使用。
2.掌握单片机仿真软件(Proteus)软件的使用。
3.掌握掌握在Keil和Proteus环境下的C51程序设计的基本方法和调试方法。
二.实验内容
按照随提供的电路原理图(Proteus)编制程序完成指定功能。
三实验结果
(1)proteus仿真图
2.程序设计流程图
图1主程序流程图
图2时间调整程序流程图
图2:
调整时间用4个调整按钮,1个作为选择控制用,另外3个分别作为加调整,减调整和确定用。
通过时间调整程序实现对时间的更改。
3.源程序代码
3.程序源代码
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitSDA=P1^0;//DS1302数据线
sbitCLK=P1^1;//DS1302时钟线
sbitRST=P1^2;//DS1302复位线
sbitRS=P2^0;
sbitRW=P2^1;
sbitEN=P2^2;
sbitK1=P3^4;//选择
sbitK2=P3^5;//加
sbitK3=P3^6;//减
sbitK4=P3^7;//确定
voidDisplay_LCD_String(ucharp,uchar*s);
uchartCount=0;//一年中每个月的天数,2月的天数由年份决定
ucharMonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
uchar*WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};//周日,周一到周六
ucharLCD_DSY_BUFFER1[]={"Date00-00-00"};//LCD显示缓冲
ucharLCD_DSY_BUFFER2[]={"Time00-00-00"};
ucharDateTime[7];//所读取的日期时间
charAdjust_Index=-1;//当前调节的时间:
秒,分,时,日,
ucharChange_Flag[]="-MHDM-Y";
ucharRead_LCD_State();
voidLCD_Busy_Wait();
voidWrite_LCD_Data(uchardat);
voidWrite_LCD_Command(ucharcmd);
voidInit_LCD();
voidSet_LCD_POS(ucharp);
voidDelayMS(uintx)
{
uchari;
while(x--)for(i=0;i<120;i++);
}
ucharRead_LCD_State()
{
ucharstate;
RS=0;
RW=1;
EN=1;
DelayMS
(1);
state=P0;
EN=0;
DelayMS
(1);
returnstate;
}
voidLCD_Busy_Wait()
{
while((Read_LCD_State()&0x08)==0x80);
DelayMS(5);
}
voidWrite_LCD_Data(uchardat)//写数据
{
LCD_Busy_Wait();
RS=1;
RW=0;
EN=0;
P0=dat;
EN=1;
DelayMS
(1);
EN=0;
}
voidWrite_LCD_Command(ucharcmd)//写命令
{
LCD_Busy_Wait();
RS=0;
RW=0;
EN=0;
P0=cmd;
EN=1;
DelayMS
(1);
EN=0;
}
voidInit_LCD()//LCD初始化
{
Write_LCD_Command(0x38);DelayMS
(1);
Write_LCD_Command(0x01);DelayMS
(1);
Write_LCD_Command(0x06);DelayMS
(1);
Write_LCD_Command(0x0C);DelayMS
(1);
Display_LCD_String(0x00,"zhongzhoudaxue");
//DelayMS(1000);
Display_LCD_String(0x40,"dianzirili");
DelayMS(2000);
}
voidSet_LCD_POS(ucharp)
{
Write_LCD_Command(p|0x80);
}
voidDisplay_LCD_String(ucharp,uchar*s)
{
uchari;
Set_LCD_POS(p);
for(i=0;i<16;i++)
{
Write_LCD_Data(s[i]);
DelayMS
(1);
}
}
向DS1302写入一字节
voidDS1302_Write_Byte(ucharx)
{
uchari;
for(i=0;i<8;i++)
{
SDA=x&1;
CLK=1;
CLK=0;
x>>=1;
}
}
/*-------------------------------
从DS1302读取一字节
--------------------------------*/
ucharDS1302_Read_Byte()
{
uchari,b,t;
for(i=0;i<8;i++)
{
b>>=1;
t=SDA;
b|=t<<7;
CLK=1;
CLK=0;
}
returnb/16*10+b%16;
}
从DS1302指定位置数据
ucharRead_Data(ucharaddr)
{
uchardat;
RST=0;
CLK=0;
RST=1;
DS1302_Write_Byte(addr);
dat=DS1302_Read_Byte();
CLK=1;
RST=0;
returndat;
}
向DS1302某地址写入数据
voidWrite_DS1302(ucharaddr,uchardat)
{
CLK=0;
RST=1;
DS1302_Write_Byte(addr);
DS1302_Write_Byte(dat);
CLK=0;
RST=0;
}
/*------------------------------------
设置时间
------------------------------------*/
voidSET_DS1302()
{
uchari;
Write_DS1302(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_DS1302(0x80+2*i,(DateTime[i]/10<<4|(DateTime[i]%10)));
}
Write_DS1302(0x8e,0x80);
}
/*------------------------------------
读取当前时期时间
------------------------------------*/
voidGetTime()
{
uchari;
for(i=0;i<7;i++)
{
DateTime[i]=Read_Data(0x81+2*i);
}
}
/*------------------------------------
时间和日期转换成数字字符
------------------------------------*/
voidFormat_DateTime(uchard,uchar*a)
{
a[0]=d/10+'0';a[1]=d%10+'0';
}
/*------------------------------------
判断是否为闰年
------------------------------------*/
ucharisLeapYear(uinty)
{
return(y%4==0&&y%100!
=0)||(y%400==0);
}
/*------------------------------------
星期转换
------------------------------------*/
voidRefreshWeekDay()
{
uinti,d,w=5;
for(i=2000;i<2000+DateTime[6];i++)
{
d=isLeapYear(i)?
366:
365;
w=(w+d)%7;
}
d=0;
for(i=1;i d+=DateTime[3]; DateTime[5]=(w+d)%7+1; } /*------------------------------------ 年月日时分秒++/-- ------------------------------------*/ voidDateTime_Adjust(charx) { switch(Adjust_Index) { case6: //年 if(x==1&&DateTime[6]<99)DateTime[6]++; if(x==-1&&DateTime[6]>0)DateTime[6]--; MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29: 28; if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay(); break; case4: //月 if(x==1&&DateTime[4]<12)DateTime[4]++; if(x==-1&&DateTime[4]>1)DateTime[4]--; MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29: 28; if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay(); break; case3: //日 MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29: 28; if(x==1&&DateTime[3] if(x==-1&&DateTime[3]>0)DateTime[3]--; RefreshWeekDay(); break; case2: //时 if(x==1&&DateTime[2]<23)DateTime[2]++; if(x==-1&&DateTime[2]>0)DateTime[2]--; break; case1: //秒 if(x==1&&DateTime[1]<59)DateTime[1]++; if(x==-1&&DateTime[1]>0)DateTime[1]--; break; } } /*------------------------------------ 定时器每秒刷新LCD显示 ------------------------------------*/ voidT0_INT()interrupt1 { TH0=-50000/256; TL0=-50000%256; if(++tCount! =2)return; tCount=0; Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]); Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); Display_LCD_String(0x00,LCD_DSY_BUFFER1); Display_LCD_String(0x40,LCD_DSY_BUFFER2); } /*------------------------------------ 键盘中断 ------------------------------------*/ voidEX_INT0()interrupt0 { if(K1==0)//选择调整对象: 年,月,日,时,分,秒 { while(K1==0); if(Adjust_Index==-1||Adjust_Index==1)Adjust_Index=7; Adjust_Index--; if(Adjust_Index==5)Adjust_Index=4; LCD_DSY_BUFFER2[13]='['; LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; LCD_DSY_BUFFER2[15]=']'; } else if(K2==0)//加 { while(K2==0);DateTime_Adjust (1); } else if(K3==0)//减 { while(K3==0);DateTime_Adjust(-1); } else if(K4==0)//确定 { while(K4==0); SET_DS1302();//调整后的时间写入DS1302 LCD_DSY_BUFFER2[13]=''; LCD_DSY_BUFFER2[14]=''; LCD_DSY_BUFFER2[15]=''; Adjust_Index=-1; } } voidmain() { Init_LCD();//LCD初始化 IE=0x83;//允许INT0,T0中断 IP=0x01; IT0=0x01; TMOD=0x01; TH0=-50000/256; TL0=-50000%256; TR0=1; while (1) { if(Adjust_Index==-1)GetTime(); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c51 课程设计 报告