這是我寫(xiě)的單片機(jī)小程序,將單片機(jī)開(kāi)發(fā)板上的ds1302,ds18b20和1602綜合起來(lái),在1602上顯示年月日周時(shí)分秒和溫度;望各位好友指點(diǎn),此程序僅適用于我的開(kāi)發(fā)板,用在其他開(kāi)發(fā)板上應(yīng)該改下端口就可以。
#include <reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; typedef long int uint32; //**************************************************************************************************** sbit DQ=P2^2;//********************供18b20使用的變量 float T; //**************************************************************************************************** uint8 counter_0,counter_1;//*******供1302使用的變量 uint8 second=0,minute=0,hour=0,year=0,month=0,day=0,week; uint32 sh; uint8 D[]="wek"; uint16 i=0; //**************************************************************************************************** //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ds18b20>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //**************************************************************************************************** void delay_10us(uint8 x)//*********10微秒級(jí)別延時(shí) { while(x>0)x--; } //**************************************************************************************************** void ds18b20_init()//**************ds18b20的初始化 { uint16 i; DQ=0; i=103; while(i>0)i--; DQ=1; i=4; while(i>0)i--;; } //**************************************************************************************************** bit readbit()//********************讀取一位數(shù)據(jù) { uint16 i; bit dat; DQ=0;i++; DQ=1;i++;i++; dat=DQ; i=8;while(i>0)i--; return(dat); } //**************************************************************************************************** uint8 r_ds18b20()//****************從ds18b20讀取一字節(jié)數(shù)據(jù) { uint8 dat=0,i,j; for(i=1;i<=8;i++) { j=readbit(); dat=(j<<7)|(dat>>1); } return(dat); } //**************************************************************************************************** void w_ds18b20(uint8 dat)//********向ds18b20寫(xiě)入一字節(jié)數(shù)據(jù) { uint8 j; uint8 i; bit testb; for(i=1;i<=8;i++) { testb=dat&0x01; dat>>=1; if(testb) { DQ=0; j++;j++;j++; DQ=1; j=14;while(j>0)j--; } else { DQ=0; j=14;while(j>0)j--; DQ=1; j++;j++;j++; } } } //**************************************************************************************************** void beginchange()//***************開(kāi)始轉(zhuǎn)換溫度 { ds18b20_init(); delay_10us(200); w_ds18b20(0xcc); w_ds18b20(0x44); } //**************************************************************************************************** void get_temp()//*****************從ds18b20讀取數(shù)據(jù)并轉(zhuǎn)換成十進(jìn)制 { uint8 H,L; uint16 temp; ds18b20_init(); delay_10us(200); w_ds18b20(0xcc); w_ds18b20(0xbe); L=r_ds18b20(); H=r_ds18b20(); temp=H; temp<<=8; temp|=L; T=temp*(0.0625); } //**************************************************************************************************** //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ds1302>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //**************************************************************************************************** #define WRITE_SECOND 0x80//*****寫(xiě)**秒寄存器地址 #define WRITE_MINUTE 0x82//*****寫(xiě)**分寄存器地址 #define WRITE_HOUR 0x84//*******寫(xiě)**時(shí)寄存器地址 #define WRITE_DAY 0x86//********寫(xiě)**天寄存器地址 #define WRITE_MONTH 0x88//******寫(xiě)**月寄存器地址 #define WRITE_YEAR 0x8c//*******寫(xiě)**年寄存器地址 #define WRITE_WEEK 0x8A//*******寫(xiě)**周寄存器地址 #define READ_SECOND 0x81//******讀**秒寄存器地址 #define READ_MINUTE 0x83//******讀**分寄存器地址 #define READ_HOUR 0x85//********讀**時(shí)寄存器地址 #define READ_DAY 0x87//*********讀**天寄存器地址 #define READ_MONTH 0x89//*******讀**月寄存器地址 #define READ_YEAR 0x8d//********讀**年寄存器地址 #define READ_WEEK 0x8b//********讀**周寄存器地址 #define WRITE_PROTECT 0x8E//****寫(xiě)保護(hù)寄存器 sbit ACC_7=ACC^7; sbit CLCK=P2^1; sbit RST=P2^4; sbit IO=P2^0; //**************************************************************************************************** void write_1302(uint8 addr,uint8 dat)//向1302寫(xiě)入地址和數(shù)據(jù) { uint8 i=0; RST=0; CLCK=0; RST=1; for(i=8;i>0;i--) { CLCK=0; if((addr&0x01)==1)IO=1; else IO=0; addr>>=1; CLCK=1; } for(i=8;i>0;i--) { CLCK=0; if((dat&0x01)==1)IO=1; else IO=0; dat>>=1; CLCK=1; } RST=0; } //**************************************************************************************************** uint8 read_1302(uint8 addr)//先向1302寫(xiě)地址,再讀數(shù)據(jù) { uint8 i=0,dat; RST=0; CLCK=0; RST=1; for(i=8;i>0;i--) { CLCK=0; if((addr&0x01)==1)IO=1; else IO=0; addr>>=1; CLCK=1; } for(i=8;i>0;i--) { ACC_7=IO; CLCK=1; ACC>>=1; CLCK=0; } dat=ACC; dat=(dat>>4)*10+(dat&0x0f);//有BCD碼轉(zhuǎn)換成十進(jìn)制數(shù) return(dat); RST=0; } //***************************************************************************************************** void ds1302_init()//1302初始化 { write_1302(WRITE_PROTECT,0x00);//*******取消寫(xiě)保護(hù) write_1302(WRITE_SECOND,0x00);//********00秒//NUM_BCD(0) write_1302(WRITE_MINUTE,0x00);//********00分鐘//NUM_BCD(0) write_1302(WRITE_HOUR,0x16);//**********16小時(shí)//NUM_BCD(0) write_1302(WRITE_DAY,0x21);//***********21天 write_1302(WRITE_MONTH,0x11);//*********11月 write_1302(WRITE_YEAR,0x12);//**********2012年 write_1302(WRITE_WEEK,0x03);//**********星期三 write_1302(WRITE_PROTECT,0x80);//*******打開(kāi)寫(xiě)保護(hù) } //**************************************************************************************************** void timer0_init()//幾十毫秒的延時(shí) { TMOD|=0x01; TMOD&=0xfd; TH0=0x3c; TL0=0xaf; TR0=1; } //**************************************************************************************************** void dushu()//從1302讀取數(shù)據(jù)并將其轉(zhuǎn)換成顯示函數(shù)直接用到的數(shù)字 { second=read_1302(READ_SECOND); minute=read_1302(READ_MINUTE); hour=read_1302(READ_HOUR); day=read_1302(READ_DAY); month=read_1302(READ_MONTH); year=read_1302(READ_YEAR); week=read_1302(READ_WEEK); } //****************************************************************************************************** void jishi0()//每一段時(shí)間會(huì)進(jìn)行一次讀取數(shù)字 { if(TF0==1) { TF0=0; TH0=0x3c; TL0=0xaf; counter_1++; } dushu(); if(counter_1==2) { counter_1=0; get_temp(); beginchange(); } } //**************************************************************************************************** //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<1602>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //**************************************************************************************************** sbit RS=P1^0;//**************數(shù)據(jù)命令選擇端 sbit RW=P1^1;//**************讀寫(xiě)選擇端 sbit ENLCD=P2^5;//***********使能端 sbit shang=P2^6;//***********數(shù)碼管數(shù)據(jù)輸入控制端 sbit xia=P2^7;//*************數(shù)碼管共陰極控制端 sbit busy=P0^7;//************判斷忙標(biāo)志 //**************************************************************************************************** void delay(uint32 x) { while(x--); } //**************************************************************************************************** bit check_1602()//***********判斷1602是否處于忙狀態(tài) { P0=0xff; RS=0; RW=1; ENLCD=0; delay(50); ENLCD=1; return((bit)(P0&0x80)); } //**************************************************************************************************** void write_com(uint8 com)//向1602寫(xiě)入一命令 { while(check_1602());//***首先判斷1602是否在忙 忙則等待 RS=0; RW=0; ENLCD=1; P0=com; delay(50); ENLCD=0; } //**************************************************************************************************** void write_dat(uint8 dat)//**向1602寫(xiě)入一字節(jié)數(shù)據(jù) { while(check_1602());//**首先判斷1602是否在忙 忙則等待 RS=1; RW=0; ENLCD=1; P0=dat; delay(50); ENLCD=0; } //**************************************************************************************************** void init_1602()//**********1602初始化 { write_com(0x38); delay(1000); write_com(0x38); delay(1000); write_com(0x38); write_com(0x08); write_com(0x01); write_com(0x06); write_com(0x0c); } //**************************************************************************************************** void w_string(uint8 string[],uint8 x,uint8 y)//寫(xiě)入字符型數(shù)組 x代表從第一行的第幾個(gè)方格開(kāi)始顯示 { uint8 i=0; //y 代表在第幾行 if(y==1) { while(string[i]!=0) { write_com(0x80+i+x); write_dat(string[i]); i++; }; i=0; } if(y==2) { while(string[i]!=0) { write_com(0xc0+i+x); write_dat(string[i]); i++; }; i=0; } } //**************************************************************************************************** void w_char(uint8 c,x,y)//*********向1602寫(xiě)入一個(gè)字符 { if(y==1) { write_com(0x80+x); write_dat(c); } if(y==2) { write_com(0xc0+x); write_dat(c); } } //**************************************************************************************************** void H_1602()//********************1602要顯示的內(nèi)容 { w_char(2+48,0,1); w_char(48,1,1); w_char(year/10%10+48,2,1); w_char(year%10+48,3,1); w_char(':',4,1); w_char(month/10+48,5,1); w_char(month%10+48,6,1); w_char(':',7,1); w_char(day/10+48,8,1); w_char(day%10+48,9,1); w_string(D,11,1); w_char(':',14,1); w_char(week%10+48,15,1); w_char(hour/10+48,0,2); w_char(hour%10+48,1,2); w_char(':',2,2); w_char(minute/10+48,3,2); w_char(minute%10+48,4,2); w_char(':',5,2); w_char(second/10+48,6,2); w_char(second%10+48,7,2); w_char((uint8)T/10%10+48,9,2); w_char((uint8)T%10+48,10,2); w_char('.',11,2); w_char((uint16)(T*10)%10+48,12,2); w_char(0xdf,13,2);//顯示圓點(diǎn) w_char(67,14,2);//顯示大寫(xiě)字母C } void closeLED()//******************關(guān)閉數(shù)碼管函數(shù) { shang=0x00; xia=0x00; } //**************************************************************************************************** void init() { timer0_init(); ds1302_init(); init_1602(); closeLED(); } //**************************************************************************************************** main() { init(); beginchange(); while(1) { jishi0(); H_1602(); } }