文章目錄
- 0 前言
- 1 設(shè)計內(nèi)容
- 2 軟件設(shè)計
- 3 關(guān)鍵代碼
- 4 最后
0 前言
??
這兩年開始畢業(yè)設(shè)計和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點,往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長自己做的項目系統(tǒng)達(dá)不到老師的要求。
為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長分享優(yōu)質(zhì)畢業(yè)設(shè)計項目,今天要分享的是
?? 基于STM32與wifi的天氣預(yù)報網(wǎng)時鐘系統(tǒng)
??學(xué)長這里給一個題目綜合評分(每項滿分5分)
- 難度系數(shù):3分
- 工作量:3分
- 創(chuàng)新點:3分
1 設(shè)計內(nèi)容
該項目中學(xué)長是以實時時鐘芯片DS1302和STM32F103C8T6
單片機(jī)為主要研究對象,著重進(jìn)行嵌入式控制系統(tǒng)的設(shè)計研究和如何讀取DS1302內(nèi)部時鐘信息的研究。以及運用18B20進(jìn)行實時溫度檢測。
主要內(nèi)容包括:
- 1)實時溫度顯示;
- 2)年月日星期時分秒顯示;
- 3)年月日星期時分秒調(diào)整;
- 4)鬧鐘定時小時分鐘和秒;
原理圖如下
2 軟件設(shè)計
主程序開始初始化,并打開中斷,然后執(zhí)行掃描鬧鐘、鍵盤及讀取18B20值。當(dāng)有S1鍵按下時,執(zhí)行時鐘設(shè)置,當(dāng)有S4鍵按下時,則進(jìn)入鬧鐘設(shè)置,無論是時鐘還是鬧鐘,設(shè)置完后退出,溫度、時鐘恢復(fù)實時顯示。主程序流程圖如圖
通過單片機(jī)判斷S1按下的次數(shù)來設(shè)置,由s1num標(biāo)志位來記錄次數(shù),用if語句判斷執(zhí)行命令。系統(tǒng)程序不斷掃面鍵盤,當(dāng)s1鍵按下后產(chǎn)生一個低電平,即s1num加一。在調(diào)節(jié)時間之前首先進(jìn)行各個變量初始化,及設(shè)置起始時間,同時為讀取數(shù)據(jù)作準(zhǔn)備。當(dāng)s1=1時進(jìn)入秒的設(shè)置,地址指針指向miao顯示位置處,通過兩個if語句分別循環(huán)控制顯示秒數(shù)的加和減。當(dāng)s1=2時,地址指針指向fen顯示位置處,變量最大值為59。當(dāng)s1=3時,地址指針指向shi顯示位置處,變量最大值設(shè)為23。當(dāng)s1=4時,地址指針指向week顯示位置處,最大值設(shè)為7,1至7分別用MON、TUE、WED、THU
、FRI、SAT、SUN字符串顯示。隨著s2、s3值的的變化顯示不同的字符串。當(dāng)s1=5時,地址指針指向day顯示位置,變量最大值為31。當(dāng)s1=6時,地址指針指向month顯示位置,變量最大值為12。
當(dāng)s1=7時,地址指針指向year顯示位置,最大值為99。
時間設(shè)置程序流程圖如圖3-3所示。在開始時間設(shè)置之前程序會關(guān)閉全局中斷,直至設(shè)置結(jié)束,中斷又會重新開啟,進(jìn)入計時狀態(tài)。
鬧鐘的設(shè)置時通過S1鍵的按下次數(shù)來判斷的。當(dāng)單片機(jī)檢測到S4鍵按下一次時則進(jìn)入鬧鐘設(shè)置界面,光標(biāo)并自動跳到秒設(shè)置位置,可以對秒進(jìn)行設(shè)置,當(dāng)S1鍵依次按下1、2、3次時,則分別進(jìn)入鬧鐘的秒、分、時關(guān)的設(shè)置。:
3 關(guān)鍵代碼
?
? #include “stm32f10x.h”
? #include “delay.h”
? #include “usart.h”
? #include “sys.h”
? #include “1302.h”
? #include “key.h”
? #include “timer.h”
? #include “flash.h”
? #include “ds18b20.h”
? #include “time2.h”
? #include “beep.h”
? #include “l(fā)cd1602.h”
? u8 key = 0;
? u8 keyflag = 0;
? u8 time[8];
? int flag1 = 0;
? u8 flag2 = 0;//鬧鐘開關(guān)狀態(tài)
? u8 flag3;
? int beepflag1 = 0;
? u8 n = ’ ';
? u8 memory_flag=0;
? extern u8 flag4;
? extern u8 flag5;
? extern my_time TIME;
? extern u8 time4flag;
? u8 nolock[] = {15,30};
? #define size sizeof(nolock)
? u8 nolock1[size];
? short temperature; //接收讀取到的溫度
? //#define FLASH_SAVE_ADDR 0X0800b000 //存儲的地址p
? //#define FLASH_SAVE_ADDR1 0X0800C000 //存儲的地址
? //#define FLASH_SAVE_ADDR2 0X0800CB00 //存儲的地址
? u8 state,s0;
? u8 key1_flag=1,key2_flag=1,key3_flag=1,key4_flag=1;
? u8 sec1,sec2;
? u8 ms=0;
? u8 read_flag=1;
? u8 time_data[7];
? u8 time_data_1[7];
? u8 time_data_2[7];
? u8 time_data_3[7];
? u8 time_data_4[7];
? u8 beep1=0;
?
void memory()
{//08002400
STMFLASH_Write(0X0800b000,(u16*)nolock1,2);
STMFLASH_Write(0X0800C000,(u16*)&flag2,1);
}
void read_memory()
{
STMFLASH_Read(0X0800b000,(u16*)nolock1,2);
STMFLASH_Read(0X0800C000,(u16*)&flag2,1);
if(nolock1[0]>23||nolock1[1]>59||flag2>1)
{
nolock1[0]=6;
nolock1[1]=30;
flag2=1;
}
}
void dis_play()
{
if(state<7)
{
LCD1602_Set_Cursor(0,0);
if(state==1&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Show_Str("20");
LCD1602_Set_Cursor(2,0);
LCD1602_Write_Dat('0'+TIME.year/10%10);
LCD1602_Write_Dat('0'+TIME.year%10); //年
}
LCD1602_Show_Str("-");
if(state==2&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Write_Dat('0'+TIME.month/10%10);
LCD1602_Write_Dat('0'+TIME.month%10); //月
}
LCD1602_Show_Str("-");
if(state==3&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Write_Dat('0'+TIME.date/10%10);
LCD1602_Write_Dat('0'+TIME.date%10); //日
}
LCD1602_Show_Str(" ");
switch(Conver_week(TIME.year,TIME.month,TIME.date)) //星期
{
case 0:LCD1602_Show_Str("Sun"); break;
case 1:LCD1602_Show_Str("Mon"); break;
case 2:LCD1602_Show_Str("Tue"); break;
case 3:LCD1602_Show_Str("Wed"); break;
case 4:LCD1602_Show_Str("Thu"); break;
case 5:LCD1602_Show_Str("Fri"); break;
case 6:LCD1602_Show_Str("Sat"); break;
}
LCD1602_Set_Cursor(0,1);
if(state==4&&s0)
{
LCD1602_Show_Str(" ") ;
}
else
{
LCD1602_Write_Dat('0'+TIME.hour/10%10);
LCD1602_Write_Dat('0'+TIME.hour%10); //時
}
LCD1602_Show_Str(":");
if(state==5&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Write_Dat('0'+TIME.minute/10%10); //分
LCD1602_Write_Dat('0'+TIME.minute%10);
}
LCD1602_Show_Str(":");
if(state==6&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Write_Dat('0'+TIME.second/10%10); //秒
LCD1602_Write_Dat('0'+TIME.second%10);
}
LCD1602_Show_Str(" ");
if(temperature<0)
{
temperature=-temperature;
LCD1602_Write_Dat('-');
LCD1602_Write_Dat(0x30+temperature/100%10); //取出第一位
LCD1602_Write_Dat(0x30+temperature%100/10); //取出第二位
LCD1602_Write_Dat(0x2E);
LCD1602_Write_Dat(0x30+temperature%10); //取出最后一位
LCD1602_Write_Dat(0xDF);
LCD1602_Write_Dat('C');
}
else if(temperature>999)
{
LCD1602_Write_Dat(0x30+temperature/1000%10); //取出第一位
LCD1602_Write_Dat(0x30+temperature%1000/100); //取出第一位
LCD1602_Write_Dat(0x30+temperature%1000/10%10); //取出第二位
LCD1602_Write_Dat(0x2E);
LCD1602_Write_Dat(0x30+temperature%10); //取出最后一位
LCD1602_Write_Dat(0xDF);
LCD1602_Write_Dat('C');
}
else
{
//LCD1602_Write_Cmd(0x80+0x40+0x09);
LCD1602_Write_Dat(' ');
LCD1602_Write_Dat(0x30+temperature/100%10); //取出第一位
LCD1602_Write_Dat(0x30+temperature%100/10); //取出第二位
LCD1602_Write_Dat(0x2E);
LCD1602_Write_Dat(0x30+temperature%10); //取出最后一位
LCD1602_Write_Dat(0xDF);
LCD1602_Write_Dat('C');
}
}
else
{
LCD1602_Set_Cursor(0,0);
LCD1602_Show_Str(" clock: ");
LCD1602_Set_Cursor(0,1);
LCD1602_Show_Str(" ");
if(state==7&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Write_Dat('0'+nolock1[0]/10%10);
LCD1602_Write_Dat('0'+nolock1[0]%10); //鬧鐘-時
}
LCD1602_Show_Str(":");
if(state==8&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
LCD1602_Write_Dat('0'+nolock1[1]/10%10);
LCD1602_Write_Dat('0'+nolock1[1]%10); //鬧鐘-分
}
LCD1602_Show_Str(" ");
if(state==9&&s0)
{
LCD1602_Show_Str(" ");
}
else
{
if(flag2 == 0) LCD1602_Show_Str(" on");
else if(flag2 == 1) LCD1602_Show_Str("off");
}
LCD1602_Show_Str(" ");
}
}
void key_scan() //系統(tǒng)按鍵控制程序
{
if(key1==0)
{
if(key1_flag)
{
key1_flag=0;
state=(state+1)%10;
}
}
else
{
key1_flag=1;
}
if(!key2) //手動上轉(zhuǎn)動控制
{
if(key2_flag)
{
key2_flag=0;
if(state>0&&state<7)
{
if(state==1)
{
TIME.year=(TIME.year+1)%100;
}
else if(state==2)
{
TIME.month=TIME.month%12+1;
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
if(TIME.date>29)TIME.date=29;
}
else
{
if(TIME.date>28) TIME.date=28;
}
}
else if(TIME.month==4||TIME.month==6||TIME.month==9||TIME.month==11)
{
if(TIME.date>30) TIME.date=30;
}
}
else if(state==3)
{
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
TIME.date=TIME.date%29+1;
}
else
{
TIME.date=TIME.date%28+1;
}
}
else if(TIME.month==1||TIME.month==3||TIME.month==5||TIME.month==7||TIME.month==8||TIME.month==10||TIME.month==12)
{
TIME.date=TIME.date%31+1;
}
else
{
TIME.date=TIME.date%30+1;
}
}
else if(state==4)
{
TIME.hour=(TIME.hour+1)%24;
}
else if(state==5)
{
TIME.minute=(TIME.minute+1)%60;
}
else if(state==6)
{
TIME.second=(TIME.second+1)%60;
}
}
else if(state!=0)
{
if(state==7)
{
nolock1[0]=(nolock1[0]+1)%24;
}
else if(state==8)
{
nolock1[1]=(nolock1[1]+1)%60;
}
else if(state==9)
{
flag2=0;
}
}
}
if(sec1==0) //判斷是否長按,如果長按,實現(xiàn)連加效果
{
if(state!=0&&state<7) //設(shè)置萬年歷
{
if(state==1)
{
TIME.year=(TIME.year+1)%100;
}
else if(state==2)
{
TIME.month=TIME.month%12+1;
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
if(TIME.date>29)TIME.date=29;
}
else
{
if(TIME.date>28) TIME.date=28;
}
}
else if(TIME.month==4||TIME.month==6||TIME.month==9||TIME.month==11)
{
if(TIME.date>30) TIME.date=30;
}
}
else if(state==3)
{
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
TIME.date=TIME.date%29+1;
}
else
{
TIME.date=TIME.date%28+1;
}
}
else if(TIME.month==1||TIME.month==3||TIME.month==5||TIME.month==7||TIME.month==8||TIME.month==10||TIME.month==12)
{
TIME.date=TIME.date%31+1;
}
else
{
TIME.date=TIME.date%30+1;
}
}
else if(state==4)
{
TIME.hour=(TIME.hour+1)%24;
}
else if(state==5)
{
TIME.minute=(TIME.minute+1)%60;
}
else if(state==6)
{
TIME.second=(TIME.second+1)%60;
}
}
else if(state!=0)
{
if(state==7)
{
nolock1[0]=(nolock1[0]+1)%24;
}
else if(state==8)
{
nolock1[1]=(nolock1[1]+1)%60;
}
else if(state==9)
{
flag2=0;
}
}
}
}
else
{
sec1=2;
if(key2_flag==0)
{
memory_flag=1;
key2_flag=1;
}
}
if(!key3) //手動下轉(zhuǎn)動控制監(jiān)測
{
if(key3_flag)
{
key3_flag=0;
if(state!=0&&state<7)
{
if(state==1)
{
TIME.year--;
if(TIME.year>120) TIME.year=99;
}
else if(state==2)
{
TIME.month--;
if(TIME.month==0) TIME.month=12;
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
if(TIME.date>29)TIME.date=29;
}
else
{
if(TIME.date>28) TIME.date=28;
}
}
else if(TIME.month==4||TIME.month==6||TIME.month==9||TIME.month==11)
{
if(TIME.date>30) TIME.date=30;
}
}
else if(state==3)
{
TIME.date--;
if(TIME.date==0)
{
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
TIME.date=29;
}
else
{
TIME.date=28;
}
}
else if(TIME.month==1||TIME.month==3||TIME.month==5||TIME.month==7||TIME.month==8||TIME.month==10||TIME.month==12)
{
TIME.date=31;
}
else
{
TIME.date=30;
}
}
}
else if(state==4)
{
TIME.hour--;
if(TIME.hour>25) TIME.hour=23;
}
else if(state==5)
{
TIME.minute--;
if(TIME.minute>60) TIME.minute=59;
}
else if(state==6)
{
TIME.second--;
if(TIME.second>60) TIME.second=59;
}
}
else if(state!=0)
{
if(state==7)
{
nolock1[0]--;
if(nolock1[0]>25) nolock1[0]=23;
}
else if(state==8)
{
nolock1[1]--;
if(nolock1[1]>60) nolock1[1]=59;
}
else if(state==9)
{
flag2=1;
}
}
}
if(sec2==0) //判斷是否長按,如果長按,實現(xiàn)連減效果
{
if(state!=0&&state<7)
{
if(state==1)
{
TIME.year--;
if(TIME.year>120) TIME.year=99;
}
else if(state==2)
{
TIME.month--;
if(TIME.month==0) TIME.month=12;
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
if(TIME.date>29)TIME.date=29;
}
else
{
if(TIME.date>28) TIME.date=28;
}
}
else if(TIME.month==4||TIME.month==6||TIME.month==9||TIME.month==11)
{
if(TIME.date>30) TIME.date=30;
}
}
else if(state==3)
{
TIME.date--;
if(TIME.date==0)
{
if(TIME.month==2)
{
if((TIME.year%4==0&&TIME.year%100!=0)||TIME.year==0)
{
TIME.date=29;
}
else
{
TIME.date=28;
}
}
else if(TIME.month==1||TIME.month==3||TIME.month==5||TIME.month==7||TIME.month==8||TIME.month==10||TIME.month==12)
{
TIME.date=31;
}
else
{
TIME.date=30;
}
}
}
else if(state==4)
{
TIME.hour--;
if(TIME.hour>25) TIME.hour=23;
}
else if(state==5)
{
TIME.minute--;
if(TIME.minute>60) TIME.minute=59;
}
else if(state==6)
{
TIME.second--;
if(TIME.second>60) TIME.second=59;
}
}
else if(state!=0)
{
if(state==7)
{
nolock1[0]--;
if(nolock1[0]>25) nolock1[0]=23;
}
else if(state==8)
{
nolock1[1]--;
if(nolock1[1]>60) nolock1[1]=59;
}
else if(state==9)
{
flag2=1;
}
}
}
}else //否則上下轉(zhuǎn)動標(biāo)志位清0
{
if(key3_flag==0)
{
memory_flag=1;
key3_flag=1;
}
sec2=2;
}
if(key4==0)
{
if(key4_flag)
{
key4_flag=0;
state=0;
}
}
else
{
key4_flag=1;
}
}
?
?
? void clock_dispose()
? {
? if(state0&&flag20&&nolock1[0]TIME.hour&&nolock1[1] == TIME.minute)
? {
? if(TIME.second0) beep1=1;
? }
? else
? {
? beep1=0;
? }
? }
?
int main(void)
{
delay_init();
BEEP_Init();
delay_ms(20);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
LCD1602_Init();
KEY_Init();
ds1302_gpio_init();
do
{
temperature=DS18B20_Get_Temp();
}while(temperature == 850);
TIM3_Int_Init(4999, 7199);
TIM4_Int_Init(499 ,7199);
read_memory();
while(1)
{
if(read_flag)
{
read_flag=0;
temperature=DS18B20_Get_Temp(); //獲取溫度 返回的是一個三位數(shù)short型的整數(shù)
}
read_time1();
clock_dispose();
dis_play();
if(memory_flag)
{
memory_flag=0;
memory();
}
}
}文章來源:http://www.zghlxwxcb.cn/news/detail-742017.html
?
? void TIM4_IRQHandler(void) //TIM4中斷
? {
? if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //檢查TIM2更新中斷發(fā)生與否
? {
?
if(beep1)
{
if(key10||key20||key30||key40)
{
beep1=0;
}
}
else
{
key_scan();
}
ms++;
if(ms%50)
{
if(beep1)
{
BEEP=~BEEP;
}
else
{
BEEP=0;
}
s0=~s0;
}
if(ms%100)
{
if(sec1!=0) sec1–;
if(sec2!=0) sec2–;
}
if(ms>=20)
{
ms=0;
read_flag=1;
}
}
TIM_ClearITPendingBit(TIM4, TIM_IT_Update );
}文章來源地址http://www.zghlxwxcb.cn/news/detail-742017.html
最后
到了這里,關(guān)于畢業(yè)設(shè)計 基于STM32與wifi的天氣預(yù)報網(wǎng)時鐘系統(tǒng) - 物聯(lián)網(wǎng) 單片機(jī)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!