c8051f020单片机数字时钟.docx
- 文档编号:12288759
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:20
- 大小:19.28KB
c8051f020单片机数字时钟.docx
《c8051f020单片机数字时钟.docx》由会员分享,可在线阅读,更多相关《c8051f020单片机数字时钟.docx(20页珍藏版)》请在冰豆网上搜索。
c8051f020单片机数字时钟
/*
本程序只是为了应付课程设计而用
据我所知其中至少含有3处bug
使用环境c8051f020使用通过
*/
#include
#include
//*****软件仿真I2C总线与HD7279A连接的两根并行口线*****//
sbitHD7279_DAT=P1^7。
sbitHD7279_CLK=P1^6。
//*****宏定义,HD7279A片选信号、数据信号和时钟信号定义*****//
#defineNOSELECT7279P5|=0x80//P5^7接片选信号,选种
#defineSELECT7279P5&=~(0x80>//未选种
#defineSet7279DATHD7279_DAT=1//数据线置1
#defineClr7279DATHD7279_DAT=0//数据线置0
#defineSet7279CLKHD7279_CLK=1//时钟高电平
#defineClr7279CLKHD7279_CLK=0//时钟底电平
unsignedcharCount1ms。
unsignedcharxdataNowTime[3]。
//当前时间,用于当前时间的设置
unsignedcharxdataHourH,HourL,MinuteH,MinuteL,SecondH,SecondL。
unsignedcharxdatamHourH,mHourL,mMinuteH,mMinuteL,mSecondH,mSecondL。
unsignedcharxdatasetHourH,setHourL,setMinuteH,setMinuteL,setSecondH,setSecondL。
//*****对所调用其它文件中函数的声明*****//
voidDelay1ms(unsignedcharT>。
//延时T毫秒
voidDelay1s(unsignedcharT>。
//延时T秒
voidDelay1us(unsignedcharT>。
//延时T微秒
//*****仿真I2C总线时序发送一字节*****//
voidSYSCLK_Init(void>
{
inti。
OSCXCN=0x67。
//外部晶振22.1184MHz
for(i=0。
i<256。
i++>。
while(!
(OSCXCN&0x80>>。
//等待外部晶振稳定
OSCICN=0x88。
//选择外部晶振作系统时钟源,允许时钟丢失检测
}
//*****端口初始化*****//
voidPORT_Init(void>
{
XBR0=0x07。
//允许SMBus、SPI0和UART0
XBR1=0x00。
XBR2=0x44。
//使能交叉开关和弱上拉
}
//*****定时器T0初始化*****//
voidTimer0_Init(void>
{
CKCON|=0x8。
//T0按系统时钟频率计数
TMOD|=0x1。
//T0方式1
Count1ms=10。
TR0=0。
//停止T0
TH0=(-SYSCLK/1000>>>8。
//定时1ms的时间常数
TL0=-SYSCLK/1000。
TR0=1。
//启动T0
IE|=0x2。
//开T0中断
}
//*****定时器T0中断服务程序<每隔1ms中断1次)*****//
voidTimer0_ISR(void>interrupt1
{
TH0=(-SYSCLK/1000>>>8。
//重新装入初值
TL0=-SYSCLK/1000。
if(Count1ms>Count1ms--。
//定时时间减1
}
//******延时Tμs<软件实现)******//
voidDelay1us(unsignedcharT>
{
while(T>
{
_nop_(>。
_nop_(>。
_nop_(>。
_nop_(>。
_nop_(>。
--T。
}
}
//******延时Tms<定时器T0实现)******//
voidDelay1ms(unsignedcharT>
{
Count1ms=T。
while(Count1ms>。
//在T0中断服务程序中减1
}
//*****延时Ts<定时器T0实现)******//
voidDelay1s(unsignedcharT>
{
while(T>
{
Delay1ms(200>。
Delay1ms(200>。
Delay1ms(200>。
Delay1ms(200>。
Delay1ms(200>。
T--。
}
}
voidSend7279Byte(unsignedcharch>
{
chari。
SELECT7279。
//置CS低电平
Delay1us(50>。
//延时50μ
for(i=0。
i<8。
i++>
{
if(ch&0x80>//输出1位到HD7279A的DATA端
Set7279DAT。
else
Clr7279DAT。
Set7279CLK。
ch=ch<<1。
//待发数据左移
Delay1us(8>。
Clr7279CLK。
Delay1us(8>。
}
Clr7279DAT。
//发送完毕,DATA端置低,返回
}
//*****仿真I2C总线时序接收一字节*****//
unsignedcharReceive7279Byte(void>
{
unsignedchari,ch=0。
Set7279DAT。
//DATA端置为高电平<输入状态)
Delay1us(50>。
for(i=0。
i<8。
i++>
{
Set7279CLK。
Delay1us(8>。
ch=ch<<1。
//接收数据左移1位
if(HD7279_DAT>ch+=1。
//接收1位数据
Clr7279CLK。
Delay1us(8>。
}
Clr7279DAT。
//接收完毕,DATA端重新置成低电平(输出状态>
returnch。
}
//*****让第No(0到5>位LED闪烁*****//
voidFlashLED(unsignedcharNo>
{
unsignedchari。
Send7279Byte(0x88>。
//发闪烁指令
i=0x01。
while(No>//将1移到第No位
{
i=i<<1。
No--。
}
Send7279Byte(~i>。
//0闪烁、1不闪烁
NOSELECT7279。
}
//******HD7279A左移命令*****//
voidMoveLeft(void>
{
Send7279Byte(0xA1>。
//发左移指令
NOSELECT7279。
}
//******采用不译码方式显示时数字0到F的段码******//
unsignedcharcodeBdSeg[]={
0x7e,0x30,0x6d,0x79,//0123
0x33,0x5b,0x5f,0x70,//4567
0x7f,0x7b,0x77,0x1f,//89ab
0x4e,0x3d,0x4f,0x47,//cdef
0x00,0x01}。
//*显示指针DispBuf所指6个单元数据,点亮第ShowDot<1到6)个LED的小数点*//
voidDispLED(unsignedchar*DispBuf,unsignedcharShowDot>
{
chari,ch。
ShowDot--。
for(i=0。
i<6。
i++>
{
ch=DispBuf[i]。
//取一字符
if((ch>='a'>&&(ch<='f'>>//转换成数字
{
ch-='a'。
ch+=0xa。
}
if((ch>='A'>&&(ch<='F'>>
{
ch-='A'。
ch+=0xa。
}
Send7279Byte(0x90+5-i>。
//用不译码方式显示在第i位
if(ch==''>//发送不译码方式显示命令的第2字节
Send7279Byte(0x00>。
else
if(ch=='-'>
Send7279Byte(0x01>。
else
{
if(ShowDot==i>//查表显示,同时点亮小数点
Send7279Byte(0x80|BdSeg[ch&0x0f]>。
else
Send7279Byte(BdSeg[ch&0x0f]>。
}
}
NOSELECT7279。
//置CS高电平
}
//*****读取按键值*****//
unsignedcharGetKeyValue(void>
{
unsignedcharKeyValue。
if(CPT1CN&0x40>return-1。
//if(P17==1>return-1。
//无键按下
Send7279Byte(0x15>。
//发读键盘命令
KeyValue=Receive7279Byte(>。
NOSELECT7279。
returnKeyValue。
}
//***等待按键释放,用C8051F020的比较器硬件检测,也可以用软件延时实现***//
voidWaitKeyOff(void>
{
while(!
(CPT1CN&0x40>>。
}
//*****显示任意长整型数据*****//
voidDispValue(unsignedlongxx>
{
unsignedcharbuf[6]。
buf[0]=(xx%1000000>/100000。
//最高位
buf[1]=(xx%100000>/10000。
buf[2]=(xx%10000>/1000。
buf[3]=(xx%1000>/100。
buf[4]=(xx%100>/10。
buf[5]=(xx%10>。
//最低位
DispLED(buf,0>。
//调用显示函数,所有小数点都不点亮
}
//**从键盘读取6位数据,用于存储时间,格式是HHMMSS,所读数据转换成长整型**//
unsignedlongInputNum(void>
{
unsignedlongNum=0。
unsignedchari=0,KeyValue。
DispLED("-",0>。
//输入提示
FlashLED(0>。
//第一位闪烁
Delay1s(1>。
while(1>
{
KeyValue=GetKeyValue(>。
if(i==6>//6位数据输入完,返回
{
FlashLED(8>。
//关闪烁
returnNum。
}
if((KeyValue>=0>&&(KeyValue<=9>>//只接收十进制的0到9
{
i++。
Send7279Byte(0xC8>。
//发送键码值,按方式1译码下载显示
Send7279Byte(KeyValue>。
MoveLeft(>。
//显示并左移一位,仍使低位显示并闪烁。
Send7279Byte(0x90>。
Send7279Byte(0x01>。
NOSELECT7279。
WaitKeyOff(>。
Num*=10。
//转换成十进制
Num+=KeyValue。
}
Delay1ms(500>。
}
}
voidDispTime(void>
{
Send7279Byte(0x85>。
//在最高位<第5位)LED显示小时的高位
Send7279Byte(HourH>。
Send7279Byte(0x84>。
//在第4位LED显示小时的低位
Send7279Byte(HourL>。
Send7279Byte(0x83>。
//在第3位LED显示分钟的高位
Send7279Byte(MinuteH>。
Send7279Byte(0x82>。
//在第2位LED显示分钟的低位
Send7279Byte(MinuteL>。
Send7279Byte(0x81>。
//在第1位LED显示秒钟的高位
Send7279Byte(SecondH>。
Send7279Byte(0x80>。
//在第0位LED显示秒钟的低位
Send7279Byte(SecondL>。
}
voidmDispTime(void>
{
Send7279Byte(0x85>。
//在最高位<第5位)LED显示小时的高位
Send7279Byte(mHourH>。
Send7279Byte(0x84>。
//在第4位LED显示小时的低位
Send7279Byte(mHourL>。
Send7279Byte(0x83>。
//在第3位LED显示分钟的高位
Send7279Byte(mMinuteH>。
Send7279Byte(0x82>。
//在第2位LED显示分钟的低位
Send7279Byte(mMinuteL>。
Send7279Byte(0x81>。
//在第1位LED显示秒钟的高位
Send7279Byte(mSecondH>。
Send7279Byte(0x80>。
//在第0位LED显示秒钟的低位
Send7279Byte(mSecondL>。
}
voidset_time(>
{
unsignedlongCurrentTime=0。
do{//从键盘输入时间,格式HHMMSS
CurrentTime=InputNum(>。
DispValue(CurrentTime>。
NowTime[0]=(unsignedchar>((CurrentTime/100000><<4>。
//时
CurrentTime=CurrentTime%100000。
NowTime[0]=NowTime[0]|(CurrentTime/10000>。
CurrentTime=CurrentTime%10000。
NowTime[1]=(unsignedchar>((CurrentTime/1000><<4>。
//分
CurrentTime=CurrentTime%1000。
NowTime[1]=NowTime[1]|(CurrentTime/100>。
CurrentTime=CurrentTime%100。
NowTime[2]=(unsignedchar>((CurrentTime/10><<4>。
//秒
CurrentTime=CurrentTime%10。
NowTime[2]=NowTime[2]|CurrentTime。
}while((NowTime[0]>0x24>|(NowTime[1]>0x59>|(NowTime[2]>0x59>>。
HourH=NowTime[0]/16。
//转换成10进制
HourL=NowTime[0]%16。
MinuteH=NowTime[1]/16。
MinuteL=NowTime[1]%16。
SecondH=NowTime[2]/16。
SecondL=NowTime[2]%16。
}
unsignedlongset_InputNum(void>
{
unsignedlongNum=0。
unsignedchari=0,KeyValue。
intc=0。
DispLED("-",0>。
//输入提示
FlashLED(0>。
//第一位闪烁
while(1>
{
KeyValue=GetKeyValue(>。
if(i==6>//6位数据输入完,返回
{
FlashLED(8>。
//关闪烁
returnNum。
}
if((KeyValue>=0>&&(KeyValue<=9>>//只接收十进制的0到9
{
i++。
Send7279Byte(0xC8>。
//发送键码值,按方式1译码下载显示
Send7279Byte(KeyValue>。
MoveLeft(>。
//显示并左移一位,仍使低位显示并闪烁。
Send7279Byte(0x90>。
Send7279Byte(0x01>。
NOSELECT7279。
WaitKeyOff(>。
Num*=10。
//转换成十进制
Num+=KeyValue。
}
if(SecondL>9>{SecondH++,SecondL=0。
}
if(SecondH>5>{SecondH=0,MinuteL++。
}
if(MinuteL>9>{MinuteH++,MinuteL=0。
}
if(MinuteH>5>{MinuteH=0,HourL++。
}
if(HourL>9>{HourH++。
HourL=0。
}
if(HourH>2>HourH=0。
if((HourH==2>&&(HourL>3>>{HourH=0。
HourL=0。
}
c++。
Delay1ms(500>。
if(c%2==0>SecondL++。
}
}
voidset_ring(>
{
unsignedlongCurrentTime=0。
do{//从键盘输入时间,格式HHMMSS
CurrentTime=set_InputNum(>。
DispValue(CurrentTime>。
NowTime[0]=(unsignedchar>((CurrentTime/100000><<4>。
//时
CurrentTime=CurrentTime%100000。
NowTime[0]=NowTime[0]|(CurrentTime/10000>。
CurrentTime=CurrentTime%10000。
NowTime[1]=(unsignedchar>((CurrentTime/1000><<4>。
//分
CurrentTime=CurrentTime%1000。
NowTime[1]=NowTime[1]|(CurrentTime/100>。
CurrentTime=CurrentTime%100。
NowTime[2]=(unsignedchar>((CurrentTime/10><<4>。
//秒
CurrentTime=CurrentTime%10。
NowTime[2]=NowTime[2]|CurrentTime。
}while((NowTime[0]>0x24>|(NowTime[1]>0x59>|(NowTime[2]>0x59>>。
setHourH=NowTime[0]/16。
//转换成10进制
setHourL=NowTime[0]%16。
setMinuteH=NowTime[1]/16。
setMinuteL=NowTime[1]%16。
setSecondH=NowTime[2]/16。
setSecondL=NowTime[2]%16。
}
voidm(>
{
unsignedlongCurrentTime=0。
unsignedcharcontrol_keyvalue。
intma=0。
inta=1。
DispValue(CurrentTime>。
NowTime[0]=(unsignedchar>((CurrentTime/100000><<4>。
//时
CurrentTime=CurrentTime%100000。
NowTime[0]=NowTime[0]|(CurrentTime/10000>。
CurrentTime=CurrentTime%10000。
NowTime[1]=(unsignedchar>((CurrentTime/1000><<4>。
//分
CurrentTime=CurrentTime%1000。
NowTime[1]=NowTime[1]|(CurrentTime/100>。
CurrentTime=CurrentTime%100。
NowTime[2]=(unsignedchar>((CurrentTime/10><<4>。
//秒
CurrentTime=CurrentTime%10。
NowTime[2]=NowTime[2]|CurrentTime。
mHourH=NowTime[0]/16。
//转换成10进制
mHourL=NowTime[0]%16。
mMinuteH=NowTime[1]/16。
mMinuteL=NowTime[1]%16。
mSecondH=NowTime[2]/16。
mSecondL=NowTime[2]%16。
while(1>
{
Delay1ms(200>。
ma++。
if(ma%5==0>
mSecondL++。
if(mSecondL>9>{mSecondH++,mSecondL=0。
}
if(mSecondH>5>{mSecondH=0,mMinuteL++。
}
if(mMinuteL>9>{mMinuteH++,mMinuteL=0。
}
if(mMinuteH>5>{mMinuteH=0,mHourL++。
}
if(mHourL>9>{mHourH++。
mHourL=0。
}
if(mHourH>2>mHourH=0。
if((mHourH==2>&&(mHourL>3>>{mHourH=0。
mHourL=0。
}
control_keyvalue=GetKeyValue(>。
if(control_keyvalue==14>break。
if(control_keyvalue==10>a=-a。
if(a==-1&&ma%5==0>mSecondL--。
mDispTime(>。
if(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c8051f020 单片机 数字 时钟