導航:首頁 > 操作系統 > 單片機萬年歷程序怎樣讀取時間

單片機萬年歷程序怎樣讀取時間

發布時間:2023-03-27 04:45:51

㈠ 我想做一個單片機控制的家用萬年歷,顯示時間,溫度。希望高手指點指點,(我要買什麼部件,和程序怎麼寫)

為了學習的話,可以用單片機內部定時器做時間顯示,也可以用樓上說的專用晶元;溫度感測器用18B20,簡單,同時可以學習單匯流排,也可以用熱敏電阻,可以學習ADC轉換控制。建議先用proteus模擬,模擬成功了,可散槐以用洞洞板自己焊,畢竟出電路板的話還要學PCB軟體,做PCB的話自己用光刻板做也比較麻煩,發廠家做成本較高;買個STC89C52(串口下載,方便),做個最小系統,測試沒問題了,加入顯示電路(數碼管 or LCD1602都行),搞定。
可以看一沖桐友下郭天祥的書和視頻教輪閉程~

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

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

㈢ 求大神解答下單片機80c51,下面程序中的一個能夠讓萬年歷調時間的代碼,求大神告訴下這些代碼

DS_WriteBCDBata(0x80,second|0x80);

這個函數應該是把秒寫到DS1302晶元的秒寄存器中,秒的寄存器的地址上80和81兩個地址(寄存器0)。寄存器0中最高位 CH 是一個時鍾停止標志位。如果時鍾電路有備用電源,上電後,我們要先檢測一下這一位,如果這一位是 0,那說明時鍾晶元在系統掉電後,由於備用電源的供給,時鍾是持續正常運行的;如果這一位是 1,那麼說明時鍾晶元在系統掉電後,時鍾部分不工作了。如果 Vcc1 懸空或者是電池沒電了,當我們下次重新上電扒鎮襪孫時,讀取這一位,那這一位就是 1,我們可以通過這一位判斷時鍾在單片機系統掉電後是否還正常運行。剩下的7 位高 3 位是秒的十位,低 4 位是秒的個位,這里再提請注意一次春好粗,DS1302 內部是 BCD 碼,而秒的十位最大是 5,所以 3 個二進制位就夠了。second|0x80後面的這個數據使用 | 符號就是把最高位CH變成1.

㈣ 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();

};
}

㈤ 跪求 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

㈥ 基於AT89C51單片機的萬年歷。。。求大神,求指導

/*****************************ds18b20.H*******************************/
#ifndef DS_18B20_H
#define DS_18B20_H
sbit DQ=P2^4; //定義埠temp
uchar tt;
//uchar code tab1[]={"Temp:"};
uchar code tab2[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
/*延時函數us*/
void Delay(uchar num)
{
while( num-- );
}
void DS18B20_Init(void)//初始化ds1820
{
uchar x = 0;
DQ = 1; /猛搭/temp復位
Delay(16);
DQ = 0; //單片機將temp拉低
Delay(100); //精確延時 大於 480us
DQ = 1; //拉高匯流排
Delay(4);
x = DQ; //檢測存在脈沖,在此未使用x,自己玩沒加
Delay(60);
// return x;
}
uchar DS18B20_ReadOneChar(void)//讀一個位元組
{
uchar i = 0;
uchar dat = 0;
for (i = 8; i > 0; i--)
{
DQ=1;
_nop_();
DQ = 0; // 給脈沖信號
dat >>= 1;
DQ = 1; // 給脈沖信號
if(DQ)
dat |= 0x80;
Delay(4);
}
return (dat);
}
void DS18B20_WriteOneChar(unsigned char dat)//寫枝備拿一個位元組
{
unsigned char i = 0;
for (i = 8; i > 0; i--)
{
DQ=1;
_nop_();_nop_();_nop_();_nop_();
DQ = 0;
Delay(1);//注意
DQ = dat&0x01;
Delay(5);
DQ = 1;
dat>>=1;
}
}
uint DS18B20_Read_Disp_Temperature(void)/滾罩/讀取並顯示溫度
{
uint th,tl,t = 0;
DS18B20_Init();
DS18B20_WriteOneChar(0xCC); // 跳過讀序號列號的操作
DS18B20_WriteOneChar(0x44); // 啟動溫度轉換
Delayms(50);
DS18B20_Init();
DS18B20_WriteOneChar(0xCC); //跳過讀序號列號的操作
DS18B20_WriteOneChar(0xBE);
tl = DS18B20_ReadOneChar(); //讀取溫度寄存器
th = DS18B20_ReadOneChar();
t=th<<4; //轉化成位元組溫度
t +=(tl&0xf0)>>4; //整數部分
tt=tab2[tl&0x0f]; //小數部分(查表對照,獲取小數位)
return t;
}
/*void main()
{
Initialization_LCD_1602();
while(1)
{
uchar Gw,Sw;
Gw=DS18B20_Read_Disp_Temperature()%10;//取得個位數字
Sw=DS18B20_Read_Disp_Temperature()/10;//取得十位數字
Pos(2);
Show_String(tab1);
Pos(7);//er是頭文件規定的值0x80+0x40
Write_LCD_1602_Data(0x30+Sw);//數字+30得到該數字的LCD1602顯示碼
Write_LCD_1602_Data(0x30+Gw);//數字+30得到該數字的LCD1602顯示碼
Write_LCD_1602_Data(0x2e);
Write_LCD_1602_Data(tt+0x30);
Write_LCD_1602_Data(0xdf);//顯示溫度的小圓圈符號,0xdf是液晶屏字元庫的該符號地址碼
Write_LCD_1602_Data(0x43);//顯示"C"符號,0x43是液晶屏字元庫里大寫C的地址碼
}
}*/
#endif
/************************************LCD1602.H*****************************************/
#ifndef LCD_1602_H
#define LCD_1602_H
//#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS=P2^7;
sbit LCD_RW=P2^6;
sbit LCD_EN=P2^5;
void Delayms(uint x)
{
uchar i;
while(x--)for(i=0;i<110;i++);//at:125;stc:600
}
/*write command*/
void Write_LCD_1602_Command(uchar com)
{
LCD_RS=0;//write lcd1602 command
LCD_RW=0;//write
P0=com;//data
Delayms(1);
LCD_EN=1;
Delayms(1);
LCD_EN=0;
}
/*write data*/
void Write_LCD_1602_Data(uchar dat)
{
LCD_RS=1;
LCD_RW=0;
P0=dat;
LCD_EN=1;
Delayms(1);
LCD_EN=0;
Delayms(1);
}
/*Initialization LCD_1602*/
void Initialization_LCD_1602()
{
Write_LCD_1602_Command(0x38);
Delayms(1);
Write_LCD_1602_Command(0x0c);
Delayms(1);
Write_LCD_1602_Command(0x06);
Delayms(1);
Write_LCD_1602_Command(0x01);
Delayms(1);
}
void Pos(uchar pos)
{
Write_LCD_1602_Command(0x80+pos);
//return 0;
}
void Show_String(uchar *str)
{
while(*str!='\0')
{
Write_LCD_1602_Data(*str);
str++;
}
}
#endif
/**************************************MAIN.C**********************************/
#include <reg52.h>
#include <intrins.h>
#include "lcd1602.h"
#include "ds18B20.h"
#define uint unsigned int
#define uchar unsigned char

/*DS1302IO定義*/
sbit SCK=P1^2;
sbit SDA=P1^3;
sbit RST=P1^4;
/*設定時間鍵*/
sbit key0=P1^0;//設定
sbit key1=P1^1; //分+
sbit key2=P1^5;//時+
sbit key3=P1^6;//確認
uchar key1m;
uchar Second, Minute,Hour,Week,Day,Month,Year;//DateString[9],TimeString[9];
uchar Data_String[13];
uchar Time_String[12];
/*延時*/
/*void DelayUs(uint x)
{
while(x--);
}*/
/*寫一位元組*/
void Write_One_Char(uchar dat)
{
uchar i;
//RST=1;
for(i=0;i<8;i++)
{
SDA = dat & 0x01;
SCK = 1;
SCK = 0;
dat >>= 1;
SCK = 0;
}
}
/*讀一位元組*/
uchar Read_One_Char()
{
uchar i,dat=0;
for(i=0;i<8;i++)
{
dat >>= 1;
if (SDA)
dat |= 0x80;
SCK = 1;
SCK = 0;
}
return dat;
}
/*復位DS1302*/
void Rest_Ds1302()
{
RST = 0;
SCK = 0;
RST = 1;
}
/*寫入數據*/
void Write_Ds1302(uchar addr, uchar dat)
{
Rest_Ds1302();
//RST = 1;
Write_One_Char(addr);
Write_One_Char(dat);
SCK=1;
//SDA = 0;
RST = 0;
}
/*讀取數據*/
uchar Read_Ds1302(uchar addr)
{
uchar temp=0;
Rest_Ds1302();
//RST = 1;
Write_One_Char(addr);
temp = Read_One_Char();
SCK=1;
//SDA = 0;
RST = 0;
return (temp);
}
uchar BCD_To_Decimal(uchar bcd)
{
uchar Decimal;
Decimal=bcd/16;
return(Decimal=Decimal*10+(bcd%16));
}
void Get_Time()
{
Second=BCD_To_Decimal(Read_Ds1302(0x81));
Minute=BCD_To_Decimal(Read_Ds1302(0x83));
Hour=BCD_To_Decimal(Read_Ds1302(0x85));
Week=BCD_To_Decimal(Read_Ds1302(0x8b));
Day=BCD_To_Decimal(Read_Ds1302(0x87));
Month=BCD_To_Decimal(Read_Ds1302(0x89));
Year=BCD_To_Decimal(Read_Ds1302(0x8d));
Data_String[0]='D';
Data_String[1]=':';
Data_String[2]='2';
Data_String[3]='0';
Data_String[4]=(Year/10)+0x30;
Data_String[5]=(Year%10)+0x30;
Data_String[6]=0x2f;
Data_String[7]=(Month/10)+0x30;
Data_String[8]=(Month%10)+0x30;
Data_String[9]=0x2f;
Data_String[10]=(Day/10)+0x30;
Data_String[11]=(Day%10)+0x30;
Data_String[12]=' ';
Time_String[0]='T';
Time_String[1]=':';
Time_String[2]=(Hour/10)+0x30;
Time_String[3]=(Hour%10)+0x30;
Time_String[4]=0x3a;
Time_String[5]=(Minute/10)+0x30;
Time_String[6]=(Minute%10)+0x30;
Time_String[7]=0x3a;
Time_String[8]=(Second/10)+0x30;
Time_String[9]=(Second%10)+0x30;
}
void Key_Scan()
{
uchar m1,m2;
Write_Ds1302(0x8e,0x00);
Write_Ds1302(0x80,0x80);
if((P1&0xf0)!=0)
Delayms(10);
if((P1&0xf0)!=0)
{
if(key1==0)
{
while(!key1);
Hour++;
if(Hour==24) Hour=0;
m1=Hour/10*16+Hour%10;
Write_Ds1302(0x84,m1);
}
if(key2==0)
{
while(!key2);
Minute++;
if(Minute==60) Minute=0;
m2=(Minute/10*16)+(Minute%10);
Write_Ds1302(0x82,m2);
}
if(key3==0)
{
while(!key3);
Write_Ds1302(0x80,0x00);
Write_Ds1302(0x8e,0x80);
key1m=0;
}
}
}
void Ds1302_Init() //1302晶元初始化子函數(2010-01-07,12:00:00,week4)
{
RST=0;
SCK=0;
Write_Ds1302(0x8e,0x00); //允許寫,禁止防寫
Write_Ds1302(0x80,0x00); //向DS1302內寫秒寄存器80H寫入初始秒數據00
Write_Ds1302(0x82,0x00);//向DS1302內寫分寄存器82H寫入初始分數據00
Write_Ds1302(0x84,0x09);//向DS1302內寫小時寄存器84H寫入初始小時數據12
Write_Ds1302(0x8a,0x05);//向DS1302內寫周寄存器8aH寫入初始周數據4
Write_Ds1302(0x86,0x05);//向DS1302內寫日期寄存器86H寫入初始日期數據07
Write_Ds1302(0x88,0x05);//向DS1302內寫月份寄存器88H寫入初始月份數據01
Write_Ds1302(0x8c,0x11);//向DS1302內寫年份寄存器8cH寫入初始年份數據10
Write_Ds1302(0x8e,0x80); //打開防寫
}
void Write_Week(uchar week)//寫星期函數
{
Pos(0x0d);//星期字元的顯示位置
switch(week)
{
case 1:Write_LCD_1602_Data('S');//星期數據為7時顯示
Write_LCD_1602_Data('U');
Write_LCD_1602_Data('N');
break;
case 2:Write_LCD_1602_Data('M');//星期數為1時,顯示
Write_LCD_1602_Data('O');
Write_LCD_1602_Data('N');
break;

case 3:Write_LCD_1602_Data('T');//星期數據為2時顯示
Write_LCD_1602_Data('U');
Write_LCD_1602_Data('E');
break;
case 4:Write_LCD_1602_Data('W');//星期數據為3時顯示
Write_LCD_1602_Data('E');
Write_LCD_1602_Data('D');
break;
case 5:Write_LCD_1602_Data('T');//星期數據為4是顯示
Write_LCD_1602_Data('H');
Write_LCD_1602_Data('U');
break;
case 6:Write_LCD_1602_Data('F');//星期數據為5時顯示
Write_LCD_1602_Data('R');
Write_LCD_1602_Data('I');
break;
case 7 :Write_LCD_1602_Data('S');//星期數據為6時顯示
Write_LCD_1602_Data('T');
Write_LCD_1602_Data('A');
break;
}
}
void main()
{
Ds1302_Init();
Initialization_LCD_1602();
while(1)
{
Get_Time();
if(key0==0)
{
Delayms(10);
if(key0==0)
{
while(!key0)
key1m=1;
}
}
if(key1m==1)Key_Scan();
Pos(0);
Show_String(Data_String);
Write_Week(Week);
Pos(0x40);
Show_String(Time_String);
Pos(0x40+0x0b);//er是頭文件規定的值0x80+0x40
Write_LCD_1602_Data('0'+(DS18B20_Read_Disp_Temperature()/10));//數字+30得到該數字的LCD1602顯示碼
Write_LCD_1602_Data('0'+(DS18B20_Read_Disp_Temperature()%10));//數字+30得到該數字的LCD1602顯示碼
Write_LCD_1602_Data(0x2e);
Write_LCD_1602_Data(tt+0x30);
//Write_LCD_1602_Data(0xdf);//顯示溫度的小圓圈符號,0xdf是液晶屏字元庫的該符號地址碼
Write_LCD_1602_Data(0x43);//顯示"C"符號,0x43是液晶屏字元庫里大寫C的地址碼
}
}
這個是帶年月日,星期,溫度顯示,小時分秒,可調,你可以參考一下噢!

㈦ 基於單片機的萬年歷怎麼做啊只要求顯示日期和時間電路圖、程序有誰懂的支援下哇.拜託了!

#include <reg52.h>
#include<stddef.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_FLAG
#define LCD1602_PORT P0
sbit lcd1602_rs=P2^0;
sbit lcd1602_e=P2^2;
sbit lcd1602_rw=P2^1;
sbit lcd1602_busy=P0^7;
sbit key_ch=P3^5;
sbit key_add=P3^6;
sbit key_minus=P3^7;
uchar i,sec,min,h,date,month,flag;
uint year;
uchar *chgstr[7]={" ","sec","min","hour","date","min","year"};
uchar j,k,m,n,o,p;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar timestr[10],datestr[10];
void init();
void delay(uint);
void time_display();
void date_display();
void control();
void time();
/*
************************************
* 函數名稱:lcd1602_CheckBusy()
* 函數功能:狀態查詢
************************************
*/
void lcd1602_CheckBusy()
{
do
{
lcd1602_busy=1;
lcd1602_rs=0;
lcd1602_rw=1;
lcd1602_e=0;
lcd1602_e=1;
}
while(lcd1602_busy);
}
/*
***************************************
* 函數名稱: lcd1602_WriteCmd()
* 函數功能:寫命令
* 入口參數:命令字
* 出口參數:無
***************************************
*/
void lcd1602_WriteCmd(const uchar cmd)
{
lcd1602_CheckBusy();
lcd1602_rs=0;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=cmd;
lcd1602_e=0;
}
/*
*******************************************
* 函數名稱:lcd1602_WriteData()
* 函數功能:寫數據
* 入口參數:c--待寫數據
* 出口參數:無
*********************************************
*/
void lcd1602_WriteData(const uchar c)
{
lcd1602_CheckBusy();
lcd1602_rs=1;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=c;
lcd1602_e=0;
}
/*
***********************************************
* 函數名稱:lcd1602_Init()
* 函數功能:初始化LCD
* 入口參數:無
* 出口參數:無
***********************************************
*/
void lcd1602_Init()
{
lcd1602_WriteCmd(0x38); //顯示模式為8位2行5*7點陣
lcd1602_WriteCmd(0x0c); //display enable,flag enable,flash enable,
lcd1602_WriteCmd(0x06); //flag move to right,screen don't move
lcd1602_WriteCmd(0x01); //clear screen
}
/*
************************************************
* 函數名稱:lcd1602_Display()
* 函數功能: 字元顯示
* 入口參數:ptr--字元或字元串指針
* 出口參數:無
* 說 明:用戶可通過以下方式來調用:
* 1)lcd1602_Display("Hello,world!");
* 2) INT8U 存儲類型 txt[]="要顯示的字元串";
* 或者 INT8U 存儲類型 txt[]={'t','x','t',..,'\0'};
* INT8U *ptr;
* ptr=&txt;
* lcd1602_Display(ptr);
* 或 lcd1602_Display(txt);
* 或 lcd1602_Display(&txt);
************************************************
*/
void lcd1602_Display(const uchar *ptr,uchar line,uchar xaddr)
{
uchar data i=0;
uchar *data q;
q=ptr;
switch(line)
{
case 0:
lcd1602_WriteCmd(0x80+xaddr);
while(q!=NULL && (*q!='\0') && i<16)
{
lcd1602_WriteData(*q);
q++;
i++;
}
break;
case 1:
lcd1602_WriteCmd(0xc0+xaddr);
while(q!=NULL && (*q!='\0') && i<16)
{
lcd1602_WriteData(*q);
q++;
i++;
}
break;
}
}
void main()
{
lcd1602_Init();
init();
while(1)
{
time_display();
date_display();
control();
}
}
void init()
{
i=0;
sec=0;
min=30;
h=7;
date=17;
month=10;
year=2017;
flag=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 time_display()
{
timestr[7]=0x30+sec%10;
timestr[6]=0x30+sec/10;
timestr[5]=':';
timestr[4]=0x30+min%10;
timestr[3]=0x30+min/10;
timestr[2]=':';
timestr[1]=0x30+h%10;
timestr[0]=0x30+h/10;
timestr[8]=0;
lcd1602_Display(timestr,1,3);
}
void date_display()
{
datestr[9]=0x30+date%10;
datestr[8]=0x30+date/10;
datestr[7]=':';
datestr[6]=0x30+month%10;
datestr[5]=0x30+month/10;
datestr[4]=':';
datestr[3]=0x30+year%10;
datestr[2]=0x30+year/10%10;
datestr[1]=0x30+year/100%10;
datestr[0]=0x30+year/1000;
lcd1602_Display(datestr,0,2);
}
void control()
{
if(!key_ch)
{
delay(5);
if(!key_ch)
{
flag++;
TR0=0;
if(flag==7)
{flag=0;TR0=1;lcd1602_Init();}
lcd1602_Display(chgstr[flag],1,12);
}
}
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==4&&key_minus==0)
{
while(!key_minus);
if(date>1)date--;
}
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++;
}
}
}
}
}
}
}

㈧ 單片機萬年歷

今天碰到了N個白痴問題。萬年歷是能夠顯示年月日、二十四節氣、農歷之類的東西,單片機是一塊晶元。萬年歷可以用單片機來做,但是我真不知道「萬年歷單片機」怎麼做。我想你應該想問的是怎麼用單片機來做萬年歷,我提供思路。 1、單片機最小系統一塊。可以用STC89C52晶元+外圍電路。可以燒入用戶編寫的程序,實現萬年歷所需的邏輯。 2、實時時鍾電路一塊,可以用DS1302晶元。提供年月日、時分秒數據給單片機。 3、顯示器電路一塊。用來顯示這些數據。 4、一些必要的按鍵,用來調整數據。

㈨ AT89C52+DS1302單片機萬年歷程序

參考程序,可以調節時間,設置鬧鍾,音樂鬧鈴

#include<reg52.h>
#include<INTRINS.H>
/************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define TIME (0X10000-50000)
#define FLAG 0XEF //鬧鍾標志
/************************************************************/
//引腳連接圖
sbit CLK=P1^2;
sbit RST=P1^4;
sbit DAT=P1^3;
sbit RS=P1^5;
sbit RW=P1^6;
sbit E=P1^7;
sbit P32=P3^2;

sbit KEY1 = P2^7;
sbit KEY2 = P2^6;
sbit KEY3 = P2^5;
sbit KEY4 = P2^4;

sbit ACC_7=ACC^7;
/************************************************************/
//全局變數及常量定義
uchar i=20,j;
uchar DataBuf[16] = {};//日期
uchar TimeBuf[16] = {};//時間
uchar alarm[2],time[3];
uchar code Day[]={31,28,31,30,31,30,31,31,30,31,30,31};//12個月的最大日期(非閏年)

//閏年月星期表
const unsigned char WeekTab[] = {

(3 << 5) + 31,///1月
(6 << 5) + 29,///2月
(0 << 5) + 31,///3月
(3 << 5) + 30,///4月
(5 << 5) + 31,//5月
(1 << 5) + 30,//6月
(3 << 5) + 31,//7月
(6 << 5) + 31,//8月
(1 << 5) + 30,//9月
(4 << 5) + 31,//10月
(0 << 5) + 30,//11月
(2 << 5) + 31 //12月
};

//音律表
uint code table1[]={64260,64400,64524,64580,64684,64777,
64820,64898,64968,65030,65058,65110,65157,65178,65217};
//發聲部分的延時時間
uchar code table2[]={0x82,1,0x81,0xf4,0xd4,0xb4,0xa4,
0x94,0xe2,1,0xe1,0xd4,0xb4,0xc4,0xb4,4,0};

//鬧鍾中用的全局變數
uchar th1,tl1;

/************************************************************/
//延時1ms函數
delay1ms(uchar time)
{
uchar i,j;
for(i=0;i<time;i++)
{
for(j=0;j<250;j++);
}
}

/************************************************************/
//LCD控制函數
Enable()
{
RS=0;
RW=0;
E=0;
delay1ms(3);
E=1;
}

/************************************************************/
//LCD1602寫入字元函數
LCD1602_WriteSChr(uchar i)
{
P0=i;
RS=1;
RW=0;
E=0;
delay1ms(2);
E=1;
}

/************************************************************/
//LCD1602寫入字元串函數
//入口函數
//uchar data *address : 寫入數據首地址
//ucharm:寫入位元組數
LCD1602_WriteStr(uchar *address,uchar m)
{
uchar i,j;
for(i=0;i<m;i++,address++)
{
j=*address;
LCD1602_WriteSChr(j);
}
}

/************************************************************/
//LCD顯示
void LCDShow(void)
{
P0=0XC; //顯示器開、游標關
Enable();
//P0=0x80; //寫入顯示起始地址
//Enable();
//LCD1602_WriteStr(DataBuf,16); //寫入日期顯示緩存
P0=0xc1; //寫入顯示起始地址
Enable();

LCD1602_WriteStr(TimeBuf,16); //寫入時間顯示緩存
}

/************************************************************/
//DS1302寫入子程序
void DS1302_Write(uchar temp)
{
uchar i;
CLK=0; //將DS1320時鍾脈沖拉低
_nop_();//延時一指令周期
RST=1; //RST置高電平
_nop_();//延時一指令周期
for(i=0;i<8;i++) //循環8次
{
DAT=temp&0x01; //向DS1302寫入一位元組數據
_nop_(); //延時一指令周期
CLK=1; //拉高時鍾脈沖
temp>>=1; //右移一位
CLK=0; //拉低時鍾脈沖
}
}

/************************************************************/
//DS1302讀取子程序
uchar DS1302_Read()
{
uchar i,j=0;
for(i=0;i<8;i++)//循環8次
{
j>>=1; //右移一位
_nop_(); //延時一指令周期
CLK=0; //拉低時鍾脈沖
_nop_(); //延時一指令周期
if(DAT) //判斷接收該位數據是否為1
j|=0x80;//該位置1
_nop_(); //延時一指令周期
CLK=1; //拉高時鍾脈沖
}
return(j); //返回數值
}

/************************************************************/
//部分顯示數據初始化
TimeStart()
{
TimeBuf[0]=TimeBuf[8]=TimeBuf[9]=TimeBuf[10]=0x20; //不顯示字元
TimeBuf[2]=TimeBuf[5]=':'; //時間分隔顯示
DS1302_Write(0xc1);
alarm[0]=DS1302_Read();
RST=0;
DS1302_Write(0xc3);
alarm[1]=DS1302_Read();
RST=0;
DS1302_Write(0xc5);
DataBuf[0]=DS1302_Read();
RST=0;
}

/************************************************************/
//讀取時間
ReadTime()
{
uchar i,m,n;
for(m=0,i=0,n=0x85;i<7;i+=3,n-=2,m++) //連續讀取時,分,秒
{
DS1302_Write(n); //寫入讀取寄存器指令
time[m]=DS1302_Read(); //讀取數據
RST=0; //將RST電平拉低,停止傳輸
TimeBuf[i]=time[m]/16+0x30; //將兩位數據的十位轉為字元格式
TimeBuf[i+1]=time[m]%16+0x30;//將兩位數據的個位轉為字元格式
}
}

/************************************************************/
//功能選擇超時定時器
time0() interrupt 1 using 1
{
i--;
if(i==0)
{
if(j!=0)
j--;
i=20;
}
TH0=TIME/256,TL0=TIME%256;
}

/************************************************************/
//產生鬧鈴音調
intime1() interrupt 3
{
TH1=th1,TL1=tl1;
P32=!P32;
}

/************************************************************/
//鬧鍾顯示
void AlarmShow(void)
{
uchar i,j,a,b,n;
ET1=1;
for(j=0;j<6;j++)
{
i=0;
while(1)
{
a=table2[i];
if(a==0)
break;
b=a&0xf;
a>>=4;
if(a==0)
{
TR1=0;
goto D1;
}
a=((--a)<<1)/2;
TH1=th1=table1[a]/256,TL1=tl1=table1[a]%256;
TR1=1;
D1: do
{
b--;
for(n=0;n<3;n++)
{
ReadTime();
LCDShow();
P2=0xff;
if(KEY4 == 1)
{
delay1ms(100);
if(KEY4 == 1)
{
TR1=0;
ET1=0;
P32 = 1;
return;
}
}
}
}while(b!=0);
i++;
}
TR1=0;
}
ET1=0;
}

/************************************************************/
//設置日期、時間
void SetTime(void)
{
uchar i=0xc2,year,month,day,n;
TimeBuf[6]=TimeBuf[7]=0x30;
DataBuf[14]=DataBuf[15]=0x20;
LCDShow();
while(1)
{
P0=0xe; //顯示器開、游標開
Enable();
P0=i; //定游標
Enable();
P2=0xff;
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
delay1ms(100); //延時0.1s去抖動
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
j=7;
if(KEY1 == 1)
{
i+=3; //更改設置項目
if(i==0x8e)
i=0xc2;
else if(i>0xc5)
i=0xc2;
}
else if(KEY2 == 1)
{
year=(DataBuf[4]&0xf)*10+(DataBuf[5]&0xf); //將字元格式的年份轉換為數值格式
month=(DataBuf[7]&0xf)*10+(DataBuf[8]&0xf); //將字元格式的月份轉換為數值格式
day=(DataBuf[10]&0xf)*10+(DataBuf[11]&0xf); //將字元格式的日數轉換為數值格式
if(i==0x85) //設置年份
{
year++;
if(year>99)
year=0;
if((year%4)!=0)
if(month==2&&day==29)
day=28;
}
else if(i==0x88) //設置月份
{
month++;
if(month>12)
month=1;
if(day>Day[month-1])
{
day=Day[month-1];
if(month==2&&(year%4)==0) //計算是否閏年
day=29;
}
}
else if(i==0x8b) //設置日期
{
day++;
if(day>Day[month-1])
{
if(month==2&&(year%4)==0) //計算是否閏年
{
if(day>29)
day=1;
}
if(month!=2)
day=1;
}
}
else if(i==0xc2) //設置小時
{
n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf);
n++;
if(n>23)
n=0;
TimeBuf[0]=n/10+0x30;
TimeBuf[1]=n%10+0x30;
}
else //設置分鍾
{
n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf);
n++;
if(n>59)
n=0;
TimeBuf[3]=n/10+0x30;
TimeBuf[4]=n%10+0x30;
}
DataBuf[4]=year/10+0x30; //將數值格式的日期轉換為字元形式
DataBuf[5]=year%10+0x30;
DataBuf[7]=month/10+0x30;
DataBuf[8]=month%10+0x30;
DataBuf[10]=day/10+0x30;
DataBuf[11]=day%10+0x30;
LCDShow();
}
else if(KEY3 == 1) //按保存退出鍵後,向DS1302寫入設置後的日期時間
{
DS1302_Write(0x8c);
DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf));
RST=0;
DS1302_Write(0x8a);
DS1302_Write(SetWeek());
RST=0;
for(i=7,n=0x88;i<11;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf));
RST=0;
}
for(i=0;i<7;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf));
RST=0;
}
TR0=0;
return;
}
else
{
TR0=0;
return;
}
}
}
if(j==0)
{
TR0=0;
return;
}
}
}

/************************************************************/
//設置鬧鍾
void SetAlarm(void)
{
uchar i,n;
for(i=1;i<16;i++)
{
DataBuf[i]=0x20;
}
TimeBuf[0]=alarm[0]/16+0x30;
TimeBuf[1]=(alarm[0]&0xf)+0x30;
TimeBuf[3]=alarm[1]/16+0x30;
TimeBuf[4]=(alarm[1]&0xf)+0x30;
TimeBuf[6]=TimeBuf[7]=0x30;
LCDShow();
i=0xc2;
while(1)
{
P0=0xe; //顯示器開、游標開
Enable();
P0=i; //定游標
Enable();
P2=0xff;
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
delay1ms(100); //延時0.1s去抖動
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
{
j=7;
if(KEY1 == 1)
{
i+=3;
if(i>0xc5)
i=0xc2;
}
else if(KEY2 == 1)
{
if(i==0xc2)
{
n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf);
n++;
if(n>23)
n=0;
TimeBuf[0]=n/10+0x30;
TimeBuf[1]=n%10+0x30;
}
else
{
n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf);
n++;
if(n>59)
n=0;
TimeBuf[3]=n/10+0x30;
TimeBuf[4]=n%10+0x30;
}
LCDShow();
}
else if(KEY3 == 1)
{
DS1302_Write(0xc0);
DS1302_Write((TimeBuf[0]&0xf)*16+(TimeBuf[1]&0xf));
RST=0;
DS1302_Write(0xc2);
DS1302_Write((TimeBuf[3]&0xf)*16+(TimeBuf[4]&0xf));
RST=0;
DataBuf[0]=FLAG;
DS1302_Write(0xc4);
DS1302_Write(DataBuf[0]);
RST=0;
TR0=0;
TimeStart();
return;
}
else
{
TR0=0;
TimeStart();
return;
}
}
}
if(j==0)
{
TR0=0;
TimeStart();
return;
}
}
}

/************************************************************/
//DS1302初始化程序
void DS1302_Init(void)
{
uchar i,n;

DS1302_Write(0x8c);
DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf));
RST=0;
DS1302_Write(0x8a);
DS1302_Write(SetWeek());
RST=0;
for(i=7,n=0x88;i<11;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf));
RST=0;
}
for(i=0;i<7;i+=3,n-=2)
{
DS1302_Write(n);
DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf));
RST=0;
}
}

/************************************************************/
//主函數
main()
{
IE=0x82;
TMOD=0x11;
DS1302_Write(0x8E); //禁止防寫
DS1302_Write(0);
RST=0;
P0=1; //清屏並游標復位
Enable();
P0=0x38; //設置顯示模式:8位2行5x7點陣
Enable();
P0=6; //文字不動,游標自動右移
Enable();
DS1302_Init();
TimeStart();

while(1)
{
ReadTime(); //讀取時間
LCDShow(); //顯示時間

if(DataBuf[0]!=0x20)
if(time[0]==alarm[0])
if(time[1]==alarm[1])
if(time[2]==0)
AlarmShow();

P2=0xff;
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1))
{
delay1ms(100); //延時0.1s去抖動
if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1))
{
j=7;
TH0=TIME/256,TL0=TIME%256;
TR0=1;
if(KEY1 == 1)
{
SetTime();
}
else if(KEY2 == 1)
{
SetAlarm();
}
else if(KEY3 == 1)
{
TR0=0;
if(DataBuf[0]==FLAG)
DataBuf[0]=0x20;
else
DataBuf[0]=FLAG;
DS1302_Write(0xc4);
DS1302_Write(DataBuf[0]);
RST=0;
}
}
}
delay1ms(100);
}
}

㈩ 想用單片機設計一個萬年歷,如何實現陽歷到農歷的轉換最好是給出思路和相關程序。

<%
' 用途:
' 當前日期計算該日期的農歷天乾地支及當年屬相
' ##-------------------------------------------##
Dim objChinaDay
Dim sDay, sWeekDay, sChinaDay, sChinaYear,sChinaAni
Set objChinaDay = New ChinaDay
Call objChinaDay.Action("",sDay,sWeekDay,sChinaYear,sChinaDay,sChinaAni)
Response.Write sDay&"" '當前日期
Response.Write sWeekDay&"" '星期
Response.Write sChinaYear&"" '農歷年份
Response.Write sChinaDay&"" '農歷日期
Response.Write sChinaAni&"" '生肖
' Copyright: 本代碼非原創,原作者未知。
'*********************************************************************************
Class ChinaDay

Dim arrWeekName(7), MonthAdd(11), NongliData(99)
Dim arrTianGan(9), arrDiZhi(11), arrShuXiang(11), arrDayName(30), arrMonName(12)
Dim curTime, curYear, curMonth, curDay, curWeekday
Dim i, m, n, k, isEnd, bit, TheDate

'初始化數據
Sub Class_Initialize()
'-------------------------------------------------------------------------
'啟凳友定義顯示字串

'星期名
arrWeekName(0) = "*"
arrWeekName(1) = "星期日"
arrWeekName(2) = "星期一"
arrWeekName(3) = "星期二"
arrWeekName(4) = "星期三"
arrWeekName(5) = "星期四"
arrWeekName(6) = "星期五"
arrWeekName(7) = "星悄槐期六"

'天干名稱
arrTianGan(0) = "甲"
arrTianGan(1) = "乙"
arrTianGan(2) = "丙"
arrTianGan(3) = "丁"
arrTianGan(4) = "戊"
arrTianGan(5) = "己"
arrTianGan(6) = "庚"
arrTianGan(7) = "辛"
arrTianGan(8) = "壬"
arrTianGan(9) = "癸"

'地支名稱
arrDiZhi(0) = "子"
arrDiZhi(1) = "丑"
arrDiZhi(2) = "寅"
arrDiZhi(3) = "卯"
arrDiZhi(4) = "辰"
arrDiZhi(5) = "巳"
arrDiZhi(6) = "午"
arrDiZhi(7) = "未"
arrDiZhi(8) = "申粗岩"
arrDiZhi(9) = "酉"
arrDiZhi(10) = "戌"
arrDiZhi(11) = "亥"

'屬相名稱
arrShuXiang(0) = "鼠"
arrShuXiang(1) = "牛"
arrShuXiang(2) = "虎"
arrShuXiang(3) = "兔"
arrShuXiang(4) = "龍"
arrShuXiang(5) = "蛇"
arrShuXiang(6) = "馬"
arrShuXiang(7) = "羊"
arrShuXiang(8) = "猴"
arrShuXiang(9) = "雞"
arrShuXiang(10) = "狗"
arrShuXiang(11) = "豬"

'農歷日期名
arrDayName(0) = "*"
arrDayName(1) = "初一"
arrDayName(2) = "初二"
arrDayName(3) = "初三"
arrDayName(4) = "初四"
arrDayName(5) = "初五"
arrDayName(6) = "初六"
arrDayName(7) = "初七"
arrDayName(8) = "初八"
arrDayName(9) = "初九"
arrDayName(10) = "初十"
arrDayName(11) = "十一"
arrDayName(12) = "十二"
arrDayName(13) = "十三"
arrDayName(14) = "十四"
arrDayName(15) = "十五"
arrDayName(16) = "十六"
arrDayName(17) = "十七"
arrDayName(18) = "十八"
arrDayName(19) = "十九"
arrDayName(20) = "二十"
arrDayName(21) = "廿一"
arrDayName(22) = "廿二"
arrDayName(23) = "廿三"
arrDayName(24) = "廿四"
arrDayName(25) = "廿五"
arrDayName(26) = "廿六"
arrDayName(27) = "廿七"
arrDayName(28) = "廿八"
arrDayName(29) = "廿九"
arrDayName(30) = "卅十"

'農歷月份名
arrMonName(0) = "*"
arrMonName(1) = "正"
arrMonName(2) = "二"
arrMonName(3) = "三"
arrMonName(4) = "四"
arrMonName(5) = "五"
arrMonName(6) = "六"
arrMonName(7) = "七"
arrMonName(8) = "八"
arrMonName(9) = "九"
arrMonName(10) = "十"
arrMonName(11) = "冬"
arrMonName(12) = "臘"

'-------------------------------------------------------------------------
'公差數據定義

'公歷每月前面的天數
MonthAdd(0) = 0
MonthAdd(1) = 31
MonthAdd(2) = 59
MonthAdd(3) = 90
MonthAdd(4) = 120
MonthAdd(5) = 151
MonthAdd(6) = 181
MonthAdd(7) = 212
MonthAdd(8) = 243
MonthAdd(9) = 273
MonthAdd(10) = 304
MonthAdd(11) = 334

'農歷數據
NongliData(0) = 2635
NongliData(1) = 333387
NongliData(2) = 1701
NongliData(3) = 1748
NongliData(4) = 267701
NongliData(5) = 694
NongliData(6) = 2391
NongliData(7) = 133423
NongliData(8) = 1175
NongliData(9) = 396438
NongliData(10) = 3402
NongliData(11) = 3749
NongliData(12) = 331177
NongliData(13) = 1453
NongliData(14) = 694
NongliData(15) = 201326
NongliData(16) = 2350
NongliData(17) = 465197
NongliData(18) = 3221
NongliData(19) = 3402
NongliData(20) = 400202
NongliData(21) = 2901
NongliData(22) = 1386
NongliData(23) = 267611
NongliData(24) = 605
NongliData(25) = 2349
NongliData(26) = 137515
NongliData(27) = 2709
NongliData(28) = 464533
NongliData(29) = 1738
NongliData(30) = 2901
NongliData(31) = 330421
NongliData(32) = 1242
NongliData(33) = 2651
NongliData(34) = 199255
NongliData(35) = 1323
NongliData(36) = 529706
NongliData(37) = 3733
NongliData(38) = 1706
NongliData(39) = 398762
NongliData(40) = 2741
NongliData(41) = 1206
NongliData(42) = 267438
NongliData(43) = 2647
NongliData(44) = 1318
NongliData(45) = 204070
NongliData(46) = 3477
NongliData(47) = 46
NongliData(48) = 1386
NongliData(49) = 2413
NongliData(50) = 330077
NongliData(51) = 1197
NongliData(52) = 2637
NongliData(53) = 268877
NongliData(54) = 3365
NongliData(55) = 531109
NongliData(56) = 2900
NongliData(57) = 2922
NongliData(58) = 398042
NongliData(59) = 2395
NongliData(60) = 1179
NongliData(61) = 267415
NongliData(62) = 2635
NongliData(63) = 661067
NongliData(64) = 1701
NongliData(65) = 1748
NongliData(66) = 398772
NongliData(67) = 2742
NongliData(68) = 2391
NongliData(69) = 330031
NongliData(70) = 1175
NongliData(71) = 1611
NongliData(72) = 200010
NongliData(73) = 3749
NongliData(74) = 527717
NongliData(75) = 1452
NongliData(76) = 2742
NongliData(77) = 332397
NongliData(78) = 2350
NongliData(79) = 3222
NongliData(80) = 268949
NongliData(81) = 3402
NongliData(82) = 3493
NongliData(83) = 133973
NongliData(84) = 1386
NongliData(85) = 464219
NongliData(86) = 605
NongliData(87) = 2349
NongliData(88) = 334123
NongliData(89) = 2709
NongliData(90) = 2890
NongliData(91) = 267946
NongliData(92) = 2773
NongliData(93) = 592565
NongliData(94) = 1210
NongliData(95) = 2651
NongliData(96) = 395863
NongliData(97) = 1323
NongliData(98) = 2707
NongliData(99) = 265877
End Sub

'#################################################################
'主要方法 Action
' inDay 輸入日期,如果不輸入則默認為當前日期
' sDay 中文格式日期
' sWeekDay 周幾
' sChinaYear 農歷年
' sChinaDay 農歷日
' sChinaAni 屬相
'#################################################################
Public Function Action(inDay,sDay,sWeekDay,sChinaYear,sChinaDay,sChinaAni)

'轉換要轉換的日期
If inDay="" Or Not IsDate(inDay) Then
'獲取當前系統時間
curTime = Now()
Else
curTime = CDate(inDay)
End If

If Datediff("d",curTime,Cdate("1921-2-8"))>0 Then
Exit Function
End If

'生成當前公歷年、月、日 ==> sDay
curYear = Year(curTime)
curMonth = Month(curTime)
curDay = Day(curTime)

sDay = curYear&"年"
If (curMonth < 10) Then
sDay = sDay&"0"&curMonth&"月"
Else
sDay = sDay&curMonth&"月"
End If
If (curDay < 10) Then
sDay = sDay&"0"&curDay&"日"
Else
sDay = sDay&curDay&"日"
End If

'生成當前公歷星期 ==> sWeekDay
curWeekday = Weekday(curTime)
sWeekDay = arrWeekName(curWeekday)

'計算到初始時間1921年2月8日的天數:1921-2-8(正月初一)
TheDate = (curYear - 1921) * 365 + Int((curYear - 1921) / 4) + curDay + MonthAdd(curMonth - 1) - 38
If ((curYear Mod 4) = 0 AND curMonth > 2) Then
TheDate = TheDate + 1
End If

'計算農歷天干、地支、月、日
isEnd = 0
m = 0
'------------------------------------
Do
If (NongliData(m) < 4095) Then
k = 11
Else
k = 12
End if

n = k
'------------------------------------
Do
If (n < 0) Then
Exit Do
End If

'獲取NongliData(m)的第n個二進制位的值
bit = NongliData(m)
For i = 1 To n Step 1
bit = Int(bit / 2)
Next
bit = bit Mod 2

If (TheDate <= 29 + bit) Then
isEnd = 1
Exit Do
End If

TheDate = TheDate - 29 - bit

n = n - 1
Loop
'------------------------------------
If (isEnd = 1) Then
Exit Do
End If

m = m + 1
Loop
'------------------------------------

curYear = 1921 + m
curMonth = k - n + 1
curDay = TheDate

If (k = 12) Then
If (curMonth = (Int(NongliData(m) / 65536) + 1)) Then
curMonth = 1 - curMonth
ElseIf (curMonth > (Int(NongliData(m) / 65536) + 1)) Then
curMonth = curMonth - 1
End if
End If

'生成農歷天干、地支==> sChinaYear
sChinaYear = "農歷"&arrTianGan(((curYear - 4) Mod 60) Mod 10)&arrDiZhi(((curYear - 4) Mod 60) Mod 12)&"年"
'生成屬相 == > sChinaAni
sChinaAni = arrShuXiang(((curYear - 4) Mod 60) Mod 12)

'生成農歷月、日 ==> NongliDayStr
If (curMonth < 1) Then
sChinaDay = "閏"&arrMonName(-1 * curMonth)
Else
sChinaDay = arrMonName(curMonth)
End If
sChinaDay = sChinaDay&"月"

sChinaDay = sChinaDay & arrDayName(curDay)
End Function
End Class
%>

閱讀全文

與單片機萬年歷程序怎樣讀取時間相關的資料

熱點內容
graphvizlinux 瀏覽:438
智能手錶藍牙怎麼下載app 瀏覽:293
女程序員下班菜譜 瀏覽:260
加密貨幣買什麼比較靠譜 瀏覽:277
用圖片的地圖再編譯的地方 瀏覽:462
python監控系統進程 瀏覽:236
群暉怎麼取消照片共享文件夾 瀏覽:156
程序員那麼可愛第幾集陸璃懷孕 瀏覽:615
西門子st編程手冊 瀏覽:59
mt4編程書籍 瀏覽:21
單片機模擬實驗設置電壓 瀏覽:948
如何用電腦打開安卓手機內存 瀏覽:860
java數據訪問層 瀏覽:181
代碼優化是編譯程序的必要階段 瀏覽:623
程序員那麼可愛孩子還在嗎 瀏覽:513
以下哪些是資料庫編程技術 瀏覽:164
水冷壓縮冷凝機組 瀏覽:177
小米路由器app怎麼加黑名單 瀏覽:433
證券交易2012pdf 瀏覽:208
單線程和多線程編譯 瀏覽:155