基於51單片機電子時鐘

塵書休 發佈 2024-04-26T13:07:33.992009+00:00

能實現整時報時的功能。mod=0,1.2,3分別對應時鐘模式,調整模式,鬧鐘設置模式,一分鐘倒計時模式。

1 基於51單片機用LCD1602實現時-分的顯示

2. 按鍵控制時-分的調整

3. 能實現整時報時的功能(蜂鳴器響)

4. 鬧鐘模式

5.按鍵切換模式(模式一:時-分顯示,模式二:60秒倒計時)


一、設計思路:

主體:

通過外部中斷0來控制mod值;mod=0,1.2,3分別對應時鐘模式,調整模式,鬧鐘設置模式,一分鐘倒計時模式。

細節:

mod0

通過定時計數器,每一秒增加變量秒(s),每60秒,增加1分(min)並且s置0,每60min,增加1小時h,當h>23,h=0;進行一天循環

mod1

按鍵控制增加min,h和s制0

mod2

另外設置變量min1,h1,當min=min1,h=h1時蜂鳴器響

mod3

設置變量daojishi=60, 通過定時計數器,每一秒daojishi減1,當daojishi<0時,蜂鳴器響

另外:

1.設置外部中斷2,關閉蜂鳴器

2.時間發送一次只能發送一個位


程序:


#include

//K1後K3加分鐘,K4加時間,K2加秒,K1進入鬧鐘設置,K2退出

//K2關閉鬧鐘


typedef unsigned int u16; //對數據類型進行聲明定義

typedef unsigned char u8;


#define data8b P1


sbit K1=P3^2; //外部中斷0

sbit K2=P3^3; //外部中斷1

sbit K3=P3^0;

sbit K4=P3^1;


sbit BUZ=P2^4; //蜂鳴器,0響

sbit RW=P2^5; //4腳,數據(1)or命令(0)

sbit RS=P2^6; //5腳,讀(1)寫(0)

sbit E=P2^7; //6腳,使能信號


u8 code dat1[]={0X30,0X31,0X32,0X33,

0X34,0X35,0X36,0X37,

0X38,0X39};


void delay(u16 i) //延時函數

{

while(i--);

}


void open012() //打開中斷0,1,定時器中斷0

{

TMOD|=0X01; //選擇為定時器0模式,工作方式1

ET0=1; //打開定時器0中斷允許

EA=1; //打開總中斷

TR0=1; //打開定時器

EX0=1; //打開外部中斷0

IT0=1; //邊沿觸發方式

EX1=1; //打開外部中斷1

IT1=1; //邊沿觸發

}



void wrm(u8 dat) //寫入命令

{

delay(1000);

RS=0;

RW=0;

E=0;

data8b=dat;

E=1;

delay(1000);

E=0;

}



void wrd(u8 dat) //寫入數據

{

delay(1000);

RS=1;

RW=0;

E=0;

data8b=dat;

E=1;

delay(1000);

E=0;

}


void zero()

{

wrm(0X38); //八位數據,兩行顯示,5*7

wrm(0X0c); //無光標,打開顯示

wrm(0X06); //光標右移,屏幕不移動

wrm(0X01); //清屏

wrm(0X80); //設置數據指針起點

}


u8 fg=0,sg=0,bfg=0,bsg=0;

u16 i=0;

u8 s=0;

u8 mod=0;

char dingshi;

bit bell=0;

bit zanting=1;


void fangsong()

{

wrd(dat1[sg/10]); //時十位

wrd(dat1[sg%10]); //時個位

wrd(0x3A); //:

wrd(dat1[fg/10]); //分十位

wrd(dat1[fg%10]); //分個位

wrd(0x3A); //:

wrd(dat1[(s/10)]); //秒十

wrd(dat1[(s%10)]); //秒個

}



void fangsong1()

{

wrm(0X80);

wrd(dat1[sg/10]); //時十位

wrd(dat1[sg%10]); //時個位

wrd(0x3A); //:

wrd(dat1[fg/10]); //分十位

wrd(dat1[fg%10]); //分個位

wrd(0x3A); //:

wrd(dat1[(s/10)]); //秒十

wrd(dat1[(s%10)]); //秒個

}

void chuli()

{

if(fg==60)

{

sg++;

fg=0;

}


if(sg==24)

{

sg=0;

}

}




void main()

{

u8 shijian;

open012();

zero();

chuli();

fangsong();

shijian=100;

while(1)

{

while(mod==0)

{

EX1=1; //打開外部中斷1

if(s==60)

{

fg++; //60秒轉化為1分鐘

s=0;

}

chuli();

if((fg==0)&&(shijian!=sg))

{

BUZ=0;

shijian=sg;

}

fangsong1();

if((BUZ==0)&&(bell==0))

{

delay(1000);

BUZ=1;

}

if((fg==bfg)&&(sg==bsg)&&(bell==1))

BUZ=0;

else BUZ=1;

}

while(mod==1)

{

EX1=0; //關閉外部中斷1

zero();

fangsong();

if(K3==0)

{

delay(1000);

if(K3==0)

fg++;

}

if(K4==0)

{

delay(1000);

if(K4==0)

sg++;

}

if(K2==0)

{

delay(1000);

if(K2==0)

s=0;

}

if(fg>59)

{

fg=0;

}

if(sg>23)

{

sg=0;

}

if(s>=59)

{

s=0;

}

}

while(mod==2) //設置鬧鐘

{

if(bfg==60)

{

bsg++;

bsg=0;

}

if(bsg==24)

{

bsg=0;

}

zero();

wrd(0x20);

wrd(0x20);

wrd(0x20);

wrd(dat1[(bsg/10)]); //時十位

wrd(dat1[(bsg%10)]); //時個位

wrd(0x3A); //:

wrd(dat1[(bfg/10)]); //分十位

wrd(dat1[(bfg%10)]); //分個位

if(K3==0)

{

delay(1000);

if(K3==0)

bfg++;

}

if(K4==0)

{

delay(1000);

if(K4==0)

bsg++;

}

bell=1;

zero();

}

while(mod==3)

{

while(zanting)

{

dingshi=60;

EX1=1; //打開外部中斷1

wrm(0X80);

wrd(dat1[(dingshi/10)]); //時十位

wrd(dat1[(dingshi%10)]); //時個位

}

wrm(0X80);

wrd(dat1[(dingshi/10)]); //時十位

wrd(dat1[(dingshi%10)]); //時個位

while(dingshi<0)

{

wrm(0X80);

wrd(dat1[0]); //時十位

wrd(dat1[0]); //時個位

BUZ=0;

}

}

}

}


void time0() interrupt 1

{

TH0=0XFC; //給定時器賦初值,定時1ms

TL0=0X18;

i++;

if(i==1000) //ms轉化為s

{

i=0;

s++;

dingshi--;

}

}


void key1() interrupt 0 //外部中斷0,調整時間

{

delay(1000);

if(K1==0)

{

mod++;

while(!K1);

}


if(mod>3)

{

mod=0;

}

zero();

}


void naozhong() interrupt 2 //開關鬧鐘

{

if(K2==0)

{

delay(1000); //消抖

if(K2==0)

{

bell=0;

BUZ=1;

zanting=~zanting;

} //關閉蜂鳴器

while(!K2); //確認按鍵鬆開

}

}

二、收穫

1.更熟練掌握了定時器中斷和外部中斷的使用

可以通過打開和關閉外部中斷使同一個按鍵實現不同的功能


2.了解到了一點寄存器操作

3.中斷配置小結

外部中斷

定時器中斷

串口通信

4.更熟練使用proteus

製作了一個小型軟體開發版

5.學會了如何學習一個新元器件(LCD1602)

1.看說明書,重點是看時序圖,真值表等

2.按照時序圖寫程序

3.一二都不成立時,查找相關資料

6.下載原理

單片機的燒寫原理:

單片機燒寫,又稱為單片機程序下載、燒錄等,本質上是單片機和PC機按照晶片廠家規定的編程協議,通過晶片廠家規定的接口,把已編譯好的程序傳輸到單片機,單片機把數據存儲到自身存儲器中。

理解這個原理需要知道幾個知識點:

單片機內部是有程序的,是出廠時固化在硬體中,用戶無法修改的(這也會被認為它內部沒有程序),這些程序可以調用各種通信接口、內部存儲器等;

可以下載的通信接口:JTAG,SPI,UART,usb等;(還有很多可以擴展485、乙太網等)

編程協議:一般大廠都會公開的,在晶片的專用技術手冊中會有;

存儲器:有很多種,掩膜,EPROM,EEROM,flash等壽命不一樣,掩膜只能一次,而且要工廠做,flash擦寫次數10000+;

可以這樣比喻性的理解:單片機就是電腦的主板,我們寫的程序就是作業系統,主板裡面裝入引導作業系統的基本程序,下載程序就是給電腦裝系統!


7.其他

1.理解了現在電子表的操作原理

2.學會了藉助現成品(電子表)作參考,寫程序

3.懂得了與人交流的重要性(受王同學的啟發,完善了原有程序)


三.後期計劃

1、繼續32的學習

2、練習焊功

3、繼續51其他外設的學習

4、按興趣學習電路、模電、數電、DXP等相關知識

找元器件現貨上唯樣商城

關鍵字: