導航:首頁 > 操作系統 > 單片機萬年歷c

單片機萬年歷c

發布時間:2023-09-25 09:08:08

單片機萬年歷的c語言程序

呵呵,這個東西我最近做過。也用過DS1302、PCF8563時鍾晶元,還算比較簡單啦。
只不過沒這么多功能,這些日子正想做個跟手錶一樣多的功能。等做完了,發給你把。你加我的網路Hi吧。
我可以幫助你,你先設置我最佳答案後,我網路Hii教你。

Ⅱ C51單片機的萬年歷程序設計

我這有個數碼管顯示的程序
以前做的,。。
你可以在我這個程序上修改修改
包括鍵盤掃描,還有動態顯示



【。。。】
#include
//常量參數
#define TMODW 0x01;
#define SCONW 0x00;
#define xplay 0x04;//顯示分頻系數
//顯示位選
unsigned char data stb;
//鍵值緩存,0xFF無鍵命令
unsigned char data keynum;
//顯示字型變數
unsigned char data play[8];
//工作參數
unsigned char data l,m;
//字型碼
unsigned char code BCDPC[10]=
{0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F};
//字位碼
unsigned char code STBCODE[8]=
{0x01,0x02,0x04,0x08,
0x10,0x20,0x40,0x80 };
//400Hz xplay分頻計數
unsigned char data cttime;
//時鍾參數
unsigned char data hr,min,sec,sec100;
//調整時鍾參數(時鍾「走」)
void ct1()
{sec100++;
if (sec100==100)
{sec100=0;sec++;
if (sec==60)
{sec=0;min++;
if (min==60)
{min=0;hr++;
if (hr==24) hr=0;
}
}
}
}
//時鍾參數→LED 顯示緩存7段參數轉換函數;
void xcplay()
{play[0]=BCDPC[hr/10];
play[1]=BCDPC[hr%10];
play[2]=BCDPC[min/10];
play[3]=BCDPC[min%10];
play[4]=BCDPC[sec/10];
play[5]=BCDPC[sec%10];
play[6]=BCDPC[sec100/10];
play[7]=BCDPC[sec100%10];
}
//顯示掃描
void cplay()
{T0=1;//T0-高電平消隱
T1=0;//T1-低電平準備發脈沖前沿
TI=0;//?
P1=0;//?
SBUF=STBCODE[stb];
while (TI==0)
{
};
TI=0;
SBUF=play[stb];
while (TI==0)
{
};
T1=1;
T0=0;
stb=++stb&0x07;
}

extern void cthl0();
//定時器0中斷處理程序
void ct0(void) interrupt 1 using 1
{cthl0();
cttime--;
if (cttime==0)
{cttime=xplay;
ct1();//調用時鍾「走」函數
xcplay();//調用時鍾參數→Led顯示緩存轉換函數
};
cplay();
}
void w20ms()
{for (l=0;l<41;l++)
{for (m=0;m<81;m++)
{
}
}
}
void tkey()
{P1=0xF0;
keynum=0xFF;
if (P1!=0xF0)
{w20ms();
P1=0xF0;
if (P1!=0xF0)
{P1=0xFE;
switch (P1)
{case 0xEE:keynum=0;break;
case 0xDE:keynum=1;break;
case 0xBE:keynum=2;break;
case 0x7E:keynum=3;break;
}
P1=0xFD;
switch (P1)
{case 0xED:keynum=4;break;
case 0xDD:keynum=5;break;
case 0xBD:keynum=6;break;
case 0x7B:keynum=7;break;
}
P1=0xFB;
switch (P1)
{
case 0xEB:keynum=8;break;
}
};
};
P1=0x00;
}
void command()
{switch (keynum)
{
case 0:{hr=hr+1;
if (hr==24)
hr=0;
}
break;

case 1:{min=min+1;
if (min==60)
min=0;
}
break;

case 2:{sec=sec+1;
if (sec==60)
sec=0;
}
break;

case 3:{sec100=0;
}
break;

case 4:{
while(!(P1=0xED))
{
hr=0;
min=0;
sec=0;
}
}
break;

case 5:{hr=hr-1;
if (hr==00)
hr=24;
}
break;
case 6:{min=min-1;
if (min==00)
min=59;
}
break;

case 7:{sec=sec-1;
if (sec==00)
sec=0;
}
break;

case 0xFF:break;
}
keynum=0xFF;
}
main ()
{ hr=8;
min=5;
sec=8;
sec100=0;
TMOD=TMODW;
SCON=SCONW;
ET0=1;
TR0=1;
EA=1;
cttime=xplay;
while (1)
{w20ms();
tkey();
command();

};
}

Ⅲ 單片機做萬年歷用數碼管的優缺點

優點,定時精準,缺點,電路復雜成本高。
數碼管萬年歷的設計原理是利用AT89C5單片機內部定時/計數器TO的模式2(8位自動重裝初值)產生一個時間為250us的信號,再計數4000次產生1S的時間後發出中斷,再由單片機進行數據處理後,送人數碼管(共陰極數碼管)顯示(動態顯示)。

Ⅳ 基於51單片機製作萬年歷,用數碼管,定時器,不用時鍾晶元,不用液晶,怎麼做求大神解,原理圖和C程序

基於51單片機製作萬年歷,用兩個8位一體的共陰數碼管,顯示日期和時間。數碼管位選用兩片74HC138,便於動態掃描顯示,又節省引腳。用3個按鍵調時,K1為選擇調時狀態,K2為加1鍵,K3為減1鍵。

模擬圖如下:

Ⅳ 跪求 51單片機+12864液晶+1302時鍾製成的萬年歷c程序

頂層文件 萬年歷.C
#include<reg51.h>
#include "LCD1602.h"
#include "DS1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit speaker=P2^4;
bit key_flag1=0,key_flag2=0;
SYSTEMTIME adjusted;
uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;
uchar data_alarm[7]={0};
/************鍵盤控制******************************/
int key_scan() //掃描是否有鍵按下
{ int i=0;
uint temp;
P1=0xf0;
temp=P1;
if(temp!=0xf0)
i=1;
else
i=0;
return i;
}
uchar key_value() //確定按鍵的值
{
uint m=0,n=0,temp;
uchar value;
uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} ;
P1=0xfe; temp=P1; if(temp!=0xfe)m=0;
P1=0xfd;temp=P1 ;if(temp!=0xfd)m=1;
P1=0xfb;temp=P1 ;if(temp!=0xfb)m=2;
P1=0xf7;temp=P1 ;if(temp!=0xf7)m=3;
P1=0xef;temp=P1 ;if(temp!=0xef)n=0;
P1=0xdf;temp=P1 ;if(temp!=0xdf)n=1;
P1=0xbf;temp=P1 ;if(temp!=0xbf)n=2;
value=v[m][n];
return value;
}
/***************************設置鬧鈴函數*******************************/
void naoling(void)
{
uchar i=0,l=0,j;
init1602();
while(key_flag2&&i<12)
if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=(j-'0')*10;else {data_alarm[l]+=(j-'0');l++;}i++;delay(600);}
write_com(0x01);
}
uchar according(void)
{ uchar k;
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1;
else k=0;
return k;
}
void speak(void)
{uint i=50;
while(i)
{speaker=0;
delay(1);
speaker=1;
delay(1);
i--;
}
}
void alarm(void)
{uint i=10;
while(i)
{
speak();
delay(10);
i--;
}
}
/**************************修改時間操作********************************/
void reset(void)
{
sec_add=0;
min_add=0;
hou_add=0;
day_add=0;
mon_add=0;
yea_add=0 ;
}
void adjust(void)
{

if(key_scan()&&key_flag1)
switch(key_value())
{case '0':sec_add++;break;
case '1':min_add++;break;
case '2':hou_add++;break;
case '3':day_add++;break;
case '4':mon_add++;break;
case '5':yea_add++;break;
case 'b':reset();break;
default: break;
}
adjusted.Second+=sec_add;
adjusted.Minute+=min_add;
adjusted.Hour+=hou_add;
adjusted.Day+=day_add;
adjusted.Month+=mon_add;
adjusted.Year+=yea_add;
if(adjusted.Second>59) adjusted.Second=adjusted.Second%60;

if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60;

if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24;

if(adjusted.Day>31) adjusted.Day=adjusted.Day%31;

if(adjusted.Month>12) adjusted.Month=adjusted.Month%12;

if(adjusted.Year>100) adjusted.Year=adjusted.Year%100;

}

/**************************中斷處理函數*********************************/
void changing(void) interrupt 0 using 0 //需要修改時間和日期,或者停止修改
{
if(key_flag1)key_flag1=0;
else key_flag1=1;
}
void alarming(void) interrupt 3 using 0 //需要設置鬧鈴或者停止設置
{
if(key_flag2)key_flag2=0;
else key_flag2=1;
}
/********************************主函數***********************************/
main()
{uint i;
uchar *l;
uchar p1[]="D:",p2[]="T:";
SYSTEMTIME T;
EA=1;
EX0=1;
IT0=1;
EA=1;
EX1=1;
IT1=1;
init1602();
Initial_DS1302() ;

while(1)
{ write_com(0x80);
write_string(p1,2);
write_com(0xc0);
write_string(p2,2);
DS1302_GetTime(&T) ;
adjusted.Second=T.Second;
adjusted.Minute=T.Minute;
adjusted.Hour=T.Hour;
adjusted.Week=T.Week;
adjusted.Day=T.Day;
adjusted.Month=T.Month;
adjusted.Year=T.Year;
for(i=0;i<9;i++)
{
adjusted.DateString[i]=T.DateString[i];
adjusted.TimeString[i]=T.TimeString[i];
}
adjust();
if(key_flag2)naoling();
if(according())alarm();
DateToStr(&adjusted);
TimeToStr(&adjusted);
write_com(0x82);
write_string(adjusted.DateString,8);
write_com(0xc2);
write_string(adjusted.TimeString,8);
delay(10);
}
(二)頭文件1 顯示模塊 LCD1602.H
#ifndef LCD_CHAR_1602_2009_5_9
#define LCD_CHAR_1602_2009_5_9
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs = P2^0;
sbit lcdrw = P2^1;
sbit lcden = P2^2;
void delay(uint z) // 延時
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) // 寫入指令數據到 lcd
{
lcdrw=0;
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}

void write_data(uchar date) // 寫入字元顯示數據到 lcd
{
lcdrw=0;
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init1602() // 初始化設定
{
lcdrw=0;
lcden=0;
write_com(0x3C);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void write_string(uchar *pp,uint n)
{
int i;
for(i=0;i<n;i++)
write_data(pp[i]);
}
#endif
(三)頭文件2 時鍾模塊 DS1302.H
#ifndef _REAL_TIMER_DS1302_2009_5_20_
#define _REAL_TIMER_DS1302_2003_5_20_

sbit DS1302_CLK = P2^6; //實時時鍾時鍾線引腳
sbit DS1302_IO = P2^7; //實時時鍾數據線引腳
sbit DS1302_RST = P2^5; //實時時鍾復位線引腳
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;

typedef struct SYSTEM_TIME
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9]; //用這兩個字元串來放置讀取的時間
unsigned char TimeString[9];
}SYSTEMTIME; //定義的時間類型

#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
#define DS1302_RAM(X) (0xC0+(X)*2) //用於計算 DS1302_RAM 地址的宏

/******內部指令**********/
void DS1302InputByte(unsigned char d) //實時時鍾寫入一位元組(內部函數)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0;
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1; //因為在前面已經定義了ACC0 = ACC^0;以便再次利用DS1302_IO = ACC0;
}
}

unsigned char DS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
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_SetProtect(bit flag) //是否防寫
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}

void DS1302_SetTime(unsigned char Address, unsigned char Value) // 設置時間函數
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10))); //將十進制數轉換為BCD碼
} //在DS1302中的與日歷、時鍾相關的寄存器存放的數據必須為BCD碼形式

void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將BCD碼轉換為十進制數
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);
}
unsigned char *DataToBCD(SYSTEMTIME *Time)
{
unsigned char D[8];
D[0]=Time->Second/10<<4+Time->Second%10;
D[1]=Time->Minute/10<<4+Time->Minute%10;
D[2]=Time->Hour/10<<4+Time->Hour%10;
D[3]=Time->Day/10<<4+Time->Day%10;
D[4]=Time->Month/10<<4+Time->Month%10;
D[5]=Time->Week/10<<4+Time->Week%10;
D[6]=Time->Year/10<<4+Time->Year%10;
return D;
}
void DateToStr(SYSTEMTIME *Time)
{
//將十進制數轉換為液晶顯示的ASCII值
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}

void TimeToStr(SYSTEMTIME *Time)
{
//將十進制數轉換為液晶顯示的ASCII值
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->DateString[8] = '\0';
}
void Initial_DS1302(void)
{
unsigned char Second;
Second=Read1302(DS1302_SECOND);
if(Second&0x80) //初始化時間
DS1302_SetTime(DS1302_SECOND,0);
}
void DS1302_TimeStop(bit flag) // 是否將時鍾停止
{
unsigned char Data;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND, Data|0x80);
else
Write1302(DS1302_SECOND, Data&0x7F);
}
#endif

Ⅵ 急求PROTUES實現萬年歷 單片機C語言程序做的 HEX文件 源程序和模擬圖

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit db=P2^7;
char i,sec,min,h,date,month,year,flag;
uchar j,k,m,n,o,p;
sbit la=P2^0;
sbit wela1=P2^1;
sbit wela2=P2^2;
sbit key_ch=P3^5;
sbit key_add=P3^6;
sbit key_minus=P3^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void init();
void delay(uint);
void second_display();
void minute_display();
void hour_display();
void date_display();
void month_display();
void year_display();
void control();
void time();
void main()
{
init();
while(1)
{
second_display();
minute_display();
hour_display();
date_display();
month_display();
year_display();
control();
}
}
void init()
{
db=0;
i=0;
sec=0;
min=0;
h=0;
date=1;
month=1;
year=1;
flag=0;
wela1=0;
wela2=0;
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void second_display()
{
int sec_shi,sec_ge;
sec_shi=sec/10;
sec_ge=sec%10;

if(flag==1&&j!=1)
j++;
else
{
j=0;
la=1;
P0=~table[sec_ge];
la=0;
wela1=1;
P1=0x00;
wela1=0;
wela2=1;
P1=0x20;
wela2=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[sec_shi];
la=0;
wela1=1;
P1=0x00;
wela1=0;
wela2=1;
P1=0x10;
wela2=0;
delay(1);
la=1;
P0=0xff;
la=0;
}
}
void minute_display()
{
int min_shi,min_ge;
min_shi=min/10;
min_ge=min%10;

if(flag==2&&k!=1)
k++;
else
{
k=0;
la=1;
P0=~table[min_ge];
la=0;
wela1=1;
P1=0x00;
wela1=0;
wela2=1;
P1=0x08;
wela2=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[min_shi];
la=0;
wela1=1;
P1=0x00;
wela1=0;
wela2=1;
P1=0x04;
wela2=0;
delay(1);
la=1;
P0=0xff;
la=0;
}
}
void hour_display()
{
int h_shi,h_ge;
h_shi=h/10;
h_ge=h%10;

if(flag==3&&m!=1)
m++;
else
{
m=0;
la=1;
P0=~table[h_ge];
la=0;
wela1=1;
P1=0x00;
wela1=0;
wela2=1;
P1=0x02;
wela2=0;
delay(1);
la=1;
P0=0xff;
la=0;
delay(1);

la=1;
P0=~table[h_shi];
la=0;
wela1=1;
P1=0x00;
wela1=1;
P1=0x00;
wela1=0;
wela2=1;
P1=0x01;
wela2=0;
delay(1);
la=1;
P0=0xff;
la=0;
wela2=0;
delay(1);
}

}
void date_display()
{
int date_shi,date_ge;
date_shi=date/10;
date_ge=date%10;

if(flag==4&&n!=1)
n++;
else
{
n=0;
la=1;
P0=~table[date_ge];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x80;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[date_shi];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x40;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;
}
}
void month_display()
{
int month_shi,month_ge;
month_shi=month/10;
month_ge=month%10;

if(flag==5&&o!=1)
o++;
else
{
o=0;
la=1;
P0=~table[month_ge];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x20;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[month_shi];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x10;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;
}
}
void year_display()
{
int year_qian,year_,year_shi,year_ge;
year_qian=year/1000;
year_=year%1000/100;
year_shi=year%1000%100/10;
year_ge=year%10;

if(flag==6&&p!=1)
p++;
else
{
p=0;
la=1;
P0=~table[year_ge];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x08;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[year_shi];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x04;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[year_];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x02;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;

la=1;
P0=~table[2];
la=0;
wela2=1;
P1=0x00;
wela2=0;
wela1=1;
P1=0x01;
wela1=0;
delay(1);
la=1;
P0=0xff;
la=0;
wela1=0;
}
}
void control()
{
if(!key_ch)
{
delay(5);
if(!key_ch)
{
flag++;
if(flag==7)
flag=0;
}
}
while(!key_ch);
if(flag==1&&key_add==0)
{
while(!key_add);
sec++;
if(sec==60)
sec=0;
}
if(flag==1&&key_minus==0)
{
while(!key_minus);
sec--;
if(sec==-1)
sec=59;
}

if(flag==2&&key_add==0)
{
while(!key_add);
min++;
if(min==60)
min=0;
}
if(flag==2&&key_minus==0)
{
while(!key_minus);
min--;
if(min==-1)
min=59;
}

if(flag==3&&key_add==0)
{
while(!key_add);
h++;
if(h==24)
h=0;
}
if(flag==3&&key_minus==0)
{
while(!key_minus);
h--;
if(h==-1)
h=23;
}

if(flag==4&&key_add==0)
{
while(!key_add);
date++;
if(date==29)
if((year%4!=0)&&(month==2))
date=1;
if(date==30)
if((year%4==0)&&(month==2))
date=1;
if(date==31)
if((month==4)||(month==6)||(month==9)||(month==11))
date=1;
if(date==32)
if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
date=1;
}

if(flag==5&&key_add==0)
{
while(!key_add);
month++;
if(month==13)
month=1;
}
if(flag==5&&key_minus==0)
{
while(!key_minus);
month--;
if(month==0)
month=12;
}

if(flag==6&&key_add==0)
{
while(!key_add);
year++;
if(year==99)
year=1;
}
if(flag==6&&key_minus==0)
{
while(!key_minus);
year--;
if(year==0)
year=99;
}
}

void T0_rpt() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
i++;
time();
}

void time()
{
if(i==20)
{
i=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
h++;
if(h==24)
{
h=0;
min=0;
sec=0;
date++;
if(date==29)
if((year%4!=0)&&(month==2))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
if(date==30)
if((year%4==0)&&(month==2))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
if(date==31)
if((month==4)||(month==6)||(month==9)||(month==11))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
if(date==32)
if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
}
}
}
}
}

Ⅶ 求個用單片機c語言實現的萬年歷

/*============================================================
使用1602液晶顯示DS1302+S51時鍾+溫度顯示
==============================================================
//更新歷史:增加溫度顯示,調整時閃動。
// 增加零下溫度顯示

SMC1602A(16*2)模擬口線接線方式
連接線圖:
---------------------------------------------------
|LCM-----51 | LCM-----51 | LCM------51 |
---------------------------------------------|
|DB0-----P1.0 | DB4-----P1.4 | RS-------P2.0 |
|DB1-----P1.1 | DB5-----P1.5 | RW-------P2.1 |
|DB2-----P1.2 | DB6-----P1.6 | E--------P2.2 |
|DB3-----P1.3 | DB7-----P1.7 | VLCD接1K電阻到GND|
---------------------------------------------------
DS1302 接線圖

Vcc2 CLK I/O /RST

| | | |
--------------
| 8 7 6 5|
| DS1302 |
| |
| 1 2 3 4|
--------------
| | | |
VCC1 GND

1 腳接+5V 2,3腳32768HZ晶振 4腳接地 5腳接S51的P02 6腳接S51的P01 7接S51的P00
8腳接後備電源,可以接老計算機主板上的3.6V電池,也可以通過二級管隔離接一個大容量電解電容
電壓在2.5V以上即可維持

按鍵說明:1. 共三個鍵,低電平有效
2. P04 和 P05 同時按:初始化
3. P06 埠按鍵:選擇要調整的項目
4. P05 埠按鍵:增加;P04埠按鍵:減少
[注:AT89S51使用12M晶振]
=============================================================*/
/*#include <AT89x51.h>*/
#include <REGX51.H>
#include <string.h>
#include<intrins.h>

#define LCM_RS P2_0 //定義引腳
#define LCM_RW P2_1
#define LCM_E P2_2
#define LCM_Data P0
#define Busy 0x80 //用於檢測LCM狀態字中的Busy標識
#define uchar unsigned char

uchar id,timecount;
bit flag,sflag; //flag是時鍾冒號閃爍標志,sflag是溫度負號顯示標志
void Disp_line1(void); //顯示屏幕第一行
void Disp_line2(void); //顯示屏幕第二行
void id_case1_key();

//*********** DS1302 時間顯示定義部分
sbit T_CLK=P1^0;
sbit T_IO =P1^1;
sbit T_RST=P1^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
void Set(uchar,uchar); //根據選擇調整相應項目
void RTInputByte(uchar); /* 輸入 1Byte */
uchar RTOutputByte(void); /* 輸出 1Byte */
void W1302(uchar, uchar); // 向DS1302寫入一個位元組
uchar R1302(uchar); // 從DS1302讀出一個位元組
void Set1302(unsigned char * ); // 設置時間
bit sec,min,hour,year,mon,day,weekk; //閃爍標志位
//初始化後設置為:04年12月2日星期4 0點0分0秒
unsigned char inittime[7]={0x00,0x00,0x00,0x02,0x12,0x04,0x04};
// 秒 分鍾 小時 日 月 年 星期

//***** 18B20溫度顯示定義部分
sbit DQ=P3^3; //18B20 接P07口
typedef unsigned char byte;
typedef unsigned int word;
Read_Temperature(char,char);
void mychar(void);
void adjust_res(char res); //res 分別等於 0x1f, 0x3f, 0x5f 溫度讀數解析度分別對應
// 0.5, 0.25, 0.125
//******* 1602LCD驅動 **********************************************************
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
unsigned char code week[]={"Week."};

void main(void)
{
Delay400Ms(); //啟動等待,等LCM講入工作狀態
LCMInit(); //LCM初始化
Delay5Ms(); //延時片刻(可不要)
mychar(); //顯示自定義字元

TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
TR0=1;
ET0=1;
W1302(0x90,0xa5);//打開充電二級管 一個二級管串聯一個2K電阻
W1302(0x8e,0x80);//防寫,禁止寫操作
adjust_res(0x1f); //調整18B20的解析度 0x1f:0.5; 0x3f:0.25; 0x5f:0.125
while(1)
{
if ((P1_4|P1_5)==0) //初始化
{
Delay5Ms();
if ((P1_4|P1_5)==0) Set1302(inittime);
}
if (P1_6==0) // 設置和選擇項目鍵
{
Delay5Ms();
if(P1_6==0){id++;if(id>7) id=0;}
while(P1_6==0);
}
switch(id)
{
case 0:
sec=0;
Disp_line1(); Disp_line2();
break;
case 1://年
year=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 2://月
year=0;mon=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 3://日
mon=0;day=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 4://星期
day=0;weekk=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 5://小時
weekk=0;hour=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 6://分鍾
hour=0;min=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
case 7://秒
min=0;sec=1;
Disp_line1(); Disp_line2();
id_case1_key();
break;
}
}
}

//中斷入口,冒號閃爍
void t0(void) interrupt 1 using 0
{
TH0=(65535-50000)/256; //50ms定時
TL0=(65535-50000)%256;
timecount++;
if(timecount>9)
{
timecount=0;
flag=~flag;
}
}
//id為1時的下一級選擇
void id_case1_key()
{
if (P1_5==0) //增加
{
Delay5Ms();
if(P1_5==0) Set(id,0);
if(id!=7) while(P1_5==0);
}
if (P1_4==0) //減少
{
Delay5Ms();
if(P1_4==0) Set(id,1);
if(id!=7) while(P1_4==0);
}
}

//根據選擇調整相應項目並寫入DS1302
void Set(uchar sel,uchar sel_1)
{
signed char address,item;
signed char max,mini;
if(sel==7) {address=0x80; max=0;mini=0;} //秒
if(sel==6) {address=0x82; max=59;mini=0;} //分鍾
if(sel==5) {address=0x84; max=23;mini=0;} //小時
if(sel==3) {address=0x86; max=31;mini=1;} //日
if(sel==2) {address=0x88; max=12;mini=1;} //月
if(sel==1) {address=0x8c; max=99;mini=0;} //年
if(sel==4) {address=0x8a; max=7; mini=1;} //星期

item=R1302(address+1)/16*10+R1302(address+1)%16;
if (sel_1==0) item++; else item--;
if(item>max) item=mini;
if(item<mini) item=max;

W1302(0x8e,0x00);//允許寫操作
W1302(address,item/10*16+item%10);
W1302(0x8e,0x80);//防寫,禁止寫操作
}

//屏幕顯示第一行 時間和溫度
void Disp_line1(void)
{
Read_Temperature(10,0); //溫度顯示
//冒號閃爍
if(flag==0)
{DisplayOneChar(3,0,0x3a); DisplayOneChar(6,0,0x3a);}
else
{DisplayOneChar(3,0,0x20); DisplayOneChar(6,0,0x20);}

if(sec==1) //秒閃爍標志位
{
if(flag==1)
{
DisplayOneChar(7,0,R1302(0x81)/16+0x30); //顯示秒
DisplayOneChar(8,0,R1302(0x81)%16+0x30);
}
else
{
DisplayOneChar(7,0,0x20); //顯示秒
DisplayOneChar(8,0,0x20);
}
}
else
{
DisplayOneChar(7,0,R1302(0x81)/16+0x30); //顯示秒
DisplayOneChar(8,0,R1302(0x81)%16+0x30);
}

if(min==1) //分鍾閃爍標志位
{
if(flag==1)
{
DisplayOneChar(4,0,R1302(0x83)/16+0x30); //顯示分鍾
DisplayOneChar(5,0,R1302(0x83)%16+0x30);
}
else
{
DisplayOneChar(4,0,0x20); //顯示分鍾
DisplayOneChar(5,0,0x20);
}
}
else
{
DisplayOneChar(4,0,R1302(0x83)/16+0x30); //顯示分鍾
DisplayOneChar(5,0,R1302(0x83)%16+0x30);
}

if(hour==1) //小時閃爍標志位
{
if(flag==1)
{
DisplayOneChar(1,0,R1302(0x85)/16+0x30);//顯示小時
DisplayOneChar(2,0,R1302(0x85)%16+0x30);
}
else
{
DisplayOneChar(1,0,0x20); //顯示小時
DisplayOneChar(2,0,0x20);
}
}
else
{
DisplayOneChar(1,0,R1302(0x85)/16+0x30);//顯示小時
DisplayOneChar(2,0,R1302(0x85)%16+0x30);
}
}

// 屏幕顯示第二行 日期和星期
void Disp_line2(void)
{
DisplayOneChar(3,1,0x2f); //顯示固定字元
DisplayOneChar(6,1,0x2f);
DisplayListChar(10,1,week);

if(year==1) //年閃爍標志位
{
if(flag==1)
{
DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//顯示年
DisplayOneChar(2,1,R1302(0x8d)%16+0x30);
}
else
{
DisplayOneChar(1,1,0x20); //顯示年
DisplayOneChar(2,1,0x20);
}
}
else
{
DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//顯示年
DisplayOneChar(2,1,R1302(0x8d)%16+0x30);
}

if(mon==1) //月閃爍標志位
{
if(flag==1)
{
DisplayOneChar(4,1,R1302(0x89)/16+0x30);//顯示月
DisplayOneChar(5,1,R1302(0x89)%16+0x30);
}
else
{
DisplayOneChar(4,1,0x20); //顯示月
DisplayOneChar(5,1,0x20);
}
}
else
{
DisplayOneChar(4,1,R1302(0x89)/16+0x30);//顯示月
DisplayOneChar(5,1,R1302(0x89)%16+0x30);
}

if(day==1) //日閃爍標志位
{
if(flag==1)
{
DisplayOneChar(7,1,R1302(0x87)/16+0x30);//顯示日
DisplayOneChar(8,1,R1302(0x87)%16+0x30);
}
else
{
DisplayOneChar(7,1,0x20); //顯示日
DisplayOneChar(8,1,0x20);
}
}
else
{
DisplayOneChar(7,1,R1302(0x87)/16+0x30);//顯示日
DisplayOneChar(8,1,R1302(0x87)%16+0x30);
}

if(weekk==1) //星期閃爍標志位
{
if(flag==1)
{
DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//顯示星期
}
else
{
DisplayOneChar(15,1,0x20); //顯示星期
}
}
else
{
DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//顯示星期
}
}

//********* LCM1602驅動程序 ***************
//寫數據
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //檢測忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在這後加小的延時
LCM_E = 0; //延時
LCM_E = 1;
}
//寫指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測
{
if (BuysC) ReadStatusLCM(); //根據需要檢測忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
//讀狀態
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //檢測忙信號
return(LCM_Data);
}
//LCM初始化
void LCMInit(void)
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
WriteCommandLCM(0x08,1); //關閉顯示
WriteCommandLCM(0x01,1); //顯示清屏
WriteCommandLCM(0x06,1); // 顯示游標移動設置
WriteCommandLCM(0x0C,1); // 顯示開及游標設置
}
//按指定位置顯示一個字元
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大於15,Y不能大於1
if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40;
X |= 0x80; //算出指令碼
WriteCommandLCM(X, 0); //這里不檢測忙信號,發送地址碼
WriteDataLCM(DData);
}
//按指定位置顯示一串字元 ***原來的遇到空格0x20就不顯示***
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength,j;
ListLength = strlen(DData);
Y &= 0x1;
X &= 0xF; //限制X不能大於15,Y不能大於1
if (X <= 0xF) //X坐標應小於0xF
{
for(j=0;j<ListLength;j++)
{
DisplayOneChar(X, Y, DData[j]); //顯示單個字元
X++;
}
}
}
//5ms延時
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//400ms延時
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}

Ⅷ 設計一個基於單片機的萬年歷程序

#include<reg51.h>
#include"lcd.h"
#include"ds1302.h"

sbitK1=P3^1;
sbitK2=P3^0;
sbitK3=P3^2;
sbitK4=P3^3; //管腳接線
unsignedcharcharacter0[24]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02 ,
0x0F,0x09,0x0F,0x09,0x0F,0x09,0x13,0x00,//"月"代碼0x01
0x0F,0x09,0x09,0x0F,0x09,0x09,0x0F,0x00,//"日"代碼0x02
};//年
voidInt0Configuration();
voidLcdDisplay();
unsignedcharSetState,SetPlace;
voidDelay10ms(void);//誤差0us
/*******************************************************************************
*函數名:main
*函數功能 :主函數
*輸入:無
*輸出 :無
*******************************************************************************/

voidmain()
{
unsignedchari,h;
Int0Configuration();
LcdInit();
LcdWriteCom(0x40);
for(h=0;h<24;h++)
{
LcdWriteData(character0[h]);
}
LcdWriteCom(0x80);

// Ds1302Init();
while(1)
{
if(SetState==0)
{
Ds1302ReadTime();
}
else
{
if(K1==0) //檢測按鍵K1是否按下
{
Delay10ms(); //消除抖動
if(K1==0)
{
SetPlace++;
if(SetPlace>=7)
SetPlace=0;
}

while((i<50)&&(K1==0)) //檢測按鍵是否松開
{
Delay10ms();
i++;
}
i=0;
}
if(K2==0) //檢測按鍵K2是否按下
{
Delay10ms(); //消除抖動
if(K2==0)
{
TIME[SetPlace]++;
if((TIME[SetPlace]&0x0f)>9) //換成BCD碼。
{
TIME[SetPlace]=TIME[SetPlace]+6;
}
if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //分秒只能到59
{
TIME[SetPlace]=0;
}
if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小時只能到23
{
TIME[SetPlace]=0;
}
if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31
{
TIME[SetPlace]=0;
}
if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12
{
TIME[SetPlace]=0;
}
if((TIME[SetPlace]>=0x7)&&(SetPlace==5)) //周只能到7
{
TIME[SetPlace]=1;
}
// if(SetPlace==5) //月只能到12
// {
// TIME[SetPlace]=;
// }
}

while((i<50)&&(K2==0)) //檢測按鍵是否松開
{
Delay10ms();
i++;
}
i=0;

}
}
LcdDisplay();


}

}
/*******************************************************************************
*函數名:LcdDisplay()
*函數功能 :顯示函數
*輸入:無
*輸出 :無
*******************************************************************************/

voidLcdDisplay()
{
LcdWriteCom(0x80+0X40);

LcdWriteCom(0x0f);
LcdWriteCom(0xc0|(2-0x40));
LcdWriteCom(0x0c);
Delay10ms();
LcdWriteData('0'+TIME[2]/16); //時
LcdWriteData('0'+(TIME[2]&0x0f));
LcdWriteData(':');
LcdWriteData('0'+TIME[1]/16); //分
LcdWriteData('0'+(TIME[1]&0x0f));
LcdWriteData(':');
LcdWriteData('0'+TIME[0]/16); //秒
LcdWriteData('0'+(TIME[0]&0x0f));

LcdWriteCom(0x80);
LcdWriteData('2');
LcdWriteData('0');
LcdWriteData('0'+TIME[6]/16); //年
LcdWriteData('0'+(TIME[6]&0x0f));
LcdWriteData(0x00);
LcdWriteData('0'+TIME[4]/16); //月
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData(0x01);
LcdWriteData('0'+TIME[3]/16); //日
LcdWriteData('0'+(TIME[3]&0x0f));
LcdWriteData(0x02);
LcdWriteCom(0x8D);
LcdWriteData('0'+(TIME[5]&0x07)-1); //星期
}
/*******************************************************************************
*函數名:Int0Configuration()
*函數功能 :配置外部中斷0
*輸入:無
*輸出 :無
*******************************************************************************/

voidInt0Configuration()
{
//設置INT0
IT0=1;//跳變沿出發方式(下降沿)
EX0=1;//打開INT0的中斷允許。
EA=1;//打開總中斷
}
/*******************************************************************************
*函數名:Int0()
*函數功能 :外部中斷0中斷函數
*輸入:無
*輸出 :無
*******************************************************************************/

voidInt0()interrupt0
{
Delay10ms();
if(K3==0)
{
SetState=~SetState;
SetPlace=0;
Ds1302Init();
}
}
/*******************************************************************************
*函數名:Delay10ms
*函數功能 :延時函數,延時10ms
*輸入:無
*輸出 :無
*******************************************************************************/
voidDelay10ms(void)//誤差0us
{
unsignedchara,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}

閱讀全文

與單片機萬年歷c相關的資料

熱點內容
如何用自己電腦做伺服器做網頁 瀏覽:130
伺服器安全配置要考什麼證書 瀏覽:633
ipadpro可以編程 瀏覽:541
外國的程序員和中國的程序員 瀏覽:149
抖音小店app如何聯系客服 瀏覽:975
linux打開多個終端 瀏覽:500
linux中的命令 瀏覽:573
優化小米6相機演算法 瀏覽:259
ak47pdf 瀏覽:150
人與文化pdf 瀏覽:640
原子幣app在哪裡注冊的 瀏覽:529
php數組保存文件 瀏覽:226
無理的命令 瀏覽:510
問道手游解壓失敗是什麼原因 瀏覽:776
mysql命令提示 瀏覽:373
apachephp中文亂碼 瀏覽:342
pythonimportpylab 瀏覽:238
阿里雲app伺服器價格表 瀏覽:981
appstore怎麼搶手機 瀏覽:845
列印伺服器是什麼列印隊列 瀏覽:359