關于設計單片機萬年歷的識訓
1.在改程式中的錯誤的程序中,知道了許多錯誤型別,增加了經驗,而且我深刻的體會到了做任何事都要有耐心~
2.在結合模塊的程序中,我知道了扎實基礎很重要,不然這個程序會很混亂…
3.不能半途而廢,程式中有些錯誤改不出來時,有些內容不理解時,我想過換一些模塊聯動,但是我相信堅持就是勝利~
4.虛心求教的重要性,問過CSDN上的其他博主,B站上的老師等等,他們都給我提供了有力的幫助~
!!萬年歷具有讀取方便,顯示直觀,功能多樣,電路簡潔等優點
功能:
1.顯示年,月,日,時,分,秒
2.顯示溫度
3.顯示星期
4.按鍵調節各引數,分別為設定鍵,加鍵,減鍵設定鬧鐘鍵
一. 電路組成
1.單片機最小系統
2.LCD1602液晶顯示屏電路
3.四路獨立按鍵
4.DS1302時鐘電路
5.DS18B20溫度傳感器
6.系統電源
二.lcd1602介紹
1.引腳定義
VL引腳:為液晶顯示幕對比度調整端
RS引腳:RS為暫存器選擇,高電平時選擇資料暫存器、低電平時選擇指令暫存器
R/W引腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作,當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W為高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入資料,
EN引腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令,

2.控制程式:寫資料、寫指令、初始化
讀狀態:輸入:RS=L,RW=H,E=H----輸出:D0~D7=狀態字
寫指令:輸入:RS=L,RW=L,D0~D7=指令碼----輸出:無
讀資料:輸入:RS=H,RW=H,E=H----輸出:D0~D7=資料
寫資料:輸入:RS=H,RW=L,D0~D7=資料,E=高脈沖----輸出:無
(1)寫資料函式
(2)寫指令函式
(3)初始化函式
a.設定寫操作:R/W設為低電平;
b.螢屏設定模式:寫指令38H;
c.打開顯示,關閉游標:寫指令0CH;
d.設定顯示游標移動位置:寫指令06H;
e.設定字符顯示位置:寫指令(字符顯示的起始位置);
由于對LCD1602進行控制時不需要實作讀操作,所以R/W在初始化后恒為低電平;對控制器每次進行讀寫操作前,都必須進行讀寫檢測,確保STA7為0
三.DS18B20介紹
1.初始化
在操作時序的時候,為了防止中斷干擾總線時序,先關閉總中斷,拉低 DS18B20 這個引腳,持續 500us;延時 60us;讀取存在脈沖,并且等待存在脈沖結束,
2.ROM 操作指令
3.RAM 存盤器操作指令
4.DS18B20的位讀寫時序
四.ds1302介紹
本系統的時間讀取主要來源于單片機對ds1302的操作
引腳功能

內部結構
暫存器
操作方法:啟動傳送,發送命令位元組,傳送資料
ds18b20
uchar ds18b20_read()
{ //讀一個位元組
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
dq = 0; // 給脈沖信號
dat>>=1;
dq = 1; // 給脈沖信號
if(dq)
dat|=0x80;
delay1(4);
}
return(dat);
}
void ds18b20_write(char dat)
{ //寫一個位元組
uchar i=0;
for (i=8; i>0; i--)
{
dq = 0;
dq = dat&0x01;
delay1(5);
dq = 1;
dat>>=1;
}
}
int ds18b20_read_temp()
{ //讀取溫度
uchar low;
uchar high;
unsigned long tmp;
float value;
int t;//溫度
ds18b20_init();
ds18b20_write(0xCC); //跳過讀序列號的操作
ds18b20_write(0x44); //啟動溫度轉換
ds18b20_init();
ds18b20_write(0xCC); //跳過讀序列號的操作
ds18b20_write(0xBE); //讀取溫度暫存器
low=ds18b20_read();//低八位資料
high=ds18b20_read();//高八位資料
tmp=high;
tmp<<=8;
tmp=tmp|low;//此處有正負之分
if(tmp>=63488)
{ //ffff f000 0000 0000-->(f800)
temp_flag=0;//8位全為1時,加1才進位
if((~low)==0xff)
{ //判斷low取反加1之后是否進位
high=(~high)+1;
low=0;
}
else
{
high=~high;
low=(~low)+1;
}
tmp=high*256+low;
}
else
{
temp_flag=1;
}
value=tmp*0.0625;
t=value*10+((temp_flag==1)?+0.5:-0.5);//放大十倍輸出并四舍五入
return t;
}
LCD1602
void write_1602com(uchar com)
{ //1602寫指令
rs=0;
lcden=0;
P2=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_1602data(uchar dat)
{ //1602寫資料
rs=1;
lcden=0;
P2=dat;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init_1602()
{ //初始化1602液晶
rw=0;
lcden=0;
write_1602com(0x38);//設定顯示模式
write_1602com(0x0c);//顯示開關及游標是否顯示和閃動
write_1602com(0x06);//游標移動方向
write_1602com(0x01);//清屏
}
ds1302
void write_ds1302_byte(uchar temp)
{ //ds1302寫一個位元組資料
uchar i;
for(i=0;i<8;i++)
{
io=temp&0x01;//將資料放到IO口上
scl=0;//scl為低時準備資料
scl=1;//上升沿寫入
temp>>=1;
}
}
void write_ds1302(uchar add,uchar dat)
{ //向地址add寫入資料dat
rst=0;
scl=0;
rst=1;
write_ds1302_byte(add);
write_ds1302_byte(dat);
scl=1;
rst=0;
}
uchar read_ds1302(uchar add)
{ //ds1302讀資料
uchar i,dat;
rst=0;
scl=0;
rst=1;
write_ds1302_byte(add);//首先寫入要讀的資料處的地址
for(i=0;i<8;i++)
{
if(io==1)
{
dat|=0x80;
}
scl=1;
scl=0;//下降沿讀取資料
dat>>=1;
}
scl=1;
rst=0;
return dat;
}
void read_time(uchar curr_time[])
{
uchar i;
uchar ucAddr = 0x81;
for (i=0;i<7;i++)
{
curr_time[i] = read_ds1302(ucAddr);//格式為: 秒 分 時 日 月 星期 年
ucAddr += 2;
}
}
void set_time(uchar *pSecDa)
{ //設定時間
uchar i;
uchar ucAddr = 0x80;
write_ds1302(0x8e,0x00);
for(i =7;i>0;i--)
{
write_ds1302(ucAddr,*pSecDa); //秒 分 時 日 月 星期 年
pSecDa++;
ucAddr+=2;
}
write_ds1302(0x8e,0x80);
}
void init_ds1302()
{ //ds1302初始化
isInit_1302=read_ds1302(0x81);//讀出時鐘狀態
if(isInit_1302&0x80)
{ //說明沒有初始化
write_ds1302(0x8e,0x00);//關閉寫保護
write_ds1302(0x90,0xa5); //輔助電源充電命令 一個二極管一個2K電阻
write_ds1302(0x80,0x00);//秒 CH置0 開啟時鐘
write_ds1302(0x82,0x59);//分
write_ds1302(0x84,0x10);//時
write_ds1302(0x86,0x07);//日
write_ds1302(0x88,0x05);//月
write_ds1302(0x8a,0x04);//星期
write_ds1302(0x8c,0x14);//年
write_ds1302(0x8e,0x80);
}
}
鬧鐘設定
void init_alarm()
{ //鬧鐘設定界面 只有首次進入才執行
uchar code x[]="SET ALARM";
uchar i;
if(alarm==0)
{
write_1602com(0x01);//清屏
write_1602com(0x80+3);//設定資料指標
for(i=0;i<9;i++)
{
write_1602data(x[i]);
}
display_alarm(0x80+0x40+5,shi);//載入鬧鐘的時分
write_1602com(0x80+0x40+7);
write_1602data(':');
display_alarm(0x80+0x40+8,fen);
if(isOpen)
{ //初始化的時候如果已經設定鬧鐘則顯示ON
write_1602com(0x80+0x40+13);
write_1602data(' ');
write_1602data('O');
write_1602data('N');
}
else
{
write_1602com(0x80+0x40+13);
write_1602data('O');
write_1602data('F');
write_1602data('F');
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278154.html
標籤:其他
上一篇:我們遇到瓶頸了
