整理单片机课程设计多功能定时器.docx
- 文档编号:6101043
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:54
- 大小:155.29KB
整理单片机课程设计多功能定时器.docx
《整理单片机课程设计多功能定时器.docx》由会员分享,可在线阅读,更多相关《整理单片机课程设计多功能定时器.docx(54页珍藏版)》请在冰豆网上搜索。
整理单片机课程设计多功能定时器
一、设计目的:
1、在理论学习的基础上,通过完成一个涉及MCS-51单片机多种资源应用并具有综合功能的小系统目标板的设计与编程应用;
2、能够对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,在软件编程、排错调试、相关仪器设备的使用技能等方面得到较全面的锻炼和提高;
3、使学生增进对单片机的感性认识,加深对单片机理论方面的理解。
使学生掌握单片机的内部功能模块的应用,如定时器/计数器、中断、片内外存贮器、I/O口、串行口通信等;
4、使学生了解和掌握单片机应用系统的软硬件设计过程、方法及实现,为以后设计和实现单片机应用系统打下良好基础。
二、设计功能说明
数字钟是采用数字电路实现对时,分,秒,数字显示的计时装置,由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表,钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表的报时功能。
数字钟已成为人们日常生活中的必需品,本设计可实现如下功能:
1、使用实时时钟芯片写入及读取时间
2、用LCD显示,可显示年、月、日、时、分、秒、星期、农历日期、节日
3、选择蜂鸣器电路,实现两个闹钟设置和事件提示功能
4、实现时钟校正功能,12小时/24小时切换功能
5、显示当前时间为上午时间或下午时间
6、整点报时功能
按键功能如下:
1、对显示时间的设置
按键0:
进入设置模式,实现秒(S)、分(M)、时(H)、年(Y)、月(m)、日(D)、星期(W)设置的切换,并在LCD右下角显示所设置的项目,当各项目设置完毕后,再按下按键0则返回主界面正常显示时间;
按键1:
每按一次按键1,对所设置的时间加1,当设置的时间超过它的最大值时,该项自动为0,例如:
当设置秒为59时,秒自动清零;
按键2:
每按一次按键:
2,对所设置的时间减1,当设置的时间小于0时,该项自动为它的最大值;
按键3:
设置完成后的确认键并可按此键中途退出设置,时间按用户设置值正常计时;
按键7:
实现时钟校正功能,12小时/24小时切换功能。
2、对闹钟的设置
按键4:
进入闹钟1的设置,并在LCD右上方显示“CLOCK1”并通过按键0、1、2设置用户所需闹钟时间,完成闹钟1的设置后,通过按键0进入闹钟2的设置,并在LCD右上方显示“CLOCK2”,若无需设置闹钟2,则通过按键3退出闹钟设置,返回主界面正常显示时间;
按键5:
设置闹钟是否开启,例如:
当设置闹钟1为开启状态时,在LCD右上方显示“*CLOCK1”当闹钟,并在返回主界面后显示“C1”表示闹钟1开启;
三、整体设计思路
这部分主要介绍工作安排和整体设计的思想。
工作过程规划如下:
四、主程序流程图
五、电气原理图(见附图)
六、实验程序
1、键盘程序(Keyprocess)
键盘与848相连接,采用矩阵键盘的方式P2用于列扫描,P1用于行扫描,经过消抖及等待键释放的程序,将最终正确的结果置于getkey();程序实现如下:
#include"aduc848.h"
voidKeyDelay(unsignedintKeyJsTime);//键盘扫描延时函数声明
unsignedcharGetKey();//扫描后获取键值
unsignedcharGetKey()
{
staticunsignedcharKeyHaveFree=1;
staticunsignedintKeyJs=0;
unsignedchartemp,KeyTemp=0xff;
P1&=0xf0;
P2&=0xf0;//将低四位置零做I/O口
temp=P1&0x0f;
if(KeyHaveFree)
{
if(temp!
=0x0f)
{
KeyDelay(1000);//延时消除抖动
if(temp==(P1&0x0f))//延时后确认是否有键按下,并获取具体键值
{
P2|=0x0e;
switch(P1&0x0f)
{
case0x0e:
KeyTemp=3;break;
case0x0d:
KeyTemp=7;break;
case0x0b:
KeyTemp=11;break;
case0x07:
KeyTemp=15;break;
case0x0f:
break;
default:
KeyTemp=0x80;break;
}
P2&=0xf0;
P2|=0x0d;
switch(P1&0x0f)
{
case0x0e:
KeyTemp=2;break;
case0x0d:
KeyTemp=6;break;
case0x0b:
KeyTemp=10;break;
case0x07:
KeyTemp=14;break;
case0x0f:
break;
default:
KeyTemp=0x81;break;
}
P2&=0xf0;
P2|=0x0b;
switch(P1&0x0f)
{
case0x0e:
KeyTemp=1;break;
case0x0d:
KeyTemp=5;break;
case0x0b:
KeyTemp=9;break;
case0x07:
KeyTemp=13;break;
case0x0f:
break;
default:
KeyTemp=0x82;break;
}
P2&=0xf0;
P2|=0x07;
switch(P1&0x0f)
{
case0x0e:
KeyTemp=0;break;
case0x0d:
KeyTemp=4;break;
case0x0b:
KeyTemp=8;break;
case0x07:
KeyTemp=12;break;
case0x0f:
break;
default:
KeyTemp=0x83;break;
}
KeyHaveFree=0;//LCDPrintNumber(6,11,5,KeyTemp);
}
}
}
else
{
KeyJs++;
if(KeyJs>70)
{
KeyHaveFree=1;
KeyJs=66;
}
if(temp==0x0f){KeyHaveFree=1;KeyJs=0;}
KeyTemp=0xf0;
}
returnKeyTemp;
}
voidKeyDelay(unsignedintKeyJsTime)
{
unsignedchartemp;
unsignedintJsKeyDelay;
for(JsKeyDelay=0;JsKeyDelay } 2、Lcd程序(1602) #include"aduc848.h" sbitRS=P3^6; sbitRW=P3^5;//位定义 sbitEN=P3^3; voiddelay(unsignedintz);延时函数声明 voidwrite_com(unsignedcharcom);LCD显示位置函数声明 voidwrite_data(unsignedchardate);写数据函数声明 voidinit(); P3: 控制位P0: 数据位 RW=0: 写允许RW=1: 读允许 RS=0: 写地址RS=1: 写数据 P0口=com: P0口输出显示位置的地址 P0口=data: P0口输出数据的地址 EN=1: 从1602显示到LCD屏 EN=0: 关掉显示以便显示下一个数据 voidinit()//初始化 { RS=0; RW=0; EN=0; write_com(0x38); write_com(0x0f); write_com(0x06); } voiddelay(unsignedintz)//延时函数延时时间=Z*110 { unsignedintx,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } voidwrite_com(unsignedcharcom)// { RS=0; RW=0; P0=com; delay(5); EN=1; delay(5); EN=0; } voidwrite_data(unsignedchardate) { RS=1; RW=0; P0=date; delay(5); EN=1; delay(5); EN=0; } 3、iic程序(RTC)//实时时钟 #include"aduc848.h" voidiic_start(void); voidiic_stop(void); voidiic_ack(void); bitread_ack(void); voidiic_nack(); unsignedcharget_byte(void); voidout_byte(unsignedchardd); voidIIC_Delay_us(unsignedinttimes); voidReadTime(unsignedcharTIME[7]); voidSetTime(unsignedcharTIME[7]); voidSwitchRTC(unsignedcharSWITCH); voidReadTime(unsignedcharTIME[7]) { bitEATemp; unsignedchartemp; EATemp=EA; iic_start(); out_byte(0xd0); read_ack(); out_byte(0x00); read_ack(); iic_stop(); IIC_Delay_us (1); iic_start(); out_byte(0xd1); read_ack(); TIME[0]=get_byte(); iic_ack(); TIME[1]=get_byte(); iic_ack(); TIME[2]=get_byte(); iic_ack(); TIME[3]=get_byte(); iic_ack(); TIME[4]=get_byte(); iic_ack(); TIME[5]=get_byte(); iic_ack(); TIME[6]=get_byte(); iic_nack(); iic_stop(); IIC_Delay_us (1); TIME[0]=((TIME[0]&0x7f)>>4)*10+(TIME[0]&0x0f);//second TIME[1]=((TIME[1]&0x7f)>>4)*10+(TIME[1]&0x0f);//minute if(TIME[2]&0x40) { if(TIME[2]&0x20)temp=0x80;elsetemp=0x40; TIME[2]=((TIME[2]&0x1f)>>4)*10+(TIME[2]&0x0f);//hour TIME[2]|=temp; } else { TIME[2]=((TIME[2]&0x3f)>>4)*10+(TIME[2]&0x0f); } TIME[3]=TIME[3]&0x07;//week TIME[4]=((TIME[4]&0x3f)>>4)*10+(TIME[4]&0x0f);//date TIME[5]=((TIME[5]&0x1f)>>4)*10+(TIME[5]&0x0f);//month TIME[6]=(TIME[6]>>4)*10+(TIME[6]&0x0f);//year EA=EATemp; } voidSetTime(unsignedcharTIME[7]) { bitEATemp; unsignedchartemp=0; unsignedcharTimeTemp[7]; EATemp=EA; for(temp=0;temp<7;temp++)TimeTemp[temp]=TIME[temp]; temp=0; TimeTemp[6]=((TimeTemp[6]/10)<<4)+(TimeTemp[6]%10);//Year TimeTemp[5]=((TimeTemp[5]/10)<<4)+(TimeTemp[5]%10);//Month TimeTemp[4]=((TimeTemp[4]/10)<<4)+(TimeTemp[4]%10);//Day TimeTemp[3]=((TimeTemp[3]/10)<<4)+(TimeTemp[3]%10);//Week if((TimeTemp[2]&0xc0)==0x00)//Hour { TimeTemp[2]=((TimeTemp[2]/10)<<4)+(TimeTemp[2]%10); } else { if((TimeTemp[2]&0xc0)==0x01)temp=0x40;elsetemp=0x60; TimeTemp[2]&=0x3f; TimeTemp[2]=((TimeTemp[2]/10)<<4)+(TimeTemp[2]%10); TimeTemp[2]|=temp; } TimeTemp[1]=((TimeTemp[1]/10)<<4)+(TimeTemp[1]%10);//Minute TimeTemp[0]=((TimeTemp[0]/10)<<4)+(TimeTemp[0]%10);//Second TimeTemp[0]&=0x7f; iic_start(); out_byte(0xd0); read_ack(); out_byte(0x00); read_ack(); out_byte(TimeTemp[0]); read_ack(); out_byte(TimeTemp[1]); read_ack(); out_byte(TimeTemp[2]); read_ack(); out_byte(TimeTemp[3]); read_ack(); out_byte(TimeTemp[4]); read_ack(); out_byte(TimeTemp[5]); read_ack(); out_byte(TimeTemp[6]); read_ack(); iic_stop(); IIC_Delay_us (1); EA=EATemp; } voidSwitchRTC(unsignedcharSWITCH) { unsignedchartemp; bitEATemp; EATemp=EA; iic_start(); out_byte(0xd0); read_ack(); out_byte(0x00); read_ack(); iic_stop(); //IIC_Delay_us (1); iic_start(); out_byte(0xd1); read_ack(); temp=get_byte(); iic_nack(); iic_stop(); //IIC_Delay_us (1); if(SWITCH)temp&=0x7f; elsetemp|=0x80; iic_start(); out_byte(0xd0); read_ack(); out_byte(0x00); read_ack(); out_byte(temp); read_ack(); iic_stop(); //IIC_Delay_us (1); EA=EATemp; } voidiic_start(void) { MDE=1; MDO=1; //IIC_Delay_us (2); MCO=1; //IIC_Delay_us (2); MDO=0; //IIC_Delay_us (2); } voidiic_stop(void) { MDE=1; MDO=0; //IIC_Delay_us (2); MCO=1; //IIC_Delay_us (2); MDO=1; } voidiic_ack(void) { MDE=1; MCO=0; MDO=0; //IIC_Delay_us (2); MCO=1; //IIC_Delay_us (2); MCO=0; //IIC_Delay_us (1); MDO=1; } bitread_ack(void) { bitflag; MCO=0; //IIC_Delay_us (2); MDE=1; MDO=1; MCO=1; //IIC_Delay_us (2); MDE=0; flag=MDI; MCO=0; returnflag; } voidiic_nack() { MDE=1; MDO=1; //IIC_Delay_us (2); MCO=1; //IIC_Delay_us (2); MCO=0; } /*********************************************************************************** *函数名: get_byte; *描述: 从IIC总线获取一个字节; *输入: none; *返回值: 一字节数据; *注释: none; ************************************************************************************/ unsignedcharget_byte(void)//输入一个字节 { unsignedchardd; inti; dd=0; MDE=1; MDO=1; MDE=0; for(i=0;i<8;i++) { MCO=0; IIC_Delay_us (1); MCO=1; //IIC_Delay_us (1); dd<<=1; if(MDI)dd|=0x01; } MCO=0; return(dd); } /*********************************************************************************** *函数名: out_byte; *描述: 向IIC总线输出一个字节; *输入: 一字节数据 *返回值: none; *注释: none; ************************************************************************************/ voidout_byte(unsignedchardd)//输出一个字节 { unsignedchari; MDE=1; for(i=0;i<8;i++) { MCO=0; //IIC_Delay_us(0); MDO=(dd&0x80)>>7; IIC_Delay_us (1); MCO=1; //IIC_Delay_us(3); dd<<=1; } MCO=0; } /*********************************************************************************** *函数名: IIC_Delay_us; *描述: IIC总线延时函数; *输入: 延时参数 *返回值: none; *注释: none; ************************************************************************************/ voidIIC_Delay_us(unsignedinttimes) { unsignedinti; unsignedcharDelayJs; for(i=0;i } 4、主程序(Prj6) #include"aduc848.h" #include"KeyProcess.h" #include"rtc.h" #include"LCD1602.h" unsignedcharCurrentTime[7]={55,59,21,6,23,04,11}; unsignedcharClockSetSave1[3]={10,00,22},ClockSetSave2[3]={20,00,22}; unsignedcharcodetable[7]={0x53,0x4d,0x48,0x59,0x6d,0x44,0x57}; unsignedcharcodetable1[4]={0x20,0x53,0x4d,0x48}; unsignedcharKeyValue,ClockKeyValue,shijianzhi=0; unsignedcharSetMode=0; unsignedcharShowMode=0; unsignedcharClock=1,ClockSet=0,FinishClockSet1=0,FinishClockSet2=0,ClockEn1=0,ClockEn2=0; unsignedinti=0; voidKeyProcess(); voidstop() { P1&=0xf0; P2|=0x0f; P2&=0xfe; if((P1&0x08)==0) { P2&=0xfe; } } voidmain() { PLLCON&=0xf8;//设置频率为12.58MHz CFG848|=0x01;//使用片内xram init(); I2CCON=0xE8;//配置IIC为软件主发送模式
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 整理 单片机 课程设计 多功能 定时器