导航:首页 > 操作系统 > 单片机万年历程序怎样读取时间

单片机万年历程序怎样读取时间

发布时间: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
%>

阅读全文

与单片机万年历程序怎样读取时间相关的资料

热点内容
外出电影完整版下载 浏览:220
老电影等 浏览:235
有个小姑娘叫美娜的韩剧 浏览:143
韩国美容院老板出轨顾客的片子 浏览:870
日本爱情动作大片 浏览:617
微信好友怎么加密不能让别人看见聊天记录 浏览:145
爱情电影网 apdy类似网站 浏览:945
地铁快线和加密线 浏览:41
计算机科学程序员 浏览:356
激光手术治疗近视适合程序员吗 浏览:107
资深程序员优良习惯 浏览:358
宏晶单片机中文手册 浏览:965
主人公叫林枫的小说 浏览:773
有一个美剧学生一直想跟老师发生关系 浏览:276
kettle解压后没有bat文件 浏览:71
只剩最后一个男人的电影 浏览:578
编译原理词法未来前景 浏览:890
唐子睿 浏览:642
有弹窗广告的小说网站 浏览:745
大陆战争老电影全部 浏览:967