標題:
這是一個基于單片機制作萬年歷相關(guān)的論文 含原理圖 代碼等,希望和大家一起分享
[打印本頁]
作者:
夢想292626
時間:
2018-3-27 22:26
標題:
這是一個基于單片機制作萬年歷相關(guān)的論文 含原理圖 代碼等,希望和大家一起分享
論文下載:
基于51單片機的電子萬年歷畢業(yè)論文設(shè)計.doc
(1.49 MB, 下載次數(shù): 11)
2018-3-27 22:25 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
電路原理圖如下:
1.png
(138.16 KB, 下載次數(shù): 40)
下載附件
電路原理圖
2018-3-27 22:24 上傳
設(shè)計主程序:
/*
* 萬年歷
*/
#include "main.h"
#include "LCD.h"
#include "DS1302.h"
#include "word.h"
#include "lunar_calendar.h"
#include "buzz.h"
TIME time, tmp_time;
ALARM alarm;
bit Alarm_flag=0;
bit Clock_flag=0;
bit flag=0;
sbit DQ=P2^6; //DS18B20 pin
//-----------------18B20-----------------------
unsigned char L_18B20,H_18B20,zhengshu,shangwen,xiawen;
unsigned int fg=0,xiaoshu_a;
//-----------------18B20----------------------
//-------------音樂-----------------------------
uint8 code SONG_TONE[]=
{
212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,129,169,190,119,119,126,159,142,159,0
};
uint8 code SONG_LONG[]=
{
9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0
};
//------------------------------------------------------------
void delay(uint16 n)
{
while (n--);
}
//************************************************************************/
// 函數(shù): LCD_Delay()
// 描述: 延時t ms函數(shù)
// 參數(shù): t
// 返回: 無
// 備注: 11.0592MHZ t=1延時時間約1ms
// 版本: 2011/01/01 First version
//************************************************************************/
void Delay_nms(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<113;j++)
;
}
/////////////////////////////////////////////////
//-----------播放音樂----------------------------
void PlayMusic()
{
uint16 i =0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{
for(j=0;j<SONG_LONG[i]*20;j++)
{
BEEP = ~BEEP;
for(k=0;k<SONG_TONE[i]/3;k++);
}
Delay_nms(10);
i++;
}
BEEP =1;//關(guān)閉蜂鳴器
}
/////////////////////////////////////////////////
/*------DS18B20------*/
void delay_18B20(unsigned int i)
{
while(i--);
}
/*DS18B20的復位脈沖 主機通過拉低單總線至少480us以產(chǎn)生復位脈沖
然后主機釋放單總線并進入接收模式 此時單總線電平被拉高
DS18B20檢測到上升沿后 延時15~60us,拉低總線60~240us產(chǎn)生應(yīng)答脈沖 */
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復位
delay_18B20(8); //稍做延時
DQ = 0; //單片機將DQ拉低
delay_18B20(80); //精確延時 大于 480us
DQ = 1; //拉高總線
delay_18B20(14);
x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
delay_18B20(20);
}
/*寫時隙 主機在寫1時隙向DS18B20寫入1,在寫0時隙向DS18B20寫入0
所有寫時隙至少需要60us,且在兩次寫時隙之間至少需要1us的恢復時間
兩種寫時隙均以主機拉低總線開始
產(chǎn)生寫1時隙:主機拉低總線后,必須在15us內(nèi)釋放總線,由上拉電阻拉回至高電平
產(chǎn)生寫0時隙:主機拉低總線后,必須整個時隙保持低電平 */
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/*所有讀時隙至少60us 且兩次獨立的讀時隙之間至少需要1us的恢復時間
每次讀時隙由主機發(fā)起,拉低總線至少1us。
若傳1,則保持總線高電平;若發(fā)送0,則拉低總線
傳0時DS18B20在該時隙結(jié)束時釋放總線,再拉回高電平狀態(tài),主機必須在讀時隙開始后的15us內(nèi)釋放總線,并保持采樣總線狀態(tài) */
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
void read_18B20(void)
{
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
delay_18B20(100);
L_18B20=ReadOneChar(); //讀取低八位數(shù)據(jù)
H_18B20=ReadOneChar(); //讀取高八位數(shù)據(jù)
zhengshu=L_18B20/16+H_18B20*16; //整數(shù)部分
xiaoshu_a=(L_18B20&0x0f)*10/16; //小數(shù)第一位
}
//------------------DS18B20---------------------
/////////////////////////////////////////////////
/*
* 按鍵掃描
*/
int8 scan_key(void)
{
int8 val=-1;
if (KeyIn1 == 0)
{
val = 1;
while (KeyIn1 == 0);
}
else if (KeyIn2 == 0)
{
val = 2;
while (KeyIn2 == 0);
}
else if (KeyIn3 == 0)
{
val = 3;
while (KeyIn3 == 0);
}
//if (val > 0)
//buzzer_sound();
return val;
}
/*
* 主界面框架
*/
void main_frame(void)
{
play32(80, 2, 10);
play32(32, 2, 10);
play8(16, 0, S_xie);
play8(40, 0, S_xie);
// play8(96, 0, RH);
// play8(120, 0, S_percent);
play8(120, 6, S_du);
}
/*
* 主界面
*/
void main_show(bit refresh)
{
uint8 lunar[2];
if (refresh)
read_time((uint8 *)&time);
// 時間
if (refresh || (time.sec != tmp_time.sec)) // 秒更新
{
tmp_time.sec = time.sec;
// 溫濕度
play8_num(104, 6,zhengshu); //溫度顯示
play32_num(96, 2, time.sec);
}
if (refresh)
main_frame();
if (refresh || (time.min != tmp_time.min)) // 分更新
{
if (!refresh)
flag = 0;
tmp_time.min = time.min;
play32_num(48, 2, time.min);
}
if (refresh || (time.hour != tmp_time.hour)) // 時更新
{
if ((!refresh)&&(Clock_flag))
alarm_sound();
tmp_time.hour = time.hour;
play32_num(0, 2, time.hour);
}
if (refresh || (time.day != tmp_time.day)) // 日更新
{
tmp_time.day = time.day;
play8_num(48, 0, time.day);
// 農(nóng)歷
turn_lunar_calendar(&time, lunar);
play_lunar_calendar(0, 6, lunar[0], lunar[1]);
}
if (refresh || (time.week != tmp_time.week)) // 周更新
{
tmp_time.week = time.week;
play_week(68, 0, time.week);
}
if (refresh || (time.mon != tmp_time.mon)) // 月更新
{
tmp_time.mon = time.mon;
play8_num(24, 0, time.mon);
// 農(nóng)歷
turn_lunar_calendar(&time, lunar);
play_lunar_calendar(0, 6, lunar[0], lunar[1]);
}
if (refresh || (time.year != tmp_time.year)) // 年更新
{
tmp_time.year = time.year;
play8_num(0, 0, time.year);
// 農(nóng)歷
turn_lunar_calendar(&time, lunar);
play_lunar_calendar(0, 6, lunar[0], lunar[1]);
}
}
/*
* 主機界面設(shè)置
*/
void main_set(void)
{
int8 key_val, state=1;
play32_num(96, 2|0x80, time.sec);
while (1)
{
key_val = scan_key();
if (key_val == 1) // 設(shè)置
{
if (state >= 7)
state = 0;
else
state++;
set_time((uint8 *)&time);
main_show(1);
switch (state)
{
case 0: set_time((uint8 *)&time); break;
case 1: play32_num(96, 2|0x80, time.sec); break;
case 2: play32_num(48, 2|0x80, time.min); break;
case 3: play32_num(0, 2|0x80, time.hour); break;
case 4: play_week(68, 0|0x80, time.week); break;
case 5: play8_num(48, 0|0x80, time.day); break;
case 6: play8_num(24, 0|0x80, time.mon); break;
case 7: play8_num(0, 0|0x80, time.year); break;
default: break;
}
}
else if (key_val > 1)
{
if (state == 1)
{
if (key_val == 3)
time.sec++;
else
time.sec--;
if (time.sec >= 60)
time.sec = 0;
else if (time.sec < 0)
time.sec = 59;
play32_num(96, 2|0x80, time.sec);
}
else if (state == 2)
{
if (key_val == 3)
time.min++;
else
time.min--;
if (time.min >= 60)
time.min = 0;
else if (time.min < 0)
time.min = 59;
play32_num(48, 2|0x80, time.min);
}
else if (state == 3)
{
if (key_val == 3)
time.hour++;
else
time.hour--;
if (time.hour >= 24)
time.hour = 0;
else if (time.hour < 0)
time.hour = 23;
play32_num(0, 2|0x80, time.hour);
}
else if (state == 4)
{
if (key_val == 3)
time.week++;
else
time.week--;
if (time.week >= 8)
time.week = 1;
else if (time.week < 1)
time.week = 7;
play_week(68, 0|0x80, time.week);
}
else if (state == 5)
{
if (key_val == 3)
time.day++;
else
time.day--;
if (time.day >= 32)
time.day = 1;
else if (time.day < 1)
time.day = 31;
play8_num(48, 0|0x80, time.day);
}
else if (state == 6)
{
if (key_val == 3)
time.mon++;
else
time.mon--;
if (time.mon >= 13)
time.mon = 1;
else if (time.mon < 1)
time.mon = 12;
play8_num(24, 0|0x80, time.mon);
}
else if (state == 7)
{
if (key_val == 3)
time.year++;
else
time.year--;
if (time.year >= 100)
time.year = 0;
else if (time.year < 0)
time.year = 99;
play8_num(0, 0|0x80, time.year);
}
else
{
break;
}
}
if (state == 0)
break;
}
}
/*
* 鬧鐘界面顯示
*/
void alarm_show(void)
{
int8 key_val, state=1;
uint32 t=0;
play16(0, 0, nao);
play16(16, 0, zhong);
play16(32, 0, maohao);
if (Alarm_flag)
play16(48, 0, kai);
else
play16(48, 0, guan);
play32_num(32, 2, alarm.hour);
play32(64, 2, 10);
play32_num(80, 2, alarm.min);
play16(0, 6, zheng);
play16(16, 6, dian);
play16(32, 6, bao);
play16(48, 6, shi);
play16(64, 6, maohao);
if (Clock_flag)
play16(80, 6, kai);
else
play16(80, 6, guan);
for (t=0; t<30000; t++)
{
key_val = scan_key();
if (key_val > 1)
break;
else if (key_val == 1)
{
if (Alarm_flag)
play16(48, 0|0x80, kai);
else
play16(48, 0|0x80, guan);
while (1)
{
key_val = scan_key();
if (key_val == 1) // 完成設(shè)置
{
if (state >= 4)
state = 0;
else
state++;
if (Alarm_flag)
play16(48, 0, kai);
else
play16(48, 0, guan);
play32_num(32, 2, alarm.hour);
play32_num(80, 2, alarm.min);
if (Clock_flag)
play16(80, 6, kai);
else
play16(80, 6, guan);
switch (state)
{
case 1:
if (Alarm_flag)
play16(48, 0|0x80, kai);
else
play16(48, 0|0x80, guan);
break;
case 2:
play32_num(80, 2|0x80, alarm.min);
break;
case 3:
play32_num(32, 2|0x80, alarm.hour);
break;
case 4:
if (Clock_flag)
play16(80, 6|0x80, kai);
else
play16(80, 6|0x80, guan);
break;
default: break;
}
}
else if (key_val > 1)
{
if (state == 1)
{
Alarm_flag = ~Alarm_flag;
if (Alarm_flag)
play16(48, 0|0x80, kai);
else
play16(48, 0|0x80, guan);
}
else if (state == 2)
{
if (key_val == 3)
alarm.min++;
else
alarm.min--;
if (alarm.min >= 60)
alarm.min = 0;
else if (alarm.min < 0)
alarm.min = 59;
play32_num(80, 2|0x80, alarm.min);
}
else if (state == 3)
{
if (key_val == 3)
alarm.hour++;
else
alarm.hour--;
if (alarm.hour >= 24)
alarm.hour = 0;
else if (alarm.hour < 0)
alarm.hour = 23;
play32_num(32, 2|0x80, alarm.hour);
}
else if (state == 4)
{
Clock_flag = ~Clock_flag;
if (Clock_flag)
play16(80, 6|0x80, kai);
else
play16(80, 6|0x80, guan);
}
else
{
break;
}
}
if (state == 0)
break;
}
if (state == 0)
break;
}
}
}
main()
{
uint8 key_val;
read_18B20(); //讀溫度
Delay_nms(1000);//延時1S,等待18B20工作正常
LCD_init(); //初始化液晶
clear12864(); //清屏幕
main_frame(); //顯示主界面框架
main_show(1); //刷新1次
read_18B20(); //讀溫度
play8_num(104, 6,zhengshu); //顯示溫度
while(1)
{
key_val = scan_key();
if (key_val == 1) //K1?
{
main_set();
}
else if (key_val == 2) //K2?
{
clear12864(); //清屏幕
alarm_show();
clear12864(); //清屏幕
main_show(1);
}
else if (key_val == 3) //K3?
{
clear12864(); //清屏幕
alarm_show();
clear12864(); //清屏幕
main_show(1);
}
else
{
read_time((uint8 *)&time);
main_show(0);
if((time.sec%2)==0){read_18B20();} //每隔2S采集一次
}
// 鬧鐘
if (Alarm_flag)
{
if ((flag == 0) && (alarm.hour == time.hour) && (alarm.min == time.min))
{
flag = 1;
clear12864(); //清屏幕
alarm_show(); //鬧鐘
PlayMusic(); //播放音樂
PlayMusic(); //播放音樂
clear12864(); //清屏幕
main_show(1); //
}
}
}
}
復制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1