用单片机设计一个数字时钟

用单片机设计一个数字时钟,第1张

#include <REG51H>#include <intrinsh> #define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //实时时钟时钟线引脚 sbit DS1302_IO = P1^6; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚sbit wireless_1 = P3^0;sbit wireless_2 = P3^1;sbit wireless_3 = P3^2;sbit wireless_4 = P3^3; //无线控制sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数sbit Set = P2^0; //模式切换键sbit Up = P2^1; //加法按钮sbit Down = P2^2; //减法按钮sbit out = P2^3; //立刻跳出调整模式按钮sbit DQ = P1^0; //温度传送数据IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; //温度值uchar TempBuffer[5],week_value[2]; void show_time(); //液晶显示程序/1602液晶显示部分子程序///Port Definitionssbit LcdRs = P2^5;sbit LcdRw = P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0数据端口 //内部等待函数unsigned char LCD_Wait(void){ LcdRs=0; LcdRw=1; _nop_(); LcdEn=1; _nop_(); LcdEn=0; return DBPort; }//向LCD写入命令或数据#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){ LcdEn=0; LcdRs=style; LcdRw=0; _nop_(); DBPort=input; _nop_();//注意顺序 LcdEn=1; _nop_();//注意顺序 LcdEn=0; _nop_(); LCD_Wait(); } //设置显示模式#define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关 #define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标 #define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动 void LCD_SetDisplay(unsigned char DisplayMode){ LCD_Write(LCD_COMMAND, 0x08|DisplayMode); } //设置输入模式#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //default void LCD_SetInput(unsigned char InputMode){ LCD_Write(LCD_COMMAND, 0x04|InputMode);} //初始化LCDvoid LCD_Initial(){ LcdEn=0; LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,57点阵 LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动} //液晶字符输入的位置void GotoXY(unsigned char x, unsigned char y){ if(y==0) LCD_Write(LCD_COMMAND,0x80|x); if(y==1) LCD_Write(LCD_COMMAND,0x80|(x-0x40));} //将字符输出到液晶显示void Print(unsigned char str){ while(str!='\0') { LCD_Write(LCD_DATA,str); str++; }} /DS1302时钟部分子程序/typedef struct __SYSTEMTIME__{ unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[11]; unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型SYSTEMTIME CurrentTime; #define AM(X) X#define PM(X) (X+12) // 转成24小时制#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){ unsigned char i; ACC = d; for(i=8; i>0; i--) { DS1302_IO = ACC0; //相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } } unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数){ unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; //相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; } return(ACC); } void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据{ DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0;} unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{ unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);} void DS1302_GetTime(SYSTEMTIME Time) //获取时钟芯片的时钟数据到自定义的结构型数组{ unsigned char ReadValue; ReadValue = Read1302(DS1302_SECOND); Time->Second = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MINUTE); Time->Minute = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_HOUR); Time->Hour = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_DAY); Time->Day = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK); Time->Week = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MONTH); Time->Month = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR); Time->Year = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); } void DateToStr(SYSTEMTIME Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22 { Time->DateString[0] = '2'; Time->DateString[1] = '0'; Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0'; } else { Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' '; } Time->DateString[4] = '/'; if(hide_month<2) { Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0'; } else { Time->DateString[5] = ' '; Time->DateString[6] = ' '; } Time->DateString[7] = '/'; if(hide_day<2) { Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day%10 + '0'; } else { Time->DateString[8] = ' '; Time->DateString[9] = ' '; } if(hide_week<2) { week_value[0] = Time->Week%10 + '0'; //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示 } else { week_value[0] = ' '; } week_value[1] = '\0'; Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符} void TimeToStr(SYSTEMTIME Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];{ if(hide_hour<2) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour%10 + '0'; } else { Time->TimeString[0] = ' '; Time->TimeString[1] = ' '; } Time->TimeString[2] = ':'; if(hide_min<2) { Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0'; } else { Time->TimeString[3] = ' '; Time->TimeString[4] = ' '; } Time->TimeString[5] = ':'; if(hide_sec<2) { Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; } else { Time->TimeString[6] = ' '; Time->TimeString[7] = ' '; } Time->DateString[8] = '\0';} void Initial_DS1302(void) //时钟芯片初始化{ unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80) //判断时钟芯片是否关闭 { Write1302(0x8e,0x00); //写入允许 Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25星期: 3 时间: 23:59:55 Write1302(0x88,0x07); Write1302(0x86,0x25); Write1302(0x8a,0x07); Write1302(0x84,0x23); Write1302(0x82,0x59); Write1302(0x80,0x55); Write1302(0x8e,0x80); //禁止写入 } } /ds18b20子程序/ /ds18b20延迟子函数(晶振12MHz )/ void delay_18B20(unsigned int i){ while(i--);} /ds18b20初始化函数/ void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(8); //稍做延时 DQ = 0; //单片机将DQ拉低 delay_18B20(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay_18B20(14); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20);} /ds18b20读一个字节/ unsigned char ReadOneChar(void){ uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat>>=1; DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); } return(dat);} /ds18b20写一个字节/ void WriteOneChar(uchar dat){ unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>>=1; }} /读取ds18b20当前温度/ void ReadTemp(void){ unsigned char a=0; unsigned char b=0; unsigned char t=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳过读序号列号的 *** 作 WriteOneChar(0x44); // 启动温度转换 delay_18B20(100); // this message is wery important Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的 *** 作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 delay_18B20(100); a=ReadOneChar(); //读取温度值低位 b=ReadOneChar(); //读取温度值高位 temp_value=b<<4; temp_value+=(a&0xf0)>>4; }void temp_to_str() //温度数据转换成液晶字符显示{ TempBuffer[0]=temp_value/10+'0'; //十位 TempBuffer[1]=temp_value%10+'0'; //个位 TempBuffer[2]=0xdf; //温度符号 TempBuffer[3]='C'; TempBuffer[4]='\0';}void Delay1ms(unsigned int count){ unsigned int i,j; for(i=0;i<count;i++) for(j=0;j<120;j++);} /延时子程序/void mdelay(uint delay){ uint i; for(;delay>0;delay--) {for(i=0;i<62;i++) //1ms延时 {;} }}

#include<reg52h>

#define uint unsigned int

#define uchar unsigned char

sbit QB1=P1^0;

sbit QB2=P1^1; //数码管段选

sbit QB3=P1^2;

sbit QB4=P1^3;

sbit QB5=P1^4;

sbit QB6=P1^5;

sbit fm=P1^6; //蜂鸣器

sbit s1=P2^4; //s5按键,切换显示

sbit s2=P2^3; //s2按键,设置调时

sbit s3=P2^2; //s3按键,加1

sbit s4=P2^1; //s4按键,减1

sbit led1=P0^0;

sbit led2=P0^1;

sbit led3=P0^2;

uchar count;

uchar sec,minu,hour,day,week,mon;

uchar n_sec,n_minu,n_hour;

uint year;

uchar set_2=1,set_1=1;

uchar hs,hg,mis,mig,ss,sg;

uchar nhs,nhg,nms,nmg,nss=0,nsg=0;

uchar ms,mg,ds,dg,w;

uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,

0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}; //0~F,-,共阳

//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//0-F,-,共阴

uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,

0x87,0xff,0xef}; //0~9数组,带小数点

uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年

uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年

void delay(uint); //延时函数

void timer0(); //走时中断函数

void jishi(); //计时函数

void key_change(); //切换显示按键函数

void key_set(); //设置时间按键函数

void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示函数

void zd_clock(); //整点报时函数

void nz_clock(); //闹钟函数

uchar incone(uchar); //加1函数

uchar decone(uchar); //减1函数

void set_time(); //设置时间函数

void set_clock(); //设置闹钟函数

void set_mdw(); //设置月日星期函数

void main() //主函数

{

EA=1;

ET0=1;

TR0=1;

TMOD=0x01;

TH0=0x4c; //50ms初值 晶振110592

TL0=0x00;

hour=23;minu=59;sec=49; //赋初值:11点59分0秒

n_hour=12;n_minu=56;n_sec=0; //闹钟赋初值12点1分0秒

year=2008;mon=5;day=14;week=3;//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐

while(1)

{

hs=hour/10; //时分秒HHMMSS

hg=hour%10;

mis=minu/10;

mig=minu%10;

ss=sec/10;

sg=sec%10;

ms=mon/10; //月日-星期MMDD-W

mg=mon%10;

ds=day/10;

dg=day%10;

w=week;

nhs=n_hour/10; //闹钟定时HHMMSS

nhg=n_hour%10;

nms=n_minu/10;

nmg=n_minu%10;

nss=n_sec/10;

nsg=n_sec%10;

key_change(); //s4按键扫描

key_set(); //s2按键扫描

set_time(); //设置时间

set_mdw(); //设置月日星期

set_clock(); //设置闹钟

if(set_1==1) //正常走时显示

{

disp(hs,hg,mis,mig,ss,sg);

}

if(set_1==2) //设置时间,LED1闪亮

{

disp(hs,hg,mis,mig,ss,sg);

if(sec%2==0)

{led2=1;led3=1;led1=~led1;}

// else

// {led1=1;}

}

if(set_1==3) //正常显示月日-星期

{

disp(ms,mg,ds,dg,16,w);

}

if(set_1==4) //设置月日-星期,LED2闪亮

{

disp(ms,mg,ds,dg,16,w);

if(sec%2==0)

{led1=1;led3=1;led2=~led2;}

// else

// {led2=1;}

}

if(set_1==5) //正常显示定时

{

disp(nhs,nhg,nms,nmg,nss,nsg);

}

if(set_1==6) //设置闹钟定时,LED3闪亮

{

disp(nhs,nhg,nms,nmg,nss,nsg);

if(sec%2==0)

{led1=1;led2=1;led3=~led3;}

// else

// {led3=1;}

}

zd_clock(); //整点报时

nz_clock(); //闹钟

}

}

void timer0() interrupt 1 //50ms中断函数

{

TMOD=0x01;

TH0=0x4c; //50ms初值 晶振110592

TL0=0x00;

count++;

if(count==20)

{

count=0;

sec++;

jishi(); //调计时函数

}

}

void jishi() //计时函数

{

if(sec==60)

{

sec=0;

minu++;

if(minu==60)

{

minu=0;

hour++;

if(hour==24)

{ hour=0;

day++;

week++;

if(week==8)

{week=0;}

if(year%4==0&&year%100!=0||year%400==0) //闰年

{

if(day==table1[mon]+1)

{

day=0;

mon++;

if(mon==13)

{mon=0;year++;}

}

}

else //非闰年

{

if(day==table2[mon]+1)

{

day=0;

mon++;

if(mon==13)

{mon=0;year++;}

}

}

}

}

}

}

void key_change() //s1按键扫描

{

if(s1==0)

{

delay(200);

if(s1==0)

{

set_1++;

while(!s1);

if(set_1==7)

{set_1=1;}

}

}

}

void key_set() //s2按键扫描

{

if(s2==0)

{

delay(10);

if(s2==0)

{

set_2++;

while(!s2);

if(set_2==4)

{set_2=1;}

}

}

}

void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数

{

QB1=1;

QB2=0;

QB3=0;

QB4=0;

QB5=0;

QB6=0;

P3=table[a1]; //段码送P0口

delay(10); //延时一小会

QB1=0;

QB2=1;

QB3=0;

QB4=0;

QB5=0;

QB6=0;

P3=table[a2]; //第2个数码管显示,带小数点

delay(10);

QB1=0;

QB2=0;

QB3=1;

QB4=0;

QB5=0;

QB6=0;

P3=table[a3]; //第3个数码管显示

delay(10);

QB1=0;

QB2=0;

QB3=0;

QB4=1;

QB5=0;

QB6=0;

P3=table[a4]; //第4个数码管显示,带小数点

delay(10);

QB1=0;

QB2=0;

QB3=0;

QB4=0;

QB5=1;

QB6=0;

//第5个数码管显示

P3=table[a5];

delay(10);

QB1=0;

QB2=0;

QB3=0;

QB4=0;

QB5=0;

QB6=1;

P3=table[a6]; //第6个数码管显示

delay(10);

QB1=0;

QB2=0;

QB3=0;

QB4=0;

QB5=0;

QB6=0;

}

void zd_clock() //整点报时函数

{

if(minu==59&&(sec==53||sec==55||sec==57))

{

fm=0;

delay(5);

fm=1;

delay(5);

}

fm=0;

if(minu==59&&sec==59)

{

fm=0;

delay(5);

fm=1;

delay(5);

fm=0;

}

}

void nz_clock() //闹钟函数

{

if(hour==n_hour&&minu==n_minu&&sec==n_sec)

//if((sec%2==0)&&sec<30)

{

fm=0;

delay(1);

fm=1;

delay(1);

}

}

void set_time() //设置时间函数

{

if(set_1==2)

{

if(set_2==1)

{

hour=incone(hour);

if(hour==24)

{hour=0;}

// if(hour<0)

// {hour=23;}

hour=decone(hour);

}

if(set_2==2)

{

minu=incone(minu);

if(minu==60)

{minu=0;}

// if(minu<0)

// {minu=59;}

minu=decone(minu);

}

}

}

void set_mdw() //设置月日星期函数

{

if(set_1==4)

{

if(set_2==1)

{

mon=incone(mon);

if(mon==13)

{mon=1;}

mon=decone(mon);

// if(mon==0)

// {mon=12;}

}

if(set_2==2)

{

day=incone(day);

if(day==32)

{day=0;}

day=decone(day);

// if(day==0)

// {day=0;}

}

if(set_2==3)

{

week=incone(week);

if(week==8)

{week=0;}

week=decone(week);

// if(week==0)

// {week=7;}

}

}

}

void set_clock() //设置闹钟函数

{

if(set_1==6)

{

if(set_2==1)

{

n_hour=incone(n_hour);

if(n_hour==24)

{n_hour=0;}

n_hour=decone(n_hour);

if(n_hour==0)

{n_hour=0;}

}

if(set_2==2)

{

n_minu=incone(n_minu);

if(n_minu==60)

{n_minu=0;}

n_minu=decone(n_minu);

if(n_minu==0)

{n_minu=0;}

}

}

}

uchar incone(uchar n) //加1函数

{

if(s3==0)

{ delay(200);

if(s3==0)

{

n++;

while(!s3);

}

}

return(n);

}

uchar decone(uchar m) //减1函数

{

if(s4==0)

{

delay(200);

if(s4==0)

{

m--;

while(!s4);

if(m<0)

{m=0;}

}

}

return(m);

}

void delay(uint k) //延时函数

{

uint i,j;

for(i=k;i>0;i--)

for(j=80;j>0;j--);

}

muteM EQU 10h ;静音键 闹铃开/关

timerT EQU 0Ch ;菜单键 进入/退出设置状态

leftL EQU 46h ;左移键

rightR EQU 47h ;右移键

upU EQU 19h ;增加键

downD EQU 1dh ;减少键

d_off EQU 16H ;显示键 LED数码管显示/关闭

recall EQU 44H ;日历键 DS1302初始化 *** 作

K_on BIT P30 ;闹铃输出

LED1 BIT P33

LED2 BIT P34

LED3CLK BIT P35 ;DS1302

LED4IO BIT P37

RST BIT P31

SECOND EQU 60H

;60H 秒

;61h 分

;62h 时

;63h 日

;64h 月 ;65h DAY

;66h 年

;6Ah 闹分 from 00(1302)

;6BH 闹时 from 01(1302)

;

ORG 0000H

AJMP START

ORG 0003H

LJMP S_INT ;IRF

ORG 000BH ;200Us

LJMP P_INT ;

ORG 001BH ;display LED

LJMP DISPLAY

; ;main program

ORG 0030H

START: CLR RST

MOV SP,#2AH

SETB 05H

CLR 06H

SETB 07H;CLR 07H

CLR 08H

CLR 09H

CLR 0AH

CLR 0BH

CLR 0CH

SETB 0DH

CLR 0EH

CLR 0FH

CLR 10H

CLR 11H

MOV R2,#00H ;

MOV R3,#00H ;

MOV TMOD,#12H

MOV TL1,#0e5H ;wait

MOV TH1,#0BeH

MOV TH0,#3FH ;200uS 3f

MOV TL0,#3FH

SETB ET0

SETB ET1

setb pt0

SETB TR0

SETB TR1

SETB IT0 ;

SETB EX0 ;

CLR PX0 ;LCALL SET1302 ;初始化

MOV R1,#0C1H ;取定时参数从1302中

acall T_6061

MOV 6AH,A ;M

MOV R1,#0C3H

ACALL T_6061

MOV 6BH,A ;H

MOV 61H,#0

MOV 62H,#0

SETB EA

sjmp $

;

DISPLAY: PUSH ACC

PUSH PSW

MOV TL1,#0e0H ;wait how long to display (20ms)

MOV TH1,#0b0H

MOV dptr,#tab1

JB 0EH,DIS2

JB 0FH,DIS3

JB 10H,DIS4

JB 11H,DIS5

JNB 0DH,D_OUT

JNB 08H,D_GO ;定时到时,显示闪烁

JNB 07H,D_OUT

D_G MOV DPTR,#TAB1

MOV A,62H

ANL A,#0FH

MOV B,A

MOV A,62H

SWAP A

ANL A,#07H

MOVC A,@A+DPTR

MOV P1,A

CLR LED1

LCALL DL2M

SETB LED1

MOV A,B

MOVC A,@A+DPTR

MOV C,07H

MOV acc7,C ;秒灯闪烁

MOV P1,A

CLR LED2

LCALL DL2M

SETB LED2

MOV dptr,#tab2 ;倒装LED字段表

MOV A,61H

ANL A,#0FH

MOV B,A

MOV A,61H

SWAP A

ANL A,#0FH

MOVC A,@A+DPTR

MOV C,07H

MOV acc6,C ;秒灯闪烁

MOV P1,A

CLR LED3CLK

LCALL DL2M

SETB LED3CLK

MOV dptr,#tab1

MOV A,B

MOVC A,@A+DPTR

MOV C,06H

cpl c

MOV acc7,C ;闹铃指示灯

MOV P1,A

CLR LED4IO

LCALL DL2M

SETB LED4IO

D_OUT: SETB TR1

POP PSW

POP ACC

RETI

;

DIS2: AJMP DIS_2

DIS3: AJMP DIS_3

DIS4: AJMP DIS_4

DIS5: AJMP DIS_5

;

DIS_2: MOV dptr,#tab1 ;显示设置小时

MOV 6FH,62H

ACALL BCD_HEX

MOV B,#10

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED1

LCALL DL2M

SETB LED1

MOV A,B

MOVC A,@A+DPTR

MOV P1,A

CLR LED2

LCALL DL2M

SETB LED2

SETB TR1

POP PSW

POP ACC

RETI

;

DIS_3: MOV DPTR,#TAB2 ;显示设置分

MOV 6FH,61H

ACALL BCD_HEX

MOV B,#10

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED3CLK

LCALL DL2M

SETB LED3CLK

MOV A,B

MOV DPTR,#TAB1

MOVC A,@A+DPTR

MOV P1,A

CLR LED4IO

LCALL DL2M

SETB LED4IO

SETB TR1

POP PSW

POP ACC

RETI

;

DIS_4: MOV dptr,#tab1 ;显示设置闹时

JNB 07H,D4_OUT ;显示时闪烁

MOV A,6BH

MOV B,#0AH

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED1

LCALL DL2M

SETB LED1

MOV A,B

MOVC A,@A+DPTR

MOV P1,A

CLR LED2

LCALL DL2M

SETB LED2

D4_OUT: SETB TR1

POP PSW

POP ACC

RETI

;

DIS_5: MOV DPTR,#TAB2

JNB 07H,D5_OUT ;显示时闪烁

MOV A,6AH ;显示设置闹分

MOV B,#0AH

DIV AB

MOVC A,@A+DPTR

MOV P1,A

CLR LED3CLK

LCALL DL2M

SETB LED3CLK

MOV DPTR,#TAB1

MOV A,B

MOVC A,@A+DPTR

MOV P1,A

CLR LED4IO

LCALL DL2M

SETB LED4IO

D5_OUT: SETB TR1

POP PSW

POP ACC

RETI

;

DL2M: MOV 43H,#14H ; every LED(2ms)

DL2: MOV 44H,#14H

DL1: NOP

NOP

DJNZ 44H,DL1

DJNZ 43H,DL2

RET

;定时读取1302时间及判断闹铃时间是否到

P_INT: PUSH ACC

PUSH PSW

INC R2

CJNE R2,#250D,P_OUT

MOV R2,#00H

INC R3

CJNE R3,#10D,P_OUT

MOV R3,#00H

CPL 07H

MOV P1,#0FFH

ACALL R_1302

OUT: JNB 06H,P_OUT

MOV A,6BH

MOV B,#10

DIV AB

SWAP A

ADD A,B

CJNE A,62H,PP_OUT

MOV A,6AH

MOV B,#10

DIV AB

SWAP A

ADD A,B

CJNE A,61H,PP_OUT

SETB 08H ;定时到标志

MOV C,07H

cpl c

MOV K_ON,C

P_OUT: POP PSW

POP ACC

RETI

PP_OUT: SETB K_ON

CLR 08H

POP PSW

POP ACC

RETI

;有接收到遥控器信号

S_INT:CLR EA

PUSH ACC

PUSH PSW

PUSH DPH

PUSH DPL

PUSH 02H

PUSH 03H

MOV R6,#10D ;

SB: ACALL YS1

JB P32,EXIT

DJNZ R6, SB

JNB P32, $ ;

ACALL YS2 ;

JB P32,EXIT

MOV R1,#1AH ;

MOV R2,#4D

PP: MOV R3,#8D

JJJJ: JNB P32,$

ACALL YS1

MOV C,P32

JNC UUU

JB P32,$

UUU: MOV A,@R1

RRC A

MOV @R1,A

DJNZ R3,JJJJ

INC R1

DJNZ R2,PP

;-------------------------------------

MOV A,1AH ;

XRL A,#40h ;判断1AH的值是否等于遥控器低8位地址(40h)

JNZ EXIT ;

MOV A,1bH

XRL A,#0bfh ;再判断高8位地址是否正确(0bfh)

JNZ EXIT

MOV A,1CH

CPL A

XRL A,1DH ;将1CH的值取反后和1DH比较 不同则无效丢弃(核对数据是否准确)

JNZ EXIT

ACALL DO ;相应按键的处理

EXIT: SETB EA

POP 03H

POP 02H

POP DPL

POP DPH

POP PSW

POP ACC

RETI

;--------------------delay-----------------------

YS1: MOV 70H,#16D ;延时1

D1: MOV 71H,#21D

DJNZ 71H,$

DJNZ 70H,D1

RET

YS2: MOV 70H,#09D ;延时2

D2: MOV 71H,#220D

DJNZ 71H,$

DJNZ 70H,D2

RET

;---------------------------------------------------------

TAB: DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H ;TAB1 LED数码管显示表 TAB遥控器键值表(未用)

;TAB1: DB 3FH,11H,5EH,5BH,71H,6BH,6FH,19H,7FH,7bH,77H,7CH,39H,5EH,79H,71H

tab1: DB 0C0H,0F9H,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0a7h,0a1h,86h,8EH

TAB2: DB 0c0H,0f9H,64H,70H,59H,52H,42H ;倒装LED段码表

;0CH 为设置标志,0DH为全显示标志,0EH为显示设置小时标志,0FH为显示设置分标志

;10H 为显示设置闹时标志,11H为显示设置闹分标志

;增加闹时静音功能

;mute-10h,timer-0eh,left-46h,right-47h,up-19h,down-1dh

D MOV A,1CH

CJNE A,#TIMERT,REDO ;代码不是设置/退出键

JNB 0CH,SET1 ;是,则进入

CLR 0CH ;是,已经进入,则退出

SETB 0DH ;恢复正常显示

CLR 0EH

CLR 0FH

CLR 10H

CLR 11H

RET

SET1: SETB 0CH

SETB 0EH

CLR 0DH

CLR 0FH

CLR 10H

CLR 11H

RET

RED CJNE A,#MUTEM,REDO1 ;不是设置键的处理REDO1,2,3,4

LJMP MUTE ;MUTE

REDO1: CJNE A,#D_OFF,DO_SET2

LJMP DIS_OFF ;关闭显示

DO_SET2:JB 0CH,SET2 ;时间设置的处理

RET

SET2: CJNE A,#UPU,SET2A

LJMP INC1 ;+加(^)

SET2A: CJNE A,#DOWND,SET2B

LJMP DEC2 ;- 减

SET2B: CJNE A,#RIGHTR,SET2C

LJMP RIGHT ;RIGHT右移(>)

SET2C: CJNE A,#LEFTL,SET2D LJMP LEFT ;LEFT左移(<)

SET2D: CJNE A,#RECALL,SET2EXT ;DS1302初始化

LJMP SET1302

SET2EXT:RET

;--------------------------------INC------------------------

INC1: JB 0EH,INCH

JB 0FH,INCM

JB 10H,INC_H

JB 11H,INC_M

RET

INC_H: INC 6BH ;闹钟小时增加

MOV A,6BH

CJNE A,#24D,INCH3

MOV 6BH,#0

INCH3: MOV R1,#0C2H

MOV R0,6BH

ACALL SETONE ;写入DS1302

RET

INC_M: INC 6AH ;闹钟分增加

MOV A,6AH

CJNE A,#60D,INCH4

MOV 6AH,#0

INCH4: MOV R1,#0C0H

MOV R0,6AH

ACALL SETONE ;

RET

INCH: ;INC 62H ;

MOV 6FH,62H

ACALL BCD_HEX

INC A

CJNE A,#24D,INCH1

MOV A,#0

INCH1: MOV 6FH,A

ACALL HEX_BCD

MOV 62H,A

MOV R1,#84H

MOV R0,62H

ACALL SETONE ;

RET

INCM: ;INC 61H ;

MOV 6FH,61H

ACALL BCD_HEX

INC A

CJNE A,#60D,INCH2

MOV A,#0

INCH2: MOV 6FH,A

ACALL HEX_BCD

MOV 61H,A

MOV R1,#82H

MOV R0,61H

ACALL SETONE ;

RET

;----------------------------------DEC----------------------

DEC2: JB 0EH,DECH

JB 0FH,DECM

JB 10H,DEC_H

JB 11H,DEC_M

RET

DECH: MOV 6FH,62H

ACALL BCD_HEX

DEC A

CJNE A,#0FFH,DECH1

MOV A,#23

DECH1: MOV 6FH,A

ACALL HEX_BCD

MOV 62H,A

MOV R1,#84H

MOV R0,62H

ACALL SETONE

RET

DECM: MOV 6FH,61H

ACALL BCD_HEX

DEC A

CJNE A,#0FFH,DECM1

MOV A,#59

DECM1: MOV 6FH,A

ACALL HEX_BCD

MOV 61H,A

MOV R1,#82H

MOV R0,61H

ACALL SETONE

RET

DEC_H: DEC 6BH

MOV A,6BH

CJNE A,#0FFH,DECH3

MOV 6BH,#23D

DECH3: MOV R1,#0C2H

MOV R0,6BH

ACALL SETONE

RET

DEC_M: DEC 6AH

MOV A,6AH

CJNE A,#0FFH,DECH4

MOV 6AH,#59D

DECH4: MOV R1,#0C0H

MOV R0,6AH

ACALL SETONE

RET

;--------------------------------RIGHT----------------------

RIGHT: JB 0EH,RIGHT1

JB 0FH,RIGHT2

JB 10H,RIGHT3

JB 11H,RIGHT4

RET ;右移

RIGHT1: CLR 0EH

SETB 0FH

RET

RIGHT2: CLR 0FH

SETB 10H

RET

RIGHT3: CLR 10H

SETB 11H

RET

RIGHT4: CLR 11H

SETB 0EH

RET

;--------------------------------LEFT-----------------------

LEFT: JB 0EH,LEFT1

JB 0FH,LEFT2

JB 10H,LEFT3

JB 11H,LEFT4

RET ;左移

LEFT1: SETB 11H

CLR 0EH

RET

LEFT2: SETB 0EH

CLR 0FH

RET

LEFT3: SETB 0FH

CLR 10H

RET

LEFT4: SETB 10H

CLR 11H

RET

;------------------------------MUTE--------------

MUTE: setb k_ON

CPL 06H ;静音

CLR 08H

RET

;-----------------------------DISPLAY OFF--------

DIS_OFF:CLR ET1

CPL 05H

JNB 05H,REDORE

SETB ET1

REDORE: RET

;------------------------------------初始化1302

SET1302: CLR RST ;2002年1月1日12:00:00

CLR LED3CLK

MOV SECOND,#0

MOV 61H,#0

MOV 62H,#18 ;

MOV 63H,#1

MOV 64H,#1

MOV 65H,#1

MOV 66H,#2

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#00H

LCALL R_BIT

SETB LED3CLK

CLR RST

MOV R0,#SECOND

MOV R7,#7

MOV R1,#80H

SET1302A:CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

MOV A,@R0

LCALL R_BIT

INC R0

INC R1

INC R1

SETB LED3CLK

CLR RST

DJNZ R7,SET1302A

CLR RST

CLR LED3CLK

sETB LED3CLK

nop

CLR RST

nop

clr led3clk

SETB RST

MOV A,#90H

LCALL R_BIT

MOV A,#10100101B ;充电器设置

LCALL R_BIT

SETB LED3CLK

CLR RST

CLR LED3CLK

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#80H

LCALL R_BIT

SETB LED3CLK

CLR RST

RET

;----------------------读取一RAM ------

T_6061: CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

LCALL W_BIT

SETB LED3CLK

CLR RST

RET

;-----------------------------

R_1302: MOV R0,#SECOND

MOV R7,#7

MOV R1,#81H

R_1302A: CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

LCALL W_BIT

MOV @R0,A

INC R0

INC R1

INC R1

SETB LED3CLK

CLR RST

DJNZ R7,R_1302A

RET

;------------------R_BIT------------------

R_BIT: MOV R4,#8

R_BIT1: RRC A

MOV LED4IO,C

SETB LED3CLK

CLR LED3CLK

DJNZ R4,R_BIT1

RET

;-------------------W_BIT-----------------------

W_BIT: MOV R4,#8

W_BIT1: MOV C,LED4IO

RRC A

SETB LED3CLK

CLR LED3CLK

DJNZ R4,W_BIT1

RET

;--------------------------------------------------

BCD_HEX:

MOV A,6FH

ANL A,#0FH

MOV B,A

MOV A,6FH

MOV 6FH,B

SWAP A

ANL A,#0FH

MOV B,#0AH

MUL AB

ADD A,6FH

;MOV 6FH,A

RET

HEX_BCD:

MOV A,6FH

MOV B,#10

DIV AB

SWAP A

ADD A,B

;MOV 6FH,A

RET

;-----写一地址---R1 为地址,R0 为数据----------

SETONE: CLR LED3CLK

CLR RST

CLR LED3CLK

NOP

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#00H

LCALL R_BIT

SETB LED3CLK

CLR RST

CLR LED3CLK

NOP

CLR RST

CLR LED3CLK

SETB RST

MOV A,R1

LCALL R_BIT

MOV A,R0

LCALL R_BIT

NOP

SETB LED3CLK

CLR RST

NOP

NOP

CLR RST

CLR LED3CLK

SETB RST

MOV A,#8EH

LCALL R_BIT

MOV A,#80H

LCALL R_BIT

SETB LED3CLK

CLR RST

RET

你好!

这里肯定是定义了一个变量数组;

变量的10,就是A

变量的12,就是L

变量的11,就是C

具体情况,你对照源代码看吧

以上就是关于用单片机设计一个数字时钟全部的内容,包括:用单片机设计一个数字时钟、用C语言编写AT89C51单片机程序,设计一个智能数字钟。、时钟程序单片机等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9289540.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存