单片机课程设计多功能定时器Word

单片机课程设计多功能定时器Word
单片机课程设计多功能定时器Word

一、设计目的:

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"

void KeyDelay(unsigned int KeyJsTime); //键盘扫描延时函数声明

unsigned char GetKey(); //扫描后获取键值

unsigned char GetKey()

{

static unsigned char KeyHaveFree=1;

static unsigned int KeyJs=0;

unsigned char temp,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)

{

case 0x0e:KeyTemp=3;break;

case 0x0d:KeyTemp=7;break;

case 0x0b:KeyTemp=11;break;

case 0x07:KeyTemp=15;break;

case 0x0f:break;

default:KeyTemp= 0x80;break;

}

P2&=0xf0;

P2|=0x0d;

switch(P1&0x0f)

{

case 0x0e:KeyTemp= 2;break;

case 0x0d:KeyTemp= 6;break;

case 0x0b:KeyTemp= 10;break;

case 0x07:KeyTemp= 14;break;

case 0x0f:break;

default:KeyTemp= 0x81;break;

}

P2&=0xf0;

P2|=0x0b;

switch(P1&0x0f)

{

case 0x0e:KeyTemp= 1;break;

case 0x0d:KeyTemp= 5;break;

case 0x0b:KeyTemp= 9;break;

case 0x07:KeyTemp= 13;break;

case 0x0f:break;

default:KeyTemp= 0x82;break;

}

P2&=0xf0;

P2|=0x07;

switch(P1&0x0f)

{

case 0x0e:KeyTemp= 0;break;

case 0x0d:KeyTemp= 4;break;

case 0x0b:KeyTemp= 8;break;

case 0x07:KeyTemp= 12;break;

case 0x0f: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;

}

return KeyTemp;

}

void KeyDelay(unsigned int KeyJsTime)

{

unsigned char temp;

unsigned int JsKeyDelay;

for(JsKeyDelay=0;JsKeyDelay

2、Lcd程序(1602)

#include "aduc848.h"

sbit RS=P3^6;

sbit RW=P3^5;//位定义

sbit EN=P3^3;

void delay(unsigned int z);延时函数声明

void write_com(unsigned char com);LCD显示位置函数声明

void write_data(unsigned char date);写数据函数声明

void init();

{

RS=0;

RW=0;

EN=0;

write_com(0x38);

write_com(0x0f);

write_com(0x06);

}

void delay(unsigned int z) //延时函数延时时间=Z*110

{

unsigned int x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void write_com(unsigned char com) //

{

RS=0;

RW=0;

P0=com;

delay(5);

EN=1;

delay(5);

EN=0;

}

void write_data(unsigned char date) {

RS=1;

RW=0;

P0=date;

delay(5);

EN=1;

delay(5);

EN=0;

}

3、iic程序(RTC)//实时时钟#include"aduc848.h"

void iic_start(void);

void iic_stop(void);

void iic_ack(void);

bit read_ack(void);

void iic_nack();

unsigned char get_byte(void);

void out_byte(unsigned char dd);

void IIC_Delay_us(unsigned int times); void ReadTime(unsigned char TIME[7]); void SetTime(unsigned char TIME[7]); void SwitchRTC(unsigned char SWITCH);

void ReadTime(unsigned char TIME[7]) {

bit EATemp;

unsigned char temp;

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;else temp=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

相关主题
相关文档
最新文档