基于凌阳数字电子时钟设计.docx
- 文档编号:4347741
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:25
- 大小:149.23KB
基于凌阳数字电子时钟设计.docx
《基于凌阳数字电子时钟设计.docx》由会员分享,可在线阅读,更多相关《基于凌阳数字电子时钟设计.docx(25页珍藏版)》请在冰豆网上搜索。
基于凌阳数字电子时钟设计
题目:
数字电子时钟(基于SPCE061A凌阳单片机)
一、要求
1、基于凌阳SPCE061A单片机与SPLC501点阵LCD制作一个数字电子钟
2、电子钟计时准确,能准确进位,显示年月日时分秒和星期
3、电子钟可以手动设置时间
二、分析
从题目可以分析出,题目要求电子钟的CPU为凌阳公司的SPCE061A单片机,该款单片机时凌阳科技推出的一款16位结构的微控制器,SPCE061A里内嵌32K字的FLASH,CPU时钟为0.32MHz~49.152MHz,拥有丰富的定时器资源和时基中断源,可以轻松胜任电子时钟的任务。
SPLC501液晶显示模组采用凌阳科技的SPLC501A芯片驱动,拥有128*64点阵,足够显示一个电子时钟的界面。
由于要有准确的计时,因此计时部分采用SPCE061A的2Hz时基中断,每计数2次中断一次,时间加1。
由于时钟的进位有不同的进制,日期上的更是各有不同,因此特别定义一个时间进位函数,当时间产生进位时,调用该函数进行进位计算,避免产生错误时间。
按键控制采用1KHz时基中断来判断按键是否按下,程序中加入了软件去抖动功能。
程序开始时,会在LCD上显示出一个界面,增加系统的美观度。
模组上的液晶显示器采用凌阳科技的SPLC501芯片作为LCD驱动和控制器,为128×64点阵图形。
用单片机的IO口可以很方便的设置某一个点为1,之后就会点亮这一点。
作为一个配套的实验模组,模组里面内置有很多函数,这个电子时钟就是利用其中的LCD501_Bitmap()和LCD501_PutString()函数来显示对应的文字或者字符。
还有一个很方便的工具,就是利用对应的DM字模提取工具,可以获取要显示的数字或者文字在液晶显示模中的数组。
三、设计
1、硬件设计
1.1PLCD501模组的硬件平面图
1.2这是模组的内部设置的点阵图
1.3液晶模组相关配置信息
内置8580位显示RAM。
RAM中的一位数据控制液晶屏上的一个象素点的亮、暗状态。
“1”亮“0”暗。
具有65行驱动输出和132列驱动输出(注:
模组中的液晶显示面板仅为64行、128列)可以直接与80系列和68系列微处理器相连。
内置晶振电路,也可以外接晶振工作温度范围为-40摄氏度~+85摄氏度。
2、软件设计
2.1常用功能函数介绍
液晶显示控制类:
LCD501_Init液晶初始化
LCD501_ClrScreen清屏
LCD501_ReverseColor显示翻转
LCD501_SetPaintMode设置图形显示模式
LCD501_GetPaintMode获取当前显示模式
LCD501_FontSet设置文本字体
LCD501_FontGet获取当前文本字体
LCD501_PutChar显示单个字符
LCD501_PutString显示字符串
LCD501_PutPixel画点
LCD501_Line画直线
LCD501_Circle画圆
LCD501_Rectangle画矩形
LCD501_Bitmap位图显示/汉字显示
SPCE061A与SPLC501的接口采用6800并行接口电路,即8位数据总线、1个读写选通端口、1个数据指令选通端口、1个信号使能端口,具体接法如下图:
按键采用凌阳61板上提供的三个按键,接口电路如下:
2.2软件编程
软件部分由三个部分组成:
主程序部分、2Hz时基中断部分、1KHz时基中断部分,主程序部分主要负责初始化LCD和显示界面,2Hz时基中断部分负责时间的计数,1KHz时基中断部分负责按键的扫描,下面看看这三个程序的流程图:
2.2.1主程序流程图:
1KHz时基中断
2Hz时基中断
2.2.2主要程序及注释:
2.2.2.1时钟计数程序:
//main.c
#include"SPLC501User.h"
#include"Mychar.h"
#include"SPCE061A.h"
intCount_time=0;
intKey_time=0;
unsignedintContr=24;
intSet_mode=0;
structTime//定义时间结构体,存储现在的时间
{
intyear;//年
intmonth;//月
intweek;//周
intday;//日
inthour;//时
intminute;//分
intsecond;//秒
}Clock;
voidClock_Init();
voidClock_Fix();
voidDisp_Time();
constcharclr[]={""};
intmain()
{longintm=100000;
//addyourcodehere
intdly;
LCD501_Init(0x00);
*P_IOA_Dir&=0xfff8;
*P_IOA_Attrib&=0xfff8;
*P_IOA_Data&=0xfff8;
LCD501_Bitmap(32,0,(unsignedint*)encoding_00);//课
LCD501_Bitmap(48,0,(unsignedint*)encoding_01);//程
LCD501_Bitmap(64,0,(unsignedint*)encoding_02);//设
LCD501_Bitmap(80,0,(unsignedint*)encoding_03);//计
LCD501_Bitmap(24,16,(unsignedint*)encoding_04);//计
LCD501_Bitmap(40,16,(unsignedint*)encoding_05);//算
LCD501_Bitmap(56,16,(unsignedint*)encoding_06);//机
LCD501_Bitmap(72,16,(unsignedint*)encoding_07);//接
LCD501_Bitmap(88,16,(unsignedint*)encoding_08);//口
LCD501_Bitmap(16,32,(unsignedint*)encoding_09);//数
LCD501_Bitmap(32,32,(unsignedint*)encoding_0a);//字
LCD501_Bitmap(48,32,(unsignedint*)encoding_0b);//电
LCD501_Bitmap(64,32,(unsignedint*)encoding_0c);//子
LCD501_Bitmap(80,32,(unsignedint*)encoding_0d);//时
LCD501_Bitmap(96,32,(unsignedint*)encoding_0e);//钟
*P_Watchdog_Clear=0x0001;
while(m--)
*P_Watchdog_Clear=0x0001;
Clock_Init();
LCD501_PutString(0,0,clr);
for(dly=0;dly<100;dly++);
LCD501_PutString(0,16,clr);
for(dly=0;dly<100;dly++);
LCD501_PutString(0,32,clr);
for(dly=0;dly<100;dly++);
LCD501_PutString(0,48,clr);
for(dly=0;dly<100;dly++);
LCD501_Bitmap(0,0,(unsignedint*)encoding_15);//邓
LCD501_Bitmap(16,0,(unsignedint*)encoding_16);//中
LCD501_Bitmap(32,0,(unsignedint*)encoding_17);//满
LCD501_PutString(56,0,"08064030");//08064030
LCD501_Bitmap(32,16,(unsignedint*)encoding_18);//年
LCD501_Bitmap(64,16,(unsignedint*)encoding_19);//月
LCD501_Bitmap(96,16,(unsignedint*)encoding_1a);//日
*P_Watchdog_Clear=0x0001;
LCD501_Bitmap(0,34,(unsignedint*)encoding_1b);//北
LCD501_Bitmap(12,34,(unsignedint*)encoding_1c);//京
LCD501_Bitmap(24,34,(unsignedint*)encoding_1d);//时
LCD501_Bitmap(36,34,(unsignedint*)encoding_1e);//间
LCD501_PutChar(46,32,':
');
*P_Watchdog_Clear=0x0001;
LCD501_Bitmap(0,48,(unsignedint*)encoding_13);//星
LCD501_Bitmap(16,48,(unsignedint*)encoding_14);//期
LCD501_PutChar(32,48,':
');
LCD501_Bitmap(80,51,(unsignedint*)encoding_0f);//欢
LCD501_Bitmap(92,51,(unsignedint*)encoding_10);//迎
LCD501_Bitmap(104,51,(unsignedint*)encoding_11);//使
LCD501_Bitmap(116,51,(unsignedint*)encoding_12);//用
*P_Watchdog_Clear=0x0001;
LCD501_PutChar(72,32,':
');
LCD501_PutChar(96,32,':
');
LCD501_PutChar(120,32,'');
LCD501_PutChar(124,32,'');
Disp_Time();
*P_INT_Ctrl=C_IRQ5_2Hz|C_IRQ4_1KHz;
__asm("intirq");
while
(1)
{
*P_Watchdog_Clear=0x0001;
}
return0;
}
voidIRQ4(void)__attribute__((ISR));
voidIRQ5(void)__attribute__((ISR));
voidIRQ4(void)
{
inttime_dly;
intsign=0;
sign=0;//如果为4、6、9、11月,则31日进位,如果为1、3、5、7、8、10、12月,则32日进位,如果为2月,29日进
if(Clock.month==4)
sign=1;
if(Clock.month==6)
sign=1;
if(Clock.month==9)
sign=1;
if(Clock.month==11)
sign=1;
if((*P_INT_Ctrl&C_IRQ4_1KHz)!
=0x0000)
{
*P_INT_Clear=C_IRQ4_1KHz;//清中断
if(Key_time%=50)//20Hz判断按键是否按下
{
if((*P_IOA_Data&0x0007)!
=0x0000)//软件去抖动,
{
for(time_dly=0;time_dly<5000;time_dly++);//去抖动延时,
}
if((*P_IOA_Data&0x0007)!
=0x0000)
{
if((*P_IOA_Data&0x0001)!
=0x0000)//如果按下KEY1
{
Set_mode++;
Set_mode%=8;
}
if((*P_IOA_Data&0x0002)!
=0x0000)//如果按下KEY2
{
if(Set_mode==0)
{
Contr++;
Contr=(Contr>31)?
0:
Contr;
LCD501_SetContrast(Contr);
}
//如果为设置时间模式
if(Set_mode==1)
Clock.year++;
if(Set_mode==2)
{Clock.month++;
if(Clock.month==13)//13月进位
{
Clock.month=1;
}
}
if(Set_mode==3)
{Clock.day++;
if((Clock.month==2)&&(Clock.day==29))//2月29日进位
{
Clock.day=1;
}
if((sign==1)&&(Clock.day==31))
{
Clock.day=1;
}
if((sign==0)&&(Clock.day==32))
{
Clock.day=1;
}
}
if(Set_mode==4)
{Clock.hour++;
if(Clock.hour==24)
Clock.hour=0;
}
if(Set_mode==5)
{Clock.minute++;
if(Clock.minute==60)
Clock.minute=0;
}
if(Set_mode==6)
{Clock.second++;
if(Clock.second==60)
Clock.second=0;
}
if(Set_mode==7)
{Clock.week++;
if(Clock.week>7)
Clock.week=1;
}
}
if((*P_IOA_Data&0x0004)!
=0x0000)//如果按下KEY3
{
if(Set_mode==0)
{Contr--;
Contr=(Contr>31)?
31:
Contr;
LCD501_SetContrast(Contr);
}
if(Set_mode==1)//如果为设置时间模式
Clock.year--;
if(Set_mode==2)
{
Clock.month--;
if(Clock.month==0)
{Clock.month=12;
}
}
if(Set_mode==3)
{
Clock.day--;
if((Clock.month==2)&&(Clock.day==0))//3月0日变成2月29日
{
Clock.day=28;
}
if((sign==1)&&(Clock.day==0))//4、6、9、11月0日变成前一月的31日
{
Clock.day=30;
}
if((sign==0)&&(Clock.day==0))//1、3、5、7、8、10、12月0日变成前一月的31日
{
Clock.day=31;
}
}
if(Set_mode==4)
{
Clock.hour--;
if(Clock.hour<0)
{
Clock.hour=23;
}
}
if(Set_mode==5)
{
Clock.minute--;
if(Clock.minute<0)
{
Clock.minute=59;
}
}
if(Set_mode==6)
{
Clock.second--;
if(Clock.second<0)
{
Clock.second=59;
}
}
if(Set_mode==7)
{Clock.week--;
if(Clock.week<1)
Clock.week=7;
}
}
}
while((*P_IOA_Data&0x0007)!
=0x0000);
}
Key_time++;
}
}
voidIRQ5(void)//2Hz时基中断控制时间
{
//addyourcodehere
if((*P_INT_Ctrl&C_IRQ5_2Hz)!
=0x0000)
{
*P_INT_Clear=C_IRQ5_2Hz;
Count_time++;
Count_time%=2;
if(Set_mode==0)//如果是时钟显示模式
{
if(Count_time==1)
{
Clock.second++;
Clock_Fix();
Disp_Time();
}
}
if(Set_mode>0)//如果是设置时间模式
{
Disp_Time();
if(Count_time)
{
if(Set_mode==1)
LCD501_PutString(0,16,"");//年跳动
if(Set_mode==2)
LCD501_PutString(48,16,"");//月跳动
if(Set_mode==3)
LCD501_PutString(80,16,"");//日跳动
if(Set_mode==4)
LCD501_PutString(56,32,"");//时跳动
if(Set_mode==5)
LCD501_PutString(80,32,"");//分跳动
if(Set_mode==6)
LCD501_PutString(104,32,"");//秒跳动
if(Set_mode==7)
LCD501_PutString(40,48,"");//星期跳动
}
}
}
}
voidClock_Init()
{
Clock.year=2010;
Clock.month=12;
Clock.day=31;
Clock.hour=23;
Clock.minute=59;
Clock.second=45;
Clock.week=3;
}
voidClock_Fix()//定义修正时间函数,如果时间产生溢出,则按时间计算规则进行处理
{
intflag;
flag=0;//如果为4、6、9、11月,则31日进位,如果为1、3、5、7、8、10、12月,则32日进位,如果为2月,29日进
if(Clock.month==4)
flag=1;
if(Clock.month==6)
flag=1;
if(Clock.month==9)
flag=1;
if(Clock.month==11)
flag=1;
if(Clock.second==60)//秒修正
{
Clock.minute++;
Clock.second=0;
}
if(Clock.minute==60)//分修正
{
Clock.hour++;
Clock.minute=0;
}
if(Clock.hour==24)//时修正
{
Clock.day++;
Clock.hour=0;
Clock.week++;//星期加一次
if(Clock.week==8)
Clock.week=1;
}
if((Clock.month==2)&&(Clock.day==29))//2月29日进位
{
Clock.month++;
Clock.day=1;
}
if((flag==1)&&(Clock.day==31))
{
Clock.month++;
Clock.day=1;
}
if((flag==0)&&(Clock.day==32))
{
Clock.month++;
Clock.day=1;
}
if(Clock.month==13)//13月进位
{
Clock.year++;
Clock.month=1;
}
}
voidDisp_Time()
{
inttemp;
*P_Watchdog_Clear=0x0001;
temp=Clock.year/1000;
LCD501_PutChar(0,16,temp+0x30);//年千位
temp=Clock.year/100;
temp%=10;
LCD501_PutChar(8,16,temp+0x30);//年百位
temp=Clock.year/10;
temp%=10;
LCD501_PutChar(16,16,temp+0x30);//年十位
temp=Clock.year%10;
LCD501_PutChar(24,16,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 数字 电子 时钟 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)