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

單片機萬年歷模擬

發布時間:2023-03-18 05:21:13

Ⅰ 求個用單片機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--);
};
}

Ⅱ 單片機和lcd1602編寫萬年歷C語言程序,求高手啊

下面是我的程序,還有模擬圖,不懂可以再問我,祝你成功

/*******************************************

ds1302計時+lcd1602顯示

*******************************************/

#include<reg51.h>

#include<intrins.h>

#defineucharunsignedchar

#defineuintunsignedint

sbitrs=P2^0;

sbitrw=P2^1;

sbite=P2^2;

sbitT_RST=P1^5;

sbitT_CLK=P1^6;

sbitT_IO=P1^7;

sbitACC0=ACC^0;

sbitACC7=ACC^7;

/*******************************************

向1302寫一個位元組

*******************************************/

voidinput_BYTE(uchardat)

{

uchari;

ACC=dat;

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

{

T_IO=ACC0;

T_CLK=1;

T_CLK=0;

ACC=(ACC>>1);

}

}

/*******************************************

1302讀出一個位元組

*******************************************/

ucharoutput_BYTE()

{

uchari;

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

{

ACC=(ACC>>1);

ACC7=T_IO;

T_CLK=1;

T_CLK=0;

}

return(ACC);

}

/*******************************************

寫數據

*******************************************/

voidwrite_1302(ucharadd,uchardat)

{

T_RST=0;

T_CLK=0;

T_RST=1;

input_BYTE(add);

input_BYTE(dat);

T_CLK=1;

T_RST=0;

}

/*******************************************

讀數據

*******************************************/

ucharread_1302(ucharadd)

{

ucharinf;

T_RST=0;

T_CLK=0;

T_RST=1;

input_BYTE(add);

inf=output_BYTE();

T_CLK=1;

T_RST=0;

return(inf);

}

voidinit_1302()

{

write_1302(0x8e,0x00);//關閉防寫;

/*write_1302(0x90,0xaa);//設置充電方式;

write_1302(0x80,0x00);//秒寄存器初始化;

write_1302(0x82,0x46);//分.......

write_1302(0x84,0x22);//時.......

write_1302(0x86,0x17);//日........

write_1302(0x88,0x03);//月.......

write_1302(0x8a,0x04);//星期...

write_1302(0x8c,0x11);//年......*/

write_1302(0x8e,0x80);//打開防寫;

}

ucharcom,inf;

ucharcodetable[]="DS1302";

ucharcodetable1[]="0123456789";

ucharcodetable2[]="WEEK-";

voiddelay1(uchart)

{

ucharx,y;

for(x=t;x>0;x--)

for(y=110;y>0;y--);

}

/*******************************************

給1602寫指令

*******************************************/

voidwrite_com(ucharcom)

{

rs=0;

P0=com;

delay1(5);

e=1;

delay1(5);

e=0;

}

/*******************************************

給1602寫數據

*******************************************/

voidwrite_date(uchardate)

{

rs=1;

P0=date;

delay1(5);

e=1;

delay1(5);

e=0;

}

/*******************************************

1602初始化

*******************************************/

voinit()

{

e=0;

rw=0;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

}

/*******************************************

主函數

*******************************************/

voidmain()

{

uchari;

uchart_sec,sec1,sec2;

uchart_min,min1,min2;

uchart_hour,hour1,hour2;

uchart_mon,mon1,mon2;

uchart_day,day1,day2;

uchart_year,year1,year2;

ucharweek,week1;

ucharnum;

unit();

init_1302();

while(1)

{

t_sec=read_1302(0x81);//miao;

sec1=t_sec&0x0f;

sec2=(t_sec>>4);

t_min=read_1302(0x83);//fen;

min1=t_min&0x0f;

min2=(t_min>>4);

t_hour=read_1302(0x85);//shi;

hour1=t_hour&0x0f;

hour2=(t_hour>>4);

t_day=read_1302(0x87);//ri;

day1=t_day&0x0f;

day2=(t_day>>4);

t_mon=read_1302(0x89);//yue;

mon1=t_mon&0x0f;

mon2=(t_mon>>4);

week=read_1302(0x8b);//xingqi;

week1=week&0x0f;

t_year=read_1302(0x8d);//nian;

year1=t_year&0x0f;

year2=(t_year>>4);

write_com(0x80);

for(i=0;i<6;i++)

{

write_date(table[i]);

}

write_com(0x80+0x40);

for(i=0;i<5;i++)

{

write_date(table2[i]);

}

write_com(0x80+0x07);

write_date(table1[year2]);

write_com(0x80+0x08);

write_date(table1[year1]);

write_com(0x80+0x09);

write_date('/');

write_com(0x80+0x0a);

write_date(table1[mon2]);

write_com(0x80+0x0b);

write_date(table1[mon1]);

write_com(0x80+0x0c);

write_date('/');

write_com(0x80+0x0d);

write_date(table1[day2]);

write_com(0x80+0x0e);

write_date(table1[day1]);

write_com(0x80+0x40+0x05);

write_date(table1[week1]);

write_com(0x80+0x40+0x07);

write_date(table1[hour2]);

write_com(0x80+0x40+0x08);

write_date(table1[hour1]);

write_com(0x80+0x40+0x09);

write_date(':');

write_com(0x80+0x40+0x0a);

write_date(table1[min2]);

write_com(0x80+0x40+0x0b);

write_date(table1[min1]);

write_com(0x80+0x40+0x0c);

write_date(':');

write_com(0x80+0x40+0x0d);

write_date(table1[sec2]);

write_com(0x80+0x40+0x0e);

write_date(table1[sec1]);

}

}

Ⅲ 單片機萬年歷

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

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

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

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

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

模擬圖如下:

Ⅵ 求基於51單片機的電子萬年歷的程序及模擬圖

你好:
這是我用定時器的方式寫出來的萬年歷程序,lcd1602顯示,51單片機控制,能顯示日期和時間,並可通過按鍵調整時間。
參考參考吧,希望我的回答能幫助到你。

閱讀全文

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

熱點內容
一加7pro文件夾data 瀏覽:424
程序員淋雨 瀏覽:947
python輸出數字序列中的空格 瀏覽:78
怎麼將pdf文件大小 瀏覽:734
氧原子相對分子量演算法 瀏覽:988
加密機為什麼是安全的 瀏覽:451
單片機拼音輸入法 瀏覽:789
蘋果筆記本t2加密晶元怎麼打開 瀏覽:796
安卓如何把手機投屏至電視 瀏覽:739
方舟編譯器現在可提速哪些軟體 瀏覽:60
微信加密為什麼是黑屏 瀏覽:473
android去電狀態 瀏覽:604
蘋果13如何加密視頻 瀏覽:815
linuxweblogic緩存 瀏覽:69
雲伺服器不同地域 瀏覽:946
python鬧鍾怎麼打 瀏覽:686
虛擬主機伺服器有什麼區別 瀏覽:833
演算法與程序的奧秘章節檢測 瀏覽:378
找pdf 瀏覽:530
與伺服器連接斷開如何處理 瀏覽:833